-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
expanded version of CreateCaloCells that also add proper cell positions #100
Merged
kjvbrt
merged 22 commits into
HEP-FCC:main
from
giovannimarchiori:gmarchio-main-20240724-positionedcells
Sep 9, 2024
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
337e2fe
expanded version of CreateCaloCells that also add proper cell positions
giovannimarchiori 8f20000
Merge branch 'HEP-FCC:main' into gmarchio-main-20240724-positionedcells
giovannimarchiori de7d18d
Merge branch 'HEP-FCC:main' into gmarchio-main-20240724-positionedcells
giovannimarchiori b4e43ca
Merge branch 'HEP-FCC:main' into gmarchio-main-20240724-positionedcells
giovannimarchiori ec7fce9
Merge branch 'HEP-FCC:main' into gmarchio-main-20240724-positionedcells
giovannimarchiori de25ea2
Merge branch 'HEP-FCC:main' into gmarchio-main-20240724-positionedcells
giovannimarchiori 521a1c6
GaudiAlgorithm -> Gaudi::Algorithm
giovannimarchiori 8d6427a
Merge branch 'HEP-FCC:main' into gmarchio-main-20240724-positionedcells
giovannimarchiori 7f7e036
Merge branch 'HEP-FCC:main' into gmarchio-main-20240724-positionedcells
giovannimarchiori a8c1927
Merge branch 'HEP-FCC:main' into gmarchio-main-20240724-positionedcells
giovannimarchiori d1b1755
improve comment
giovannimarchiori d81c85e
Follow Juraj's suggestion and fix a bug
giovannimarchiori 34b132b
remove commented includes
giovannimarchiori 2feb4f2
replace CreateCaloCells+CellPositions.. with CreatePositionedCaloCell…
giovannimarchiori 24879b1
remove commented includes
giovannimarchiori eed2d6a
enable code to cluster hcal endcap cells
giovannimarchiori 1963212
fix a bug in the shell script for automatic tests, allow option for r…
giovannimarchiori 1fad662
fix bug when crosstalk is off (readCrosstalkMap undefined)
giovannimarchiori 0de7bda
Merge branch 'HEP-FCC:main' into gmarchio-main-20240724-positionedcells
giovannimarchiori f9a1100
Merge branch 'HEP-FCC:main' into gmarchio-main-20240724-positionedcells
giovannimarchiori e2e3b9f
move code to RecCalorimeter, remove unused pointer to geoSvc
giovannimarchiori 8520463
remove multiple spaces
giovannimarchiori File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
189 changes: 189 additions & 0 deletions
189
RecCalorimeter/src/components/CreatePositionedCaloCells.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,189 @@ | ||
#include "CreatePositionedCaloCells.h" | ||
|
||
// k4geo | ||
#include "detectorCommon/DetUtils_k4geo.h" | ||
|
||
// edm4hep | ||
#include "edm4hep/CalorimeterHit.h" | ||
|
||
DECLARE_COMPONENT(CreatePositionedCaloCells) | ||
|
||
CreatePositionedCaloCells::CreatePositionedCaloCells(const std::string& name, ISvcLocator* svcLoc) : | ||
Gaudi::Algorithm(name, svcLoc) { | ||
declareProperty("hits", m_hits, "Hits from which to create cells (input)"); | ||
declareProperty("cells", m_cells, "The created calorimeter cells (output)"); | ||
|
||
declareProperty("positionsTool", m_cellPositionsTool, "Handle for cell positions tool"); | ||
declareProperty("crosstalkTool", m_crosstalkTool, "Handle for the cell crosstalk tool"); | ||
declareProperty("calibTool", m_calibTool, "Handle for tool to calibrate Geant4 energy to EM scale tool"); | ||
declareProperty("noiseTool", m_noiseTool, "Handle for the calorimeter cells noise tool"); | ||
declareProperty("geometryTool", m_geoTool, "Handle for the geometry tool"); | ||
} | ||
|
||
StatusCode CreatePositionedCaloCells::initialize() { | ||
StatusCode sc = Gaudi::Algorithm::initialize(); | ||
if (sc.isFailure()) return sc; | ||
|
||
info() << "CreatePositionedCaloCells initialized" << endmsg; | ||
info() << "do calibration : " << m_doCellCalibration << endmsg; | ||
info() << "add cell noise : " << m_addCellNoise << endmsg; | ||
info() << "remove cells below threshold : " << m_filterCellNoise << endmsg; | ||
info() << "emulate crosstalk : " << m_addCrosstalk << endmsg; | ||
|
||
// Initialization of tools | ||
|
||
// Cell position tool | ||
if (!m_cellPositionsTool.retrieve()) { | ||
error() << "Unable to retrieve the cell positions tool!!!" << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
// Cell crosstalk tool | ||
if (m_addCrosstalk) { | ||
if (!m_crosstalkTool.retrieve()) { | ||
error() << "Unable to retrieve the cell crosstalk tool!!!" << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
} | ||
// Calibrate Geant4 energy to EM scale tool | ||
if (m_doCellCalibration) { | ||
if (!m_calibTool.retrieve()) { | ||
error() << "Unable to retrieve the calo cells calibration tool!!!" << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
} | ||
// Cell noise tool | ||
if (m_addCellNoise || m_filterCellNoise) { | ||
if (!m_noiseTool.retrieve()) { | ||
error() << "Unable to retrieve the calo cells noise tool!!!" << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
// Geometry settings | ||
if (!m_geoTool.retrieve()) { | ||
error() << "Unable to retrieve the geometry tool!!!" << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
// Prepare map of all existing cells in calorimeter to add noise to all | ||
StatusCode sc_prepareCells = m_geoTool->prepareEmptyCells(m_cellsMap); | ||
if (sc_prepareCells.isFailure()) { | ||
error() << "Unable to create empty cells!" << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
} | ||
|
||
// Copy over the CellIDEncoding string from the input collection to the output collection | ||
auto hitsEncoding = m_hitsCellIDEncoding.get_optional(); | ||
if (!hitsEncoding.has_value()) { | ||
error () << "Missing cellID encoding for input collection" << endmsg; | ||
return StatusCode::FAILURE; | ||
} | ||
m_cellsCellIDEncoding.put(hitsEncoding.value()); | ||
|
||
return StatusCode::SUCCESS; | ||
} | ||
|
||
StatusCode CreatePositionedCaloCells::execute(const EventContext&) const { | ||
// Get the input collection with Geant4 hits | ||
const edm4hep::SimCalorimeterHitCollection* hits = m_hits.get(); | ||
debug() << "Input Hit collection size: " << hits->size() << endmsg; | ||
|
||
// 0. Clear all cells | ||
if (m_addCellNoise) { | ||
std::for_each(m_cellsMap.begin(), m_cellsMap.end(), [](std::pair<const uint64_t, double>& p) { p.second = 0; }); | ||
} else { | ||
m_cellsMap.clear(); | ||
} | ||
|
||
|
||
// 1. Merge energy deposits into cells | ||
// If running with noise, map was already prepared in initialize(). | ||
// Otherwise it is being created below | ||
for (const auto& hit : *hits) { | ||
verbose() << "CellID : " << hit.getCellID() << endmsg; | ||
m_cellsMap[hit.getCellID()] += hit.getEnergy(); | ||
} | ||
debug() << "Number of calorimeter cells after merging of hits: " << m_cellsMap.size() << endmsg; | ||
|
||
// 2. Emulate cross-talk (if asked) | ||
if (m_addCrosstalk) { | ||
// Derive the cross-talk contributions without affecting yet the nominal energy | ||
// (one has to emulate crosstalk based on cells free from any cross-talk contributions) | ||
m_crosstalkCellsMap.clear(); // this is a temporary map to hold energy exchange due to cross-talk, without affecting yet the nominal energy | ||
// loop over cells with nominal energies | ||
for (const auto& this_cell : m_cellsMap) { | ||
uint64_t this_cellId = this_cell.first; | ||
auto vec_neighbours = m_crosstalkTool->getNeighbours(this_cellId); // a vector of neighbour IDs | ||
auto vec_crosstalks = m_crosstalkTool->getCrosstalks(this_cellId); // a vector of crosstalk coefficients | ||
// loop over crosstalk neighbours of the cell under study | ||
for (unsigned int i_cell=0; i_cell<vec_neighbours.size(); i_cell++) { | ||
// signal transfer = energy deposit brought by EM shower hits * crosstalk coefficient | ||
double signal_transfer = this_cell.second * vec_crosstalks[i_cell]; | ||
// for the cell under study, record the signal transfer that will be subtracted from its final cell energy | ||
m_crosstalkCellsMap[this_cellId] -= signal_transfer; | ||
// for the crosstalk neighbour, record the signal transfer that will be added to its final cell energy | ||
m_crosstalkCellsMap[vec_neighbours[i_cell]] += signal_transfer; | ||
} | ||
} | ||
|
||
// apply the cross-talk contributions on the nominal cell-energy map | ||
for (const auto& this_cell : m_crosstalkCellsMap) { | ||
m_cellsMap[this_cell.first] += this_cell.second; | ||
} | ||
|
||
} | ||
|
||
// 3. Calibrate simulation energy to EM scale | ||
if (m_doCellCalibration) { | ||
m_calibTool->calibrate(m_cellsMap); | ||
} | ||
|
||
// 4. Add noise to all cells | ||
if (m_addCellNoise) { | ||
m_noiseTool->addRandomCellNoise(m_cellsMap); | ||
} | ||
|
||
// 5. Filter cells | ||
if (m_filterCellNoise) { | ||
m_noiseTool->filterCellNoise(m_cellsMap); | ||
} | ||
|
||
// 6. Copy information to CaloHitCollection | ||
edm4hep::CalorimeterHitCollection* edmCellsCollection = new edm4hep::CalorimeterHitCollection(); | ||
for (const auto& cell : m_cellsMap) { | ||
if (m_addCellNoise || (!m_addCellNoise && cell.second != 0)) { | ||
auto newCell = edmCellsCollection->create(); | ||
newCell.setEnergy(cell.second); | ||
uint64_t cellid = cell.first; | ||
newCell.setCellID(cellid); | ||
|
||
// add cell position | ||
auto cached_pos = m_positions_cache.find(cellid); | ||
if(cached_pos == m_positions_cache.end()) { | ||
// retrieve position from tool | ||
dd4hep::Position posCell = m_cellPositionsTool->xyzPosition(cellid); | ||
edm4hep::Vector3f edmPos; | ||
edmPos.x = posCell.x() / dd4hep::mm; | ||
edmPos.y = posCell.y() / dd4hep::mm; | ||
edmPos.z = posCell.z() / dd4hep::mm; | ||
m_positions_cache[cellid] = edmPos; | ||
newCell.setPosition(edmPos); | ||
} | ||
else { | ||
newCell.setPosition(cached_pos->second); | ||
} | ||
|
||
debug() << "Cell energy (GeV) : " << newCell.getEnergy() << "\tcellID " << newCell.getCellID() << endmsg; | ||
debug() << "Position of cell (mm) : \t" << newCell.getPosition().x/dd4hep::mm | ||
<< "\t" << newCell.getPosition().y/dd4hep::mm | ||
<< "\t" << newCell.getPosition().z/dd4hep::mm << endmsg; | ||
} | ||
} | ||
|
||
// push the CaloHitCollection to event store | ||
m_cells.put(edmCellsCollection); | ||
|
||
debug() << "Output Cell collection size: " << edmCellsCollection->size() << endmsg; | ||
|
||
return StatusCode::SUCCESS; | ||
} | ||
|
||
StatusCode CreatePositionedCaloCells::finalize() { return Gaudi::Algorithm::finalize(); } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#ifndef RECCALORIMETER_CREATEPOSITIONEDCALOCELLS_H | ||
#define RECCALORIMETER_CREATEPOSITIONEDCALOCELLS_H | ||
|
||
// k4FWCore | ||
#include "k4FWCore/DataHandle.h" | ||
#include "k4FWCore/MetaDataHandle.h" | ||
#include "k4Interface/ICellPositionsTool.h" | ||
#include "k4Interface/ICalibrateCaloHitsTool.h" | ||
#include "k4Interface/ICalorimeterTool.h" | ||
#include "k4Interface/INoiseCaloCellsTool.h" | ||
#include "k4Interface/ICaloReadCrosstalkMap.h" | ||
|
||
// Gaudi | ||
#include "Gaudi/Algorithm.h" | ||
#include "GaudiKernel/ToolHandle.h" | ||
|
||
// edm4hep | ||
#include "edm4hep/CalorimeterHitCollection.h" | ||
#include "edm4hep/SimCalorimeterHitCollection.h" | ||
|
||
/** @class CreatePositionedCaloCells | ||
* | ||
* Algorithm for creating positioned calorimeter cells from Geant4 hits. | ||
* Based on CreateCaloCells, adding a positioning tool so that output | ||
* cells from the digitisation contain the correct position in 3D space. | ||
* | ||
* Flow of the program: | ||
* 1/ Merge Geant4 energy deposits with same cellID | ||
* 2/ Emulate cross-talk (if switched on) | ||
* 3/ Calibrate to electromagnetic scale (if calibration switched on) | ||
* 4/ Add random noise to each cell (if noise switched on) | ||
* 5/ Filter cells and remove those with energy below threshold (if noise + | ||
* filtering switched on) | ||
* 6/ Add cell positions | ||
* | ||
* Tools called: | ||
* - CalibrateCaloHitsTool | ||
* - NoiseCaloCellsTool | ||
* - CaloReadCrosstalkMap | ||
* - CalorimeterTool (for geometry) | ||
* - CellPositionsTool | ||
* | ||
* @author Giovanni Marchiori | ||
* @date 2024-07 | ||
* | ||
*/ | ||
|
||
class CreatePositionedCaloCells : public Gaudi::Algorithm { | ||
|
||
public: | ||
CreatePositionedCaloCells(const std::string& name, ISvcLocator* svcLoc); | ||
|
||
StatusCode initialize(); | ||
|
||
StatusCode execute(const EventContext&) const; | ||
|
||
StatusCode finalize(); | ||
|
||
private: | ||
/// Handle for tool to get cells positions | ||
ToolHandle<ICellPositionsTool> m_cellPositionsTool{"CellPositionsTool", this}; | ||
/// Handle for the calorimeter cells crosstalk tool | ||
mutable ToolHandle<ICaloReadCrosstalkMap> m_crosstalkTool{"ReadCaloCrosstalkMap", this}; | ||
/// Handle for tool to calibrate Geant4 energy to EM scale tool | ||
mutable ToolHandle<ICalibrateCaloHitsTool> m_calibTool{"CalibrateCaloHitsTool", this}; | ||
/// Handle for the calorimeter cells noise tool | ||
mutable ToolHandle<INoiseCaloCellsTool> m_noiseTool{"NoiseCaloCellsFlatTool", this}; | ||
/// Handle for the geometry tool | ||
ToolHandle<ICalorimeterTool> m_geoTool{"TubeLayerPhiEtaCaloTool", this}; | ||
|
||
/// Add crosstalk to cells? | ||
Gaudi::Property<bool> m_addCrosstalk{this, "addCrosstalk", false, "Add crosstalk effect?"}; | ||
/// Calibrate to EM scale? | ||
Gaudi::Property<bool> m_doCellCalibration{this, "doCellCalibration", true, "Calibrate to EM scale?"}; | ||
/// Add noise to cells? | ||
Gaudi::Property<bool> m_addCellNoise{this, "addCellNoise", true, "Add noise to cells?"}; | ||
/// Save only cells with energy above threshold? | ||
Gaudi::Property<bool> m_filterCellNoise{this, "filterCellNoise", false, | ||
"Save only cells with energy above threshold?"}; | ||
|
||
/// Handle for calo hits (input collection) | ||
mutable DataHandle<edm4hep::SimCalorimeterHitCollection> m_hits{"hits", Gaudi::DataHandle::Reader, this}; | ||
/// Handle for the cellID encoding string of the input collection | ||
MetaDataHandle<std::string> m_hitsCellIDEncoding{m_hits, edm4hep::labels::CellIDEncoding, Gaudi::DataHandle::Reader}; | ||
/// Handle for calo cells (output collection) | ||
mutable DataHandle<edm4hep::CalorimeterHitCollection> m_cells{"cells", Gaudi::DataHandle::Writer, this}; | ||
MetaDataHandle<std::string> m_cellsCellIDEncoding{m_cells, edm4hep::labels::CellIDEncoding, Gaudi::DataHandle::Writer}; | ||
/// Maps of cell IDs (corresponding to DD4hep IDs) on final energies to be used for clustering | ||
mutable std::unordered_map<uint64_t, double> m_cellsMap; | ||
/// Maps of cell IDs (corresponding to DD4hep IDs) on transfer of signals due to crosstalk | ||
mutable std::unordered_map<uint64_t, double> m_crosstalkCellsMap; | ||
|
||
/// Cache position vs cellID | ||
mutable std::unordered_map<dd4hep::DDSegmentation::CellID, edm4hep::Vector3f> m_positions_cache{}; | ||
}; | ||
|
||
#endif /* RECCALORIMETER_CREATEPOSITIONEDCALOCELLS_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this worthy of crashing, can't this be just a warning?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's exactly as in CreateCaloCells (
k4RecCalorimeter/RecCalorimeter/src/components/CreateCaloCells.cpp
Line 78 in 02d796b