From 26276b7b376a9adad3e2d117ae292b7b50520ff3 Mon Sep 17 00:00:00 2001 From: Giovanni Marchiori <39376142+giovannimarchiori@users.noreply.github.com> Date: Fri, 13 Sep 2024 14:51:06 +0200 Subject: [PATCH] fix noise filtering bug in calo digitisation, and restore defaults (#113) * fix noise filtering bug in calo digitisation, and restore defaults of CreateCaloCells * commit forgotten change --- RecCalorimeter/src/components/CreateCaloCells.cpp | 15 ++++++++++++++- RecCalorimeter/src/components/CreateCaloCells.h | 10 ++++++---- .../src/components/CreatePositionedCaloCells.cpp | 15 ++++++++++++++- .../src/components/CreatePositionedCaloCells.h | 3 ++- 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/RecCalorimeter/src/components/CreateCaloCells.cpp b/RecCalorimeter/src/components/CreateCaloCells.cpp index c370e6cc..e7d12227 100644 --- a/RecCalorimeter/src/components/CreateCaloCells.cpp +++ b/RecCalorimeter/src/components/CreateCaloCells.cpp @@ -70,6 +70,12 @@ StatusCode CreateCaloCells::initialize() { error() << "Unable to create empty cells!" << endmsg; return StatusCode::FAILURE; } + verbose() << "Initialised empty cell map with size " << m_cellsMap.size() << endmsg; + // noise filtering erases cells from the cell map after each event, so we need + // to backup the empty cell map for later reuse + if (m_addCellNoise && m_filterCellNoise) { + m_emptyCellsMap = m_cellsMap; + } } if (m_addPosition){ m_volman = m_geoSvc->getDetector()->volumeManager(); @@ -93,7 +99,14 @@ StatusCode CreateCaloCells::execute(const EventContext&) const { // 0. Clear all cells if (m_addCellNoise) { - std::for_each(m_cellsMap.begin(), m_cellsMap.end(), [](std::pair& p) { p.second = 0; }); + // if cells are not filtered, the map has same size in each event, equal to the total number + // of cells in the calorimeter, so we can just reset the values to 0 + // if cells are filtered, during each event they are removed from the cellsMap, so one has to + // restore the initial map of all empty cells + if (!m_filterCellNoise) + std::for_each(m_cellsMap.begin(), m_cellsMap.end(), [](std::pair& p) { p.second = 0; }); + else + m_cellsMap = m_emptyCellsMap; } else { m_cellsMap.clear(); } diff --git a/RecCalorimeter/src/components/CreateCaloCells.h b/RecCalorimeter/src/components/CreateCaloCells.h index c4c1de05..1e611d32 100644 --- a/RecCalorimeter/src/components/CreateCaloCells.h +++ b/RecCalorimeter/src/components/CreateCaloCells.h @@ -28,7 +28,7 @@ class IGeoSvc; /** @class CreateCaloCells * * Algorithm for creating calorimeter cells from Geant4 hits. - * Tube geometry with ModuleThetaMerged segmentation expected. + * Tube geometry with PhiEta segmentation expected. * * Flow of the program: * 1/ Merge Geant4 energy deposits with same cellID @@ -70,7 +70,7 @@ class CreateCaloCells : public Gaudi::Algorithm { /// Handle for the calorimeter cells noise tool mutable ToolHandle m_noiseTool{"NoiseCaloCellsFlatTool", this}; /// Handle for the geometry tool - ToolHandle m_geoTool{"TubeLayerModuleThetaMergedCaloTool", this}; + ToolHandle m_geoTool{"TubeLayerPhiEtaCaloTool", this}; /// Add crosstalk to cells? Gaudi::Property m_addCrosstalk{this, "addCrosstalk", false, "Add crosstalk effect?"}; @@ -92,7 +92,7 @@ class CreateCaloCells : public Gaudi::Algorithm { mutable DataHandle m_cells{"cells", Gaudi::DataHandle::Writer, this}; MetaDataHandle m_cellsCellIDEncoding{m_cells, edm4hep::labels::CellIDEncoding, Gaudi::DataHandle::Writer}; /// Name of the detector readout - Gaudi::Property m_readoutName{this, "readoutName", "ECalBarrelModuleThetaMerged", "Name of the detector readout"}; + Gaudi::Property m_readoutName{this, "readoutName", "ECalBarrelPhiEta", "Name of the detector readout"}; /// Name of active volumes Gaudi::Property m_activeVolumeName{this, "activeVolumeName", "_sensitive", "Name of the active volumes"}; /// Name of active layers for sampling calorimeter @@ -116,7 +116,7 @@ class CreateCaloCells : public Gaudi::Algorithm { * This property won't be needed anymore. */ unsigned int m_activeVolumesNumber; - /// Use only volume ID? If false, using ModuleThetaMergedSegmentation + /// Use only volume ID? If false, using PhiEtaSegmentation bool m_useVolumeIdOnly; /// Pointer to the geometry service @@ -126,6 +126,8 @@ class CreateCaloCells : public Gaudi::Algorithm { mutable std::unordered_map m_cellsMap; /// Maps of cell IDs (corresponding to DD4hep IDs) on transfer of signals due to crosstalk mutable std::unordered_map m_CrosstalkCellsMap; + /// Maps of cell IDs with zero energy, for all cells in calo (needed if addCellNoise and filterCellNoise are both set) + mutable std::unordered_map m_emptyCellsMap; }; #endif /* RECCALORIMETER_CREATECALOCELLS_H */ diff --git a/RecCalorimeter/src/components/CreatePositionedCaloCells.cpp b/RecCalorimeter/src/components/CreatePositionedCaloCells.cpp index 3c741d49..e441404e 100644 --- a/RecCalorimeter/src/components/CreatePositionedCaloCells.cpp +++ b/RecCalorimeter/src/components/CreatePositionedCaloCells.cpp @@ -68,6 +68,12 @@ StatusCode CreatePositionedCaloCells::initialize() { error() << "Unable to create empty cells!" << endmsg; return StatusCode::FAILURE; } + verbose() << "Initialised empty cell map with size " << m_cellsMap.size() << endmsg; + // noise filtering erases cells from the cell map after each event, so we need + // to backup the empty cell map for later reuse + if (m_addCellNoise && m_filterCellNoise) { + m_emptyCellsMap = m_cellsMap; + } } // Copy over the CellIDEncoding string from the input collection to the output collection @@ -88,7 +94,14 @@ StatusCode CreatePositionedCaloCells::execute(const EventContext&) const { // 0. Clear all cells if (m_addCellNoise) { - std::for_each(m_cellsMap.begin(), m_cellsMap.end(), [](std::pair& p) { p.second = 0; }); + // if cells are not filtered, the map has same size in each event, equal to the total number + // of cells in the calorimeter, so we can just reset the values to 0 + // if cells are filtered, during each event they are removed from the cellsMap, so one has to + // restore the initial map of all empty cells + if (!m_filterCellNoise) + std::for_each(m_cellsMap.begin(), m_cellsMap.end(), [](std::pair& p) { p.second = 0; }); + else + m_cellsMap = m_emptyCellsMap; } else { m_cellsMap.clear(); } diff --git a/RecCalorimeter/src/components/CreatePositionedCaloCells.h b/RecCalorimeter/src/components/CreatePositionedCaloCells.h index 0aae29d4..d3b51a12 100644 --- a/RecCalorimeter/src/components/CreatePositionedCaloCells.h +++ b/RecCalorimeter/src/components/CreatePositionedCaloCells.h @@ -89,7 +89,8 @@ class CreatePositionedCaloCells : public Gaudi::Algorithm { mutable std::unordered_map m_cellsMap; /// Maps of cell IDs (corresponding to DD4hep IDs) on transfer of signals due to crosstalk mutable std::unordered_map m_crosstalkCellsMap; - + /// Maps of cell IDs with zero energy, for all cells in calo (needed if addNoise and filterNoise are both set) + mutable std::unordered_map m_emptyCellsMap; /// Cache position vs cellID mutable std::unordered_map m_positions_cache{}; };