Commit 6e676c66 authored by Lennart Huth's avatar Lennart Huth
Browse files

Merge remote-tracking branch 'upstream/master' into fix_m26pivot

parents 8cde385f 374d6f1b
......@@ -56,6 +56,7 @@ The following authors, in alphabetical order, have contributed to Corryvreckan:
* Matthew Daniel Buckland, University of Liverpool, @mbucklan
* Carsten Daniel Burgard, DESY, @cburgard
* Manuel Colocci, CERN, @mcolocci
* Jens Dopke, STFC RAL, @jdopke
* Nicolò Jacazio, CERN, @njacazio
* Chun Cheng, DESY, @chengc
* Dominik Dannheim, CERN, @dannheim
......
......@@ -117,8 +117,8 @@ bool Detector::isAuxiliary() const {
return static_cast<bool>(m_role & DetectorRole::AUXILIARY);
}
// Functions to set and check channel masking
void Detector::set_mask_file(std::string file) {
// Function to set the channel maskfile
void Detector::maskFile(std::string file) {
m_maskfile = file;
}
......
......@@ -208,6 +208,12 @@ namespace corryvreckan {
*/
std::string calibrationFile() const { return m_calibrationfile; }
/**
* @brief Set the file with pixel mask information
* @param file New mask file name
*/
void maskFile(std::string file);
/**
* @brief Get path of the file with pixel mask information
* @return Path of the pixel mask file
......@@ -340,8 +346,6 @@ namespace corryvreckan {
// Different in Pixel/Strip Detector
virtual void configure_pos_and_orientation(Configuration& config) const = 0;
// Functions to set and check channel masking
void set_mask_file(std::string file);
virtual void process_mask_file() = 0;
// Detector information
......@@ -365,8 +369,7 @@ namespace corryvreckan {
// List of masked channels
std::map<int, bool> m_masked;
std::string m_maskfile;
std::string m_maskfile_name;
std::string m_maskfile, m_maskfile_name;
};
} // namespace corryvreckan
......
......@@ -61,11 +61,12 @@ void PixelDetector::build_axes(const Configuration& config) {
// region of interest:
m_roi = config.getMatrix<int>("roi", std::vector<std::vector<int>>());
m_maskfile_name = "";
if(config.has("mask_file")) {
m_maskfile_name = config.get<std::string>("mask_file");
std::string mask_file = config.getPath("mask_file", true);
LOG(DEBUG) << "Adding mask to detector \"" << config.getName() << "\", reading from " << mask_file;
set_mask_file(mask_file);
maskFile(mask_file);
process_mask_file();
}
}
......@@ -191,8 +192,12 @@ void PixelDetector::configure_detector(Configuration& config) const {
config.set("spatial_resolution", m_spatial_resolution, {"um"});
// Pixel mask file:
if(!m_maskfile_name.empty()) {
config.set("mask_file", m_maskfile_name);
if(!m_maskfile.empty()) {
if(m_maskfile_name.empty()) {
config.set("mask_file", m_maskfile);
} else {
config.set("mask_file", m_maskfile_name);
}
}
// Region-of-interest:
......
......@@ -20,6 +20,7 @@ AnalysisDUT::AnalysisDUT(Configuration& config, std::shared_ptr<Detector> detect
: Module(config, detector), m_detector(detector) {
config_.setDefault<double>("time_cut_frameedge", Units::get<double>(20, "ns"));
config_.setDefault<double>("spatial_cut_sensoredge", 0.5);
config_.setDefault<double>("chi2ndof_cut", 3.);
config_.setDefault<bool>("use_closest_cluster", true);
config_.setDefault<int>("n_time_bins", 20000);
......@@ -27,6 +28,7 @@ AnalysisDUT::AnalysisDUT(Configuration& config, std::shared_ptr<Detector> detect
config_.setDefault<bool>("correlations", false);
time_cut_frameedge_ = config_.get<double>("time_cut_frameedge");
spatial_cut_sensoredge_ = config_.get<double>("spatial_cut_sensoredge");
chi2_ndof_cut_ = config_.get<double>("chi2ndof_cut");
use_closest_cluster_ = config_.get<bool>("use_closest_cluster");
n_timebins_ = config_.get<int>("n_time_bins");
......@@ -626,7 +628,7 @@ StatusCode AnalysisDUT::run(const std::shared_ptr<Clipboard>& clipboard) {
}
// Check if it intercepts the DUT
if(!m_detector->hasIntercept(track.get(), 0.5)) {
if(!m_detector->hasIntercept(track.get(), spatial_cut_sensoredge_)) {
LOG(DEBUG) << " - track outside DUT area";
hCutHisto->Fill(2);
num_tracks_++;
......
......@@ -97,6 +97,7 @@ namespace corryvreckan {
// Member variables
double time_cut_frameedge_;
double spatial_cut_sensoredge_;
double chi2_ndof_cut_;
bool use_closest_cluster_;
int n_timebins_;
......
......@@ -10,6 +10,7 @@ If a region of interest (ROI) is defined for the detector under investigation, o
### Parameters
* `time_cut_frameedge`: Parameter to discard telescope tracks at the frame edges (start and end of the current CLICpix2 frame). Defaults to `20ns`.
* `spatial_cut_sensoredge`: Parameter to discard telescope tracks at the sensor edges in fractions of pixel pitch. Defaults to `0.5`.
* `chi2ndof_cut`: Acceptance criterion for the maximum telescope tracks chi2/ndf, defaults to a value of `3`.
* `use_closest_cluster`: If `true` the cluster with the smallest distance to the track is used if a track has more than one associated cluster. If `false`, loop over all associated clusters. Defaults to `true`.
* `n_time_bins`: Number of bins in the time residual and correlation histograms. Defaults to `20000`.
......
......@@ -24,6 +24,7 @@ MaskCreator::MaskCreator(Configuration& config, std::shared_ptr<Detector> detect
config_.setDefault<double>("sigma_above_avg_max", 5.);
config_.setDefault<double>("rate_max", 1.);
config_.setDefault<bool>("mask_dead_pixels", false);
config_.setDefault<bool>("write_new_config", false);
m_method = config_.get<std::string>("method");
m_frequency = config_.get<double>("frequency_cut");
......@@ -32,6 +33,7 @@ MaskCreator::MaskCreator(Configuration& config, std::shared_ptr<Detector> detect
m_sigmaMax = config_.get<double>("sigma_above_avg_max");
m_rateMax = config_.get<double>("rate_max");
m_maskDeadPixels = config_.get<bool>("mask_dead_pixels");
m_writeNewConfig = config_.get<bool>("write_new_config");
}
void MaskCreator::initialize() {
......@@ -262,6 +264,9 @@ void MaskCreator::writeMaskFiles() {
}
}
LOG(STATUS) << m_detector->getName() << " mask written to: " << std::endl << maskfile_path;
if(m_writeNewConfig) {
m_detector->maskFile(maskfile_path);
}
}
double MaskCreator::estimateDensityAtPosition(const TH2D* values, int i, int j, int bwi, int bwj) {
......
......@@ -68,7 +68,7 @@ namespace corryvreckan {
int m_bandwidthCol, m_bandwidthRow;
double m_sigmaMax, m_rateMax;
int m_numEvents, binsOccupancy;
bool m_maskDeadPixels;
bool m_maskDeadPixels, m_writeNewConfig;
static inline void fillDist(const TH2D* values, TH1D* dist);
};
......
......@@ -24,6 +24,7 @@ No masks are applied in this module as this is done by the respective event load
* `sigma_above_avg_max`: Cut for noisy pixels, number of standard deviations above average, defaults to `5`. Only used in `localdensity` mode.
* `rate_max`: Maximum rate, defaults to `1`. Only used in `localdensity` mode.
* `mask_dead_pixels`: If `true`, the module will search for pixels without any recorded hits and add them to the mask file. Default is `false`.
* `write_new_config`: If `true` and the detector config did not previously hold a mask file, then the new mask file is added to the outgoing config. Default is `false`.
### Plots produced
For each detector the following plots are produced:
......
......@@ -24,6 +24,7 @@ Prealignment::Prealignment(Configuration& config, std::shared_ptr<Detector> dete
config_.setDefault<double>("damping_factor", 1.0);
config_.setDefault<std::string>("method", "mean");
config_.setDefault<int>("fit_range_rel", 500);
config_.setDefault<double>("range_abs", Units::get<double>(10, "mm"));
if(config_.count({"time_cut_rel", "time_cut_abs"}) == 0) {
config_.setDefault("time_cut_rel", 3.0);
......@@ -34,6 +35,7 @@ Prealignment::Prealignment(Configuration& config, std::shared_ptr<Detector> dete
max_correlation_rms = config_.get<double>("max_correlation_rms");
damping_factor = config_.get<double>("damping_factor");
range_abs = config_.get<double>("range_abs");
method = config_.get<std::string>("method");
std::transform(method.begin(), method.end(), method.begin(), ::tolower);
fit_range_rel = config_.get<int>("fit_range_rel");
......@@ -49,9 +51,9 @@ void Prealignment::initialize() {
// Correlation plots
std::string title = m_detector->getName() + ": correlation X;x_{ref}-x [mm];events";
correlationX = new TH1F("correlationX", title.c_str(), 1000, -10., 10.);
correlationX = new TH1F("correlationX", title.c_str(), 1000, -1.0 * range_abs, 1.0 * range_abs);
title = m_detector->getName() + ": correlation Y;y_{ref}-y [mm];events";
correlationY = new TH1F("correlationY", title.c_str(), 1000, -10., 10.);
correlationY = new TH1F("correlationY", title.c_str(), 1000, -1.0 * range_abs, 1.0 * range_abs);
// 2D correlation plots (pixel-by-pixel, local coordinates):
title = m_detector->getName() + ": 2D correlation X (local);x [px];x_{ref} [px];events";
correlationX2Dlocal = new TH2F("correlationX_2Dlocal",
......@@ -72,9 +74,11 @@ void Prealignment::initialize() {
-0.5,
reference->nPixels().Y() - 0.5);
title = m_detector->getName() + ": 2D correlation X (global);x [mm];x_{ref} [mm];events";
correlationX2D = new TH2F("correlationX_2D", title.c_str(), 100, -10., 10., 100, -10., 10.);
correlationX2D = new TH2F(
"correlationX_2D", title.c_str(), 100, -1.0 * range_abs, 1.0 * range_abs, 100, -1.0 * range_abs, 1.0 * range_abs);
title = m_detector->getName() + ": 2D correlation Y (global);y [mm];y_{ref} [mm];events";
correlationY2D = new TH2F("correlationY_2D", title.c_str(), 100, -10., 10., 100, -10., 10.);
correlationY2D = new TH2F(
"correlationY_2D", title.c_str(), 100, -1.0 * range_abs, 1.0 * range_abs, 100, -1.0 * range_abs, 1.0 * range_abs);
}
StatusCode Prealignment::run(const std::shared_ptr<Clipboard>& clipboard) {
......
......@@ -50,6 +50,7 @@ namespace corryvreckan {
double max_correlation_rms;
double damping_factor;
double timeCut;
double range_abs;
std::string method;
int fit_range_rel;
};
......
......@@ -7,7 +7,7 @@
### Description
This module performs translational telescope plane alignment. The rotational alignment is not changed.
This initial alignment along the X and Y axes is designed to be performed before the `Alignment` module, which carries out translational and rotational alignment of the planes. To not include the DUT in this transaltional alignment, it will need to be masked in the configuration file.
This initial alignment along the X and Y axes is designed to be performed before the `Alignment` module, which carries out translational and rotational alignment of the planes. To not include the DUT in this translational alignment, it will need to be masked in the configuration file.
The way in which the required translational shifts in X and Y are calculated is specified by the parameter `method`.
Either the mean of the 1D correlation histogram, its maximum or the mean of a Gaussian fit can be used to determine the translational shifts.
......@@ -21,6 +21,7 @@ However, for the prealignment this is a an acceptable estimation which works wit
* `time_cut_abs`: Specifies an absolute value for the maximum time difference between a cluster on the current detector and a cluster on the reference plane to be considered in the prealignment. Absolute and relative time cuts are mutually exclusive. No default value.
* `method`: Specifies which method should be used to compute the translational shifts. With the option `mean` the mean of the 1D correlation histogram is used. The option `maximum` uses the maximum value of the histogram. With `method` set to `gauss_fit` a Gaussian is fitted and the mean of the fit is used for the translational shift. Default is to `mean`.
* `fit_range_rel`: Parameter to set the fit range of the Gaussian fit if `method` is set to `gauss_fit`. The absolute fit range is given by `fit_range_rel` times the spatial resolution of the corresponding detector around the maximum of the 1D correlation histogram. The default of the relative fit range is `fit_range_rel` = 500.
* `range_abs`: Parameter to allow setting up the range in which residuals get plotted (mm, +- around 0). Default is `10mm`. This needs to be increased for large sensors, where the alignment might be out by well more than 10mm and thus residual plots might be empty in the range +- 10.
### Plots Created
......
......@@ -26,6 +26,7 @@ The DUT plane can be excluded from the track finding.
* `volume_radiation_length`: Define the radiation length of the volume around the telescope. Defaults to dry air with a radiation length of`304.2 m`
* `reject_by_roi`: If true, tracks intercepting any detector outside its ROI will be rejected. Defaults to `false`.
* `unique_cluster_usage`: Only use a cluster for one track - in the case of multiple assignments, the track with the best chi2/ndof is kept. Defaults to `false`
* `max_plot_chi2`: Option to define the maximum chi2 in plots for chi2 and chi2/ndof - with an ill-aligned telescope, this is necessary for an initial alignment step. Defaults to `50.0`
### Plots produced
......
......@@ -29,6 +29,7 @@ Tracking4D::Tracking4D(Configuration& config, std::vector<std::shared_ptr<Detect
config_.setDefault<bool>("exclude_dut", true);
config_.setDefault<std::string>("track_model", "straightline");
config_.setDefault<double>("momentum", Units::get<double>(5, "GeV"));
config_.setDefault<double>("max_plot_chi2", 50.0);
config_.setDefault<double>("volume_radiation_length", Units::get<double>(304.2, "m"));
config_.setDefault<bool>("volume_scattering", false);
config_.setDefault<bool>("reject_by_roi", false);
......@@ -60,6 +61,7 @@ Tracking4D::Tracking4D(Configuration& config, std::vector<std::shared_ptr<Detect
track_model_ = config_.get<std::string>("track_model");
momentum_ = config_.get<double>("momentum");
max_plot_chi2_ = config_.get<double>("max_plot_chi2");
volume_radiation_length_ = config_.get<double>("volume_radiation_length");
use_volume_scatterer_ = config_.get<bool>("volume_scattering");
reject_by_ROI_ = config_.get<bool>("reject_by_roi");
......@@ -82,9 +84,9 @@ void Tracking4D::initialize() {
// Set up histograms
std::string title = "Track #chi^{2};#chi^{2};events";
trackChi2 = new TH1F("trackChi2", title.c_str(), 300, 0, 150);
trackChi2 = new TH1F("trackChi2", title.c_str(), 300, 0, 3 * max_plot_chi2_);
title = "Track #chi^{2}/ndof;#chi^{2}/ndof;events";
trackChi2ndof = new TH1F("trackChi2ndof", title.c_str(), 500, 0, 50);
trackChi2ndof = new TH1F("trackChi2ndof", title.c_str(), 500, 0, max_plot_chi2_);
title = "Clusters per track;clusters;tracks";
clustersPerTrack = new TH1F("clustersPerTrack", title.c_str(), 10, -0.5, 9.5);
title = "Track multiplicity;tracks;events";
......
......@@ -72,6 +72,7 @@ namespace corryvreckan {
std::map<std::string, TH1F*> kinkY;
// Cuts for tracking
double momentum_;
double max_plot_chi2_;
double volume_radiation_length_;
size_t min_hits_on_track_;
bool exclude_DUT_;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment