Skip to content
Snippets Groups Projects
Commit 20eaf84e authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Merge branch 'mod/add-long-pixels-corection-to-masking' into 'master'

Add long pixels corection to masking

See merge request corryvreckan/corryvreckan!689
parents bd4ddb7f 244eaf60
No related branches found
No related tags found
No related merge requests found
Pipeline #8002219 failed with stages
in 19 minutes and 36 seconds
......@@ -39,6 +39,7 @@ The following authors, in alphabetical order, have developed or contributed to C
* Callan Jessiman, Carleton University, [cjessima](https://gitlab.cern.ch/cjessima)
* Uwe Kraemer, Nikhef, [uwkramer](https://gitlab.cern.ch/uwkramer)
* Jens Kroeger, University of Heidelberg/CERN, [jekroege](https://gitlab.cern.ch/jekroege)
* Simon Koch, University of Oxford, [sfkoch](https://gitlab.cern.ch/sfkoch)
* Fabian Lex, University of Freiburg, [lex](https://gitlab.cern.ch/lex)
* Magnus Mager, CERN, [mmager](https://gitlab.cern.ch/mmager)
* Keerthi Nakkalil, University Bonn/DESY, [nakkalil](https://gitlab.cern.ch/nakkalil)
......
......@@ -224,6 +224,12 @@ namespace corryvreckan {
*/
virtual XYVector getSize() const = 0;
/**
* @brief Get the size of a single pixel, accounting for non-uniform pixel sizes in some detectors
* @return double with area of pixel at this index
*/
virtual double getPixelArea(int column, int row) const = 0;
/**
* @brief Get pitch of a single pixel
* @return Pitch of a pixel
......
......@@ -114,6 +114,12 @@ namespace corryvreckan {
*/
XYVector getSize() const override;
/**
* @brief Get the size of a single pixel
* @return double with area of pixel at this index
*/
double getPixelArea(int = 0, int = 0) const override { return 3 * std::sqrt(3) / 2 * getPitch().X(); }
/**
* @brief Test whether one pixel touches the cluster
* @return true if it fulfills the condition
......
......@@ -133,6 +133,12 @@ namespace corryvreckan {
*/
XYVector getSize() const override;
/**
* @brief Get the size of a single pixel
* @return double with area of pixel at this index
*/
double getPixelArea(int = 0, int = 0) const override { return getPitch().X() * getPitch().Y(); }
/**
* @brief Get pitch of a single pixel
* @return Pitch of a pixel
......
......@@ -7,6 +7,8 @@
* SPDX-License-Identifier: MIT
*/
#include <algorithm>
#include "PixelModuleDetector.hpp"
#include "core/utils/log.h"
#include "exceptions.h"
......@@ -186,6 +188,12 @@ XYVector PixelModuleDetector::getSize() const {
m_pitch.Y() * (m_nPixels.Y() + static_cast<double>(big_pixel_y.size())));
}
double PixelModuleDetector::getPixelArea(int column, int row) const {
bool is_big_x_pixel = std::binary_search(big_pixel_x.begin(), big_pixel_x.end(), column);
bool is_big_y_pixel = std::binary_search(big_pixel_y.begin(), big_pixel_y.end(), row);
return m_pitch.X() * (1 + is_big_x_pixel) * m_pitch.Y() * (1 + is_big_y_pixel);
}
XYVector PixelModuleDetector::getSpatialResolution(double column = 0, double row = 0) const {
bool is_big_x_pixel = 0;
bool is_big_y_pixel = 0;
......
......@@ -60,6 +60,12 @@ namespace corryvreckan {
XYVector getSize() const override;
/**
* @brief Get the size of a single pixel, accounting for "big pixels"
* @return double with area of pixel at selected indexes
*/
double getPixelArea(int column, int row) const override;
/**
* @brief Retrieve configuration object from detector, containing all (potentially updated) parameters
* @return Configuration object for this detector
......
......@@ -428,6 +428,16 @@ XYVector PolarDetector::getPitch() const {
return {pitch_x, pitch_y};
}
double PolarDetector::getPixelArea(int, int row) const {
// Get strip length and pitch for the given row
auto outer_r = row_radius.at(static_cast<size_t>(row));
auto strip_phi = angular_pitch.at(static_cast<size_t>(row));
auto inner_r = (row < 1) ? center_radius : row_radius.at(static_cast<size_t>(row) - 1);
/* A = pi * (r_outer^2 - r_inner^2) * (strip_phi / (2 * pi)) */
return (outer_r * outer_r - inner_r * inner_r) * strip_phi / 2;
}
XYVector PolarDetector::getSpatialResolution(double, double row) const {
// Get integer row
auto row_int = static_cast<unsigned int>(floor(row + 0.5));
......
......@@ -195,6 +195,13 @@ namespace corryvreckan {
*/
XYVector getSize() const override;
/**
* @brief Get the size of a given strip, accounting for area differences in
* radial rows
* @return double with area of pixel at this index
*/
double getPixelArea(int column = 0, int row = 0) const override;
/**
* @brief Get pitch of a single pixel
* @return Pitch of a pixel in X and Y
......
......@@ -27,6 +27,7 @@ MaskCreator::MaskCreator(Configuration& config, std::shared_ptr<Detector> detect
config_.setDefault<bool>("mask_dead_pixels", false);
config_.setDefault<bool>("write_new_config", false);
config_.setDefault<std::string>("new_config_suffix", "");
config_.setDefault<bool>("square_big_pixel_weight", false);
m_method = config_.get<MaskingMethod>("method");
m_frequency = config_.get<double>("frequency_cut");
......@@ -37,6 +38,7 @@ MaskCreator::MaskCreator(Configuration& config, std::shared_ptr<Detector> detect
m_maskDeadPixels = config_.get<bool>("mask_dead_pixels");
m_writeNewConfig = config_.get<bool>("write_new_config");
m_newConfigSuffix = config_.get<std::string>("new_config_suffix");
m_squareBigPixelWeight = config_.get<bool>("square_big_pixel_weight");
}
void MaskCreator::initialize() {
......@@ -122,7 +124,13 @@ StatusCode MaskCreator::run(const std::shared_ptr<Clipboard>& clipboard) {
// Loop over all pixels
for(auto& pixel : pixels) {
// Enter another pixel hit for this channel
m_occupancy->Fill(pixel->column(), pixel->row());
double weight = m_detector->getPitch().X() * m_detector->getPitch().Y() /
m_detector->getPixelArea(pixel->column(), pixel->row());
if(m_squareBigPixelWeight)
weight = weight * weight;
m_occupancy->Fill(pixel->column(), pixel->row(), weight);
}
return StatusCode::Success;
......
......@@ -77,6 +77,7 @@ namespace corryvreckan {
int m_numEvents, binsOccupancy;
bool m_maskDeadPixels, m_writeNewConfig;
std::string m_newConfigSuffix;
bool m_squareBigPixelWeight;
static inline void fillDist(const TH2D* values, TH1D* dist);
};
......
......@@ -14,6 +14,7 @@ This module reads in `pixel` objects for each device from the clipboard, and mas
Currently, two methods are available. The `localdensity` noise estimation method is taken from the Proteus framework [@proteus-repo] developed by Université de Genève.
It uses a local estimate of the expected hit rate to find pixels that are a certain number of standard deviations away from this estimate.
The second method, `frequency`, is a simple cut on a global pixel firing frequency which masks pixels with a hit rate larger than `frequency_cut` times the mean global hit rate.
The bare occupancy is adjusted to account for pixel area in detectors with non-identical pixels (e.g. `PixelModuleDetector` and `RadialStripDetector`).
The module appends the pixels to be masked to the mask files provided in the geometry file for each device.
If no mask file is specified there, a new file `mask_<detector_name>.txt` is created in the globally configured output directory.
......@@ -30,6 +31,7 @@ No masks are applied in this module as this is done by the respective event load
* `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`.
* `new_config_suffix`: If `write_new_config=true` and the detector config did not previously hold a mask file, add a suffix to the new mask file. Default is `""` (no suffix).
* `square_big_pixel_weight`: The occupancy for masking is adjusted for pixel area - however, in some detectors, cross-talk between neighbours can also scale linearly with pixel size, giving localised occupancies that increase by the square of the pixel area. Setting this option to `true` divides the bare occupancy by the area squared (rather than just the area) to account for this. Defaults to `false`.
### Plots produced
For each detector the following plots are produced:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment