Commit b1adf4d0 authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Merge branch 'spatial_resolution' into 'master'

spatial resolution

See merge request !193
parents 02ba5a48 c4e455cf
Pipeline #1234234 failed with stages
in 4 minutes and 32 seconds
......@@ -67,7 +67,7 @@ Detector::Detector(const Configuration& config) : m_role(DetectorRole::NONE) {
// Auxiliary devices don't have: number_of_pixels, pixel_pitch, spatial_resolution, mask_file, region-of-interest
if(!isAuxiliary()) {
// Intrinsic spatial resolution, no default:
m_resolution = config.get<ROOT::Math::XYVector>("resolution");
m_spatial_resolution = config.get<ROOT::Math::XYVector>("spatial_resolution");
// Number of pixels:
m_nPixels = config.get<ROOT::Math::DisplacementVector2D<Cartesian2D<int>>>("number_of_pixels");
// Size of the pixels:
......@@ -142,7 +142,7 @@ void Detector::processMaskFile() {
// Open the file with masked pixels
std::ifstream inputMaskFile(m_maskfile, std::ios::in);
if(!inputMaskFile.is_open()) {
LOG(ERROR) << "Could not open mask file " << m_maskfile;
LOG(WARNING) << "Could not open mask file " << m_maskfile;
} else {
int row = 0, col = 0;
std::string id;
......@@ -151,7 +151,7 @@ void Detector::processMaskFile() {
if(id == "c") {
inputMaskFile >> col;
if(col > nPixels().X() - 1) {
LOG(ERROR) << "Column " << col << " outside of pixel matrix, chip has only " << nPixels().X()
LOG(WARNING) << "Column " << col << " outside of pixel matrix, chip has only " << nPixels().X()
<< " columns!";
}
LOG(TRACE) << "Masking column " << col;
......@@ -161,7 +161,7 @@ void Detector::processMaskFile() {
} else if(id == "r") {
inputMaskFile >> row;
if(row > nPixels().Y() - 1) {
LOG(ERROR) << "Row " << col << " outside of pixel matrix, chip has only " << nPixels().Y() << " rows!";
LOG(WARNING) << "Row " << col << " outside of pixel matrix, chip has only " << nPixels().Y() << " rows!";
}
LOG(TRACE) << "Masking row " << row;
for(int c = 0; c < nPixels().X(); c++) {
......@@ -170,13 +170,13 @@ void Detector::processMaskFile() {
} else if(id == "p") {
inputMaskFile >> col >> row;
if(col > nPixels().X() - 1 || row > nPixels().Y() - 1) {
LOG(ERROR) << "Pixel " << col << " " << row << " outside of pixel matrix, chip has only "
LOG(WARNING) << "Pixel " << col << " " << row << " outside of pixel matrix, chip has only "
<< nPixels().X() << " x " << nPixels().Y() << " pixels!";
}
LOG(TRACE) << "Masking pixel " << col << " " << row;
maskChannel(col, row); // Flag to mask a pixel
} else {
LOG(ERROR) << "Could not parse mask entry (id \"" << id << "\")";
LOG(WARNING) << "Could not parse mask entry (id \"" << id << "\")";
}
}
LOG(INFO) << m_masked.size() << " masked pixels";
......@@ -271,7 +271,7 @@ Configuration Detector::getConfiguration() const {
config.set("pixel_pitch", m_pitch, {"um"});
// Intrinsic resolution:
config.set("resolution", m_resolution, {"um"});
config.set("spatial_resolution", m_spatial_resolution, {"um"});
// Pixel mask file:
if(!m_maskfile_name.empty()) {
......
......@@ -59,7 +59,8 @@ namespace corryvreckan {
/**
* @brief Detector representation in the reconstruction chain
*
* Contains the detector with all its properties such as type, name, position and orientation, pitch, resolution etc.
* Contains the detector with all its properties such as type, name, position and orientation, pitch, spatial resolution
* etc.
*/
class Detector {
public:
......@@ -123,10 +124,10 @@ namespace corryvreckan {
XYVector pitch() const { return m_pitch; }
/**
* @brief Get intrinsic resolution of the detector
* @return Intrinsic resolution in X and Y
* @brief Get intrinsic spatial resolution of the detector
* @return Intrinsic spatial resolution in X and Y
*/
XYVector resolution() const { return m_resolution; }
XYVector getSpatialResolution() const { return m_spatial_resolution; }
/**
* @brief Get number of pixels in x and y
......@@ -284,7 +285,7 @@ namespace corryvreckan {
std::string m_detectorType;
std::string m_detectorName;
XYVector m_pitch{};
XYVector m_resolution{};
XYVector m_spatial_resolution{};
ROOT::Math::DisplacementVector2D<ROOT::Math::Cartesian2D<int>> m_nPixels{};
double m_timeOffset;
double m_timeResolution;
......
......@@ -239,8 +239,8 @@ void Clustering4D::calculateClusterCentre(Cluster* cluster) {
cluster->setRow(row);
cluster->setCharge(charge);
// Set uncertainty on position from intrinstic detector resolution:
cluster->setError(m_detector->resolution());
// Set uncertainty on position from intrinstic detector spatial resolution:
cluster->setError(m_detector->getSpatialResolution());
cluster->setTimestamp(timestamp);
cluster->setDetectorID(detectorID);
......
......@@ -231,8 +231,8 @@ void ClusteringSpatial::calculateClusterCentre(Cluster* cluster) {
cluster->setColumn(column);
cluster->setCharge(charge);
// Set uncertainty on position from intrinstic detector resolution:
cluster->setError(m_detector->resolution());
// Set uncertainty on position from intrinstic detector spatial resolution:
cluster->setError(m_detector->getSpatialResolution());
cluster->setDetectorID(detectorID);
cluster->setClusterCentre(positionGlobal);
......
......@@ -6,6 +6,7 @@ using namespace std;
DUTAssociation::DUTAssociation(Configuration config, std::shared_ptr<Detector> detector)
: Module(std::move(config), detector), m_detector(detector) {
// timing cut, relative (x * time_resolution) or absolute:
if(m_config.count({"time_cut_rel", "time_cut_abs"}) > 1) {
throw InvalidCombinationError(
m_config, {"time_cut_rel", "time_cut_abs"}, "Absolute and relative time cuts are mutually exclusive.");
......@@ -14,8 +15,21 @@ DUTAssociation::DUTAssociation(Configuration config, std::shared_ptr<Detector> d
} else {
timeCut = m_config.get<double>("time_cut_rel", 3.0) * m_detector->getTimeResolution();
}
spatialCut = m_config.get<XYVector>("spatial_cut", 2 * m_detector->pitch());
// spatial cut, relative (x * spatial_resolution) or absolute:
if(m_config.count({"spatial_cut_rel", "spatial_cut_abs"}) > 1) {
throw InvalidCombinationError(
m_config, {"spatial_cut_rel", "spatial_cut_abs"}, "Absolute and relative spatial cuts are mutually exclusive.");
} else if(m_config.has("spatial_cut_abs")) {
spatialCut = m_config.get<XYVector>("spatial_cut_abs");
} else {
spatialCut = m_config.get<double>("spatial_cut_rel", 3.0) * m_detector->getSpatialResolution();
}
useClusterCentre = m_config.get<bool>("use_cluster_centre", false);
LOG(DEBUG) << "time_cut = " << Units::display(timeCut, {"ms", "us", "ns"});
LOG(DEBUG) << "spatial_cut = " << Units::display(spatialCut, {"um", "mm"});
LOG(DEBUG) << "use_cluster_centre = " << useClusterCentre;
}
void DUTAssociation::initialise() {
......
......@@ -9,9 +9,10 @@ This module performs a basic tracking method.
Clusters from the first plane in Z (named the seed plane) are related to clusters close in time on the other detector planes using straight line tracks. The DUT plane can be excluded from the track finding.
### Parameters
* `time_cut_rel`: Number of standard deviations the `time_resolution` of one detector plane will be multiplied by, either the `time_resolution` of the first plane in Z or the current telescope plane, whichever is largest. This calculated value is then used as the maximum time difference allowed between clusters for association to a track. This allows the time cuts between different planes to be detector appropriate. By default, a relative time cut is applied. Absolute and relative time cuts are mutually exclusive. Defaults to `3.0`.
* `time_cut_abs`: Specifies an absolute value for the maximum time difference allowed between clusters for association to the track. Absolute and relative time cuts are mutually exclusive. No default value.
* `spatial_cut`: Maximum spatial distance in the XY plane allowed between clusters for association for the telescope planes. Default value is `0.2mm`.
* `time_cut_rel`: Factor by which the `time_resolution` of each detector plane will be multiplied, either the `time_resolution` of the first plane in Z or the current telescope plane, whichever is largest. This calculated value is then used as the maximum time difference allowed between clusters and a track for association to the track. This allows the time cuts between different planes to be detector appropriate. By default, a relative time cut is applied. Absolute and relative time cuts are mutually exclusive. Defaults to `3.0`.
* `time_cut_abs`: Specifies an absolute value for the maximum time difference allowed between clusters and a track for association to the track. Absolute and relative time cuts are mutually exclusive. No default value.
* `spatial_cut_rel`: Factor by which the `spatial_resolution` in x and y of each detector plane will be multiplied. These calculated value are defining an ellipse which is then used as the maximum distance in the XY plane allowed between clusters and a track for association to the track. This allows the spatial cuts between different planes to be detector appropriate. By default, a relative spatial cut is applied. Absolute and relative spatial cuts are mutually exclusive. Defaults to `3.0`.
* `spatial_cut_abs`: Specifies a set of absolute value (x and y) which defines an ellipse for the maximum spatial distance in the XY plane between clusters and a track for association to the track. Absolute and relative spatial cuts are mutually exclusive. No default value.
* `min_hits_on_track`: Minium number of associated clusters needed to create a track, equivalent to the minimum number of planes required for each track. Default value is `6`.
* `exclude_dut`: Boolean to choose if the DUT plane is included in the track finding. Default value is `true`.
* `require_detectors`: Names of detectors which are required to have a cluster on the track. If a track does not have a cluster from all detectors listed here, it is rejected. If empty, no detector is required. Default is empty.
......
......@@ -9,7 +9,7 @@ using namespace std;
Tracking4D::Tracking4D(Configuration config, std::vector<std::shared_ptr<Detector>> detectors)
: Module(std::move(config), std::move(detectors)) {
// Default values for cuts
// timing cut, relative (x * time_resolution) or absolute:
if(m_config.count({"time_cut_rel", "time_cut_abs"}) > 1) {
throw InvalidCombinationError(
m_config, {"time_cut_rel", "time_cut_abs"}, "Absolute and relative time cuts are mutually exclusive.");
......@@ -24,11 +24,27 @@ Tracking4D::Tracking4D(Configuration config, std::vector<std::shared_ptr<Detecto
time_cuts_[detector] = detector->getTimeResolution() * time_cut_rel_;
}
}
spatialCut = m_config.get<double>("spatial_cut", Units::get<double>(200, "um"));
minHitsOnTrack = m_config.get<size_t>("min_hits_on_track", 6);
excludeDUT = m_config.get<bool>("exclude_dut", true);
requireDetectors = m_config.getArray<std::string>("require_detectors", {""});
timestampFrom = m_config.get<std::string>("timestamp_from", {});
// spatial cut, relative (x * spatial_resolution) or absolute:
if(m_config.count({"spatial_cut_rel", "spatial_cut_abs"}) > 1) {
throw InvalidCombinationError(
m_config, {"spatial_cut_rel", "spatial_cut_abs"}, "Absolute and relative spatial cuts are mutually exclusive.");
} else if(m_config.has("spatial_cut_abs")) {
auto spatial_cut_abs_ = m_config.get<XYVector>("spatial_cut_abs");
for(auto& detector : get_detectors()) {
spatial_cuts_[detector] = spatial_cut_abs_;
}
} else {
// default is 3.0 * spatial_resolution
auto spatial_cut_rel_ = m_config.get<double>("spatial_cut_rel", 3.0);
for(auto& detector : get_detectors()) {
spatial_cuts_[detector] = detector->getSpatialResolution() * spatial_cut_rel_;
}
}
}
void Tracking4D::initialise() {
......@@ -155,22 +171,30 @@ StatusCode Tracking4D::run(std::shared_ptr<Clipboard> clipboard) {
// Get the detector
auto det = get_detector(detectorID);
// Check if the DUT should be excluded and obey:
if(excludeDUT && det->isDUT()) {
LOG(DEBUG) << "Skipping DUT plane.";
if(trees.count(detectorID) == 0) {
LOG(TRACE) << "Skipping detector " << det->name() << " as it has 0 clusters.";
continue;
}
if(detectorID == seedPlane)
if(detectorID == seedPlane) {
LOG(TRACE) << "Skipping seed plane " << det->name();
continue;
if(trees.count(detectorID) == 0)
}
// Check if the DUT should be excluded and obey:
if(excludeDUT && det->isDUT()) {
LOG(DEBUG) << "Skipping DUT plane.";
continue;
}
// Get all neighbours within the timing cut
LOG(DEBUG) << "Searching for neighbouring cluster on " << detectorID;
LOG(DEBUG) << "Searching for neighbouring cluster on device " << detectorID;
LOG(DEBUG) << "- cluster time is " << Units::display(cluster->timestamp(), {"ns", "us", "s"});
Cluster* closestCluster = nullptr;
double closestClusterDistance = spatialCut;
// Use spatial cut only as initial value (check if cluster is ellipse defined by cuts is done below):
double closestClusterDistance =
sqrt(spatial_cuts_[det].x() * spatial_cuts_[det].x() + spatial_cuts_[det].y() * spatial_cuts_[det].y());
// For default configuration, comparing time cuts calculated from the time resolution of the current detector and
// the first plane in Z,
// and taking the maximal value as the cut in time for track-cluster association
......@@ -202,8 +226,25 @@ StatusCode Tracking4D::run(std::shared_ptr<Clipboard> clipboard) {
Cluster* newCluster = neighbours[ne];
// Calculate the distance to the previous plane's cluster/intercept
double distance = sqrt((interceptX - newCluster->global().x()) * (interceptX - newCluster->global().x()) +
(interceptY - newCluster->global().y()) * (interceptY - newCluster->global().y()));
double distanceX = interceptX - newCluster->global().x();
double distanceY = interceptY - newCluster->global().y();
double distance = sqrt(distanceX * distanceX + distanceY * distanceY);
// Check if newCluster lies within ellipse defined by spatial cuts around intercept,
// following this example:
// https://www.geeksforgeeks.org/check-if-a-point-is-inside-outside-or-on-the-ellipse/
//
// ellipse defined by: x^2/a^2 + y^2/b^2 = 1: on ellipse,
// > 1: outside,
// < 1: inside
// Continue if outside of ellipse:
double norm = (distanceX * distanceX) / (spatial_cuts_[det].x() * spatial_cuts_[det].x()) +
(distanceY * distanceY) / (spatial_cuts_[det].y() * spatial_cuts_[det].y());
if(norm > 1) {
continue;
}
// If this is the closest keep it
if(distance < closestClusterDistance) {
......@@ -295,8 +336,8 @@ StatusCode Tracking4D::run(std::shared_ptr<Clipboard> clipboard) {
<< Units::display(track_timestamp, "us") << " to track.";
track->setTimestamp(track_timestamp);
} else {
LOG(ERROR) << "Cannot assign timestamp to track. Use average cluster timestamp for track or set detector to "
"set track timestamp. Please update the configuration file.";
LOG(ERROR) << "Cannot assign timestamp to track. Use average cluster timestamp for track or set detector to set "
"track timestamp. Please update the configuration file.";
return StatusCode::Failure;
}
}
......
......@@ -43,11 +43,11 @@ namespace corryvreckan {
// Cuts for tracking
double time_cut_reference_;
double spatialCut;
size_t minHitsOnTrack;
bool excludeDUT;
std::vector<std::string> requireDetectors;
std::map<std::shared_ptr<Detector>, double> time_cuts_;
std::map<std::shared_ptr<Detector>, XYVector> spatial_cuts_;
std::string timestampFrom;
};
} // namespace corryvreckan
......
......@@ -8,7 +8,8 @@ This module performs track finding using only positional information (no timing
### Parameters
* `spatial_cut`: Cut on the maximum distance between the track and cluster for them to be considered associated. Default value is `200um`.
* `spatial_cut_rel`: Factor by which the `spatial_resolution` in x and y of each detector plane will be multiplied. These calculated value are defining an ellipse which is then used as the maximum distance in the XY plane allowed between clusters and a track for association to the track. This allows the spatial cuts between different planes to be detector appropriate. By default, a relative spatial cut is applied. Absolute and relative spatial cuts are mutually exclusive. Defaults to `3.0`.
* `spatial_cut_abs`: Specifies a set of absolute value (x and y) which defines an ellipse for the maximum spatial distance in the XY plane between clusters and a track for association to the track. Absolute and relative spatial cuts are mutually exclusive. No default value.
* `min_hits_on_track`: The minimum number of planes with clusters associated to a track for it to be stored. Default value is `6`.
* `exclude_dut`: Boolean to set if the DUT should be included in the track fitting. Default value is `true`.
......
......@@ -5,21 +5,38 @@
using namespace corryvreckan;
using namespace std;
/*
This algorithm performs the track finding using only spatial information
(no timing). It is based on a linear extrapolation along the z axis, followed
by a nearest neighbour search, and should be well adapted to testbeam
reconstruction with a mostly colinear beam.
*/
TrackingSpatial::TrackingSpatial(Configuration config, std::vector<std::shared_ptr<Detector>> detectors)
: Module(std::move(config), std::move(detectors)) {
spatialCut = m_config.get<double>("spatial_cut", Units::get<double>(200, "um"));
minHitsOnTrack = m_config.get<size_t>("min_hits_on_track", 6);
excludeDUT = m_config.get<bool>("exclude_dut", true);
}
/*
This algorithm performs the track finding using only spatial information
(no timing). It is based on a linear extrapolation along the z axis, followed
by a nearest neighbour search, and should be well adapted to testbeam
reconstruction with a mostly colinear beam.
*/
// spatial cut, relative (x * spatial_resolution) or absolute:
if(m_config.count({"spatial_cut_rel", "spatial_cut_abs"}) > 1) {
throw InvalidCombinationError(
m_config, {"spatial_cut_rel", "spatial_cut_abs"}, "Absolute and relative spatial cuts are mutually exclusive.");
} else if(m_config.has("spatial_cut_abs")) {
auto spatial_cut_abs_ = m_config.get<XYVector>("spatial_cut_abs");
for(auto& detector : get_detectors()) {
spatial_cuts_[detector] = spatial_cut_abs_;
}
} else {
// default is 3.0 * spatial_resolution
auto spatial_cut_rel_ = m_config.get<double>("spatial_cut_rel", 3.0);
for(auto& detector : get_detectors()) {
spatial_cuts_[detector] = detector->getSpatialResolution() * spatial_cut_rel_;
}
}
}
void TrackingSpatial::initialise() {
......@@ -138,11 +155,11 @@ StatusCode TrackingSpatial::run(std::shared_ptr<Clipboard> clipboard) {
for(auto& detector : detectors) {
auto detectorID = detector->name();
if(trees.count(detectorID) == 0) {
LOG(TRACE) << "Skip 0th detector.";
LOG(TRACE) << "Skipping detector " << detector->name() << " as it has 0 clusters.";
continue;
}
if(detectorID == seedPlane) {
LOG(TRACE) << "Skip seed plane.";
LOG(TRACE) << "Skipping seed plane.";
continue;
}
......@@ -153,17 +170,28 @@ StatusCode TrackingSpatial::run(std::shared_ptr<Clipboard> clipboard) {
}
// Get the closest neighbour
LOG(DEBUG) << "- looking for nearest cluster on device " << detectorID;
LOG(DEBUG) << "Searching for nearest cluster on device " << detectorID;
Cluster* closestCluster = trees[detectorID]->getClosestNeighbour(cluster);
// Check if it is within the spatial window
double distance = sqrt((cluster->global().x() - closestCluster->global().x()) *
(cluster->global().x() - closestCluster->global().x()) +
(cluster->global().y() - closestCluster->global().y()) *
(cluster->global().y() - closestCluster->global().y()));
double distanceX = (cluster->global().x() - closestCluster->global().x());
double distanceY = (cluster->global().y() - closestCluster->global().y());
double distance = sqrt(distanceX * distanceX + distanceY * distanceY);
// Check if closestCluster lies within ellipse defined by spatial cuts,
// following this example:
// https://www.geeksforgeeks.org/check-if-a-point-is-inside-outside-or-on-the-ellipse/
//
// ellipse defined by: x^2/a^2 + y^2/b^2 = 1: on ellipse,
// > 1: outside,
// < 1: inside
// Continue if on or outside of ellipse:
if(distance > spatialCut)
double norm = (distanceX * distanceX) / (spatial_cuts_[detector].x() * spatial_cuts_[detector].x()) +
(distanceY * distanceY) / (spatial_cuts_[detector].y() * spatial_cuts_[detector].y());
if(norm > 1) {
continue;
}
// Add the cluster to the track
track->addCluster(closestCluster);
......
......@@ -38,7 +38,7 @@ namespace corryvreckan {
std::map<std::string, TH1F*> residualsY;
// Member variables
double spatialCut;
std::map<std::shared_ptr<Detector>, XYVector> spatial_cuts_;
size_t minHitsOnTrack;
bool excludeDUT;
};
......
......@@ -4,75 +4,76 @@ orientation = 0deg,0deg,0deg
orientation_mode = "xyz"
pixel_pitch = 0um, 0um
position = 0mm,0mm,0mm
resolution = 0um,0um
time_resolution=1s
spatial_resolution = 0um,0um
time_resolution = 1s
type = "TLU"
role = "auxiliary"
[MIMOSA26_0]
mask_file = "mask_MIMOSA26_0.txt"
mask_file = "maskfiles/mask_MIMOSA26_0.txt"
number_of_pixels = 1152,576
orientation = -0.0317992deg,-0.0306532deg,-0.356494deg
orientation_mode = "xyz"
pixel_pitch = 18.4um,18.4um
position = -605.953um,-12.574um,0
resolution = 4um,4um
time_resolution=230us
spatial_resolution = 4um,4um
time_resolution = 230us
type = "MIMOSA26"
[MIMOSA26_1]
mask_file = "mask_MIMOSA26_1.txt"
mask_file = "maskfiles/mask_MIMOSA26_1.txt"
number_of_pixels = 1152,576
orientation = 1.57283deg,0.297652deg,-0.214515deg
orientation_mode = "xyz"
pixel_pitch = 18.4um,18.4um
position = -860.897um,280.298um,152mm
resolution = 4um,4um
time_resolution=230us
spatial_resolution = 4um,4um
time_resolution = 230us
type = "MIMOSA26"
[MIMOSA26_2]
mask_file = "mask_MIMOSA26_2.txt"
mask_file = "maskfiles/mask_MIMOSA26_2.txt"
number_of_pixels = 1152,576
orientation = -0.0336899deg,0.0812454deg,-0.00343775deg
orientation_mode = "xyz"
pixel_pitch = 18.4um,18.4um
position = -1.10334mm,99.171um,305mm
resolution = 4um,4um
time_resolution=230us
spatial_resolution = 4um,4um
time_resolution = 230us
role = "reference"
type = "MIMOSA26"
[MIMOSA26_3]
mask_file = "mask_MIMOSA26_3.txt"
mask_file = "maskfiles/mask_MIMOSA26_3.txt"
number_of_pixels = 1152,576
orientation = 2.08156deg,1.19691deg,0.00699009deg
orientation_mode = "xyz"
pixel_pitch = 18.4um,18.4um
position = -2.58205mm,285.418um,348mm
resolution = 4um,4um
time_resolution=230us
spatial_resolution = 4um,4um
time_resolution = 230us
type = "MIMOSA26"
[MIMOSA26_4]
mask_file = "mask_MIMOSA26_4.txt"
mask_file = "maskfiles/mask_MIMOSA26_4.txt"
number_of_pixels = 1152,576
orientation = -2.53133deg,-0.753898deg,-0.354489deg
orientation_mode = "xyz"
pixel_pitch = 18.4um,18.4um
position = -2.3413mm,173.727um,498mm
resolution = 4um,4um
time_resolution=230us
spatial_resolution = 4um,4um
time_resolution = 230us
type = "MIMOSA26"
[MIMOSA26_5]
mask_file = "mask_MIMOSA26_5.txt"
mask_file = "maskfiles/mask_MIMOSA26_5.txt"
number_of_pixels = 1152,576
orientation = -3.04516deg,-0.866713deg,0.0708176deg
orientation_mode = "xyz"
pixel_pitch = 18.4um,18.4um
position = -2.24809mm,202.137um,585mm
resolution = 4um,4um
time_resolution=230us
spatial_resolution = 4um,4um
time_resolution = 230us
type = "MIMOSA26"
[Timepix3_0]
......@@ -81,7 +82,7 @@ orientation = 0,0,0
orientation_mode = "xyz"
pixel_pitch = 55um,55um
position = 0,0,666mm
resolution = 10um,10um
time_resolution=20ns
spatial_resolution = 10um,10um
time_resolution = 20ns
role = "dut"
type = "Timepix3"
......@@ -4,8 +4,8 @@ orientation = 10.7471deg,186.437deg,-1.33797deg
orientation_mode = "xyz"
pixel_pitch = 55um,55um
position = 923.402um,296.86um,0
resolution = 4um,4um
time_resolution=20ns
spatial_resolution = 4um,4um
time_resolution = 20ns
type = "Timepix3"
[W0013_E03]
......@@ -14,8 +14,8 @@ orientation = 11.0172deg,186.658deg,-1.06937deg
orientation_mode = "xyz"
pixel_pitch = 55um,55um
position = -249.154um,408.592um,21.5mm
resolution = 4um,4um
time_resolution=20ns
spatial_resolution = 4um,4um
time_resolution = 20ns
type = "Timepix3"
[W0013_G02]
......@@ -24,8 +24,8 @@ orientation = 10.3075deg,187.093deg,-1.64124deg
orientation_mode = "xyz"
pixel_pitch = 55um,55um
position = 43.482um,378.305um,43.5mm
resolution = 4um,4um
time_resolution=20ns
spatial_resolution = 4um,4um
time_resolution = 20ns
type = "Timepix3"
[W0013_G03]
......@@ -34,8 +34,8 @@ orientation = 8.99544deg,8.99544deg,0
orientation_mode = "xyz"
pixel_pitch = 55um,55um
position = -0,-0,186.5mm
resolution = 4um,4um
time_resolution=20ns
spatial_resolution = 4um,4um
time_resolution = 20ns
role = "reference"
type = "Timepix3"
......@@ -45,8 +45,8 @@ orientation = 7.86184deg,9.84479deg,1.31121deg
orientation_mode = "xyz"
pixel_pitch = 55um,55um
position = 452.897um,-578.683um,208.5mm
resolution = 4um,4um
time_resolution=20ns
spatial_resolution = 4um,4um
time_resolution = 20ns
type = "Timepix3"
[W0013_L09]
......@@ -55,6 +55,6 @@ orientation = 8.06547deg,10.0823deg,0.126337deg
orientation_mode = "xyz"
pixel_pitch = 55um,55um
position = -1.08498mm,-16.204um,231.5mm
resolution = 4um,4um
time_resolution=20ns
spatial_resolution = 4um,4um
time_resolution = 20ns
type = "Timepix3"
......@@ -7,8 +7,9 @@ orientation = -170.539deg, -9.42327deg, 0.111919deg
type = "timepix"
pixel_pitch = 55um, 55um
number_of_pixels = 256, 256
resolution = 4um,4um