ATLAS Offline Software
MuonTruthSummaryTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "MuonTruthSummaryTool.h"
6 
7 #include <iostream>
8 
11 #include "TTree.h"
13 #include "TrkTrack/Track.h"
14 
15 namespace Muon {
16 
18  MuonTruthSummaryTool::MuonTruthSummaryTool(const std::string& t, const std::string& n, const IInterface* p) :
19  AthAlgTool(t, n, p),
20  m_incidentSvc("IncidentSvc", n),
21  m_wasInit(false),
22  m_truthHitsTotal(0),
23  m_tree(nullptr),
24  m_thistSvc("THistSvc", n),
25  m_writeTree(false),
26  m_level(0) {
27  declareInterface<IMuonTruthSummaryTool>(this);
28  declareProperty("WriteNtuple", m_writeTree);
29  declareProperty("NtupleTreeName", m_treeName = "MuonTruthSummaryTree");
30  declareProperty("HistStream", m_histStream = "Summary");
31  declareProperty("SelectedPdgId", m_selectedPdgId = 13, "Should be positive as absolute value is used");
32  }
33 
35  ATH_MSG_VERBOSE("Initializing ...");
36  ATH_CHECK(m_idHelperSvc.retrieve());
37  ATH_CHECK(m_printer.retrieve());
38  ATH_CHECK(m_edmHelperSvc.retrieve());
39  ATH_CHECK(m_incidentSvc.retrieve());
40 
41  m_incidentSvc->addListener(this, std::string("EndEvent"));
42 
43  if (m_writeTree) {
44  ATH_CHECK(m_thistSvc.retrieve());
45 
46  m_tree = new TTree(m_treeName.c_str(), "Ntuple of MuonTruthSummary");
47  constexpr int NUM_LEVELS = 3; // Hardcoding to 3 levels for the moment.
48 
49  std::string treePathAndName("/");
50  treePathAndName += m_histStream;
51  treePathAndName += "/";
52  treePathAndName += m_treeName;
53 
54  ATH_CHECK(m_thistSvc->regTree(treePathAndName.c_str(), m_tree));
55  ATH_MSG_VERBOSE("Registered tree as " << treePathAndName);
56 
58  }
59  if (m_selectedPdgId < 0) {
60  ATH_MSG_WARNING("SelectedPdgId should be positive, taking the absolute value");
62  }
63 
64  if (m_idHelperSvc->hasMM()) m_TruthNames.emplace_back("MM_TruthMap");
65  if (m_idHelperSvc->hasSTGC()) m_TruthNames.emplace_back("STGC_TruthMap");
66  if (m_idHelperSvc->hasCSC()) m_TruthNames.emplace_back("CSC_TruthMap");
67  ATH_CHECK(m_TruthNames.initialize());
68  return StatusCode::SUCCESS;
69  }
70 
72  ATH_MSG_INFO("Of " << m_truthHitsTotal << " truth hits in total...");
73  for (auto level : m_lossesPerLevel) { ATH_MSG_INFO(level.second << " \ttruth hits lost at level :" << level.first); }
74  return StatusCode::SUCCESS;
75  }
76 
78  std::scoped_lock lock(m_mutex);
79  m_wasInit = false;
80  m_truthHits.clear();
81  m_truthDataPerLevel.clear();
82  }
83 
85  std::scoped_lock lock(m_mutex);
86  if (!m_wasInit) {
88  if (!col.isValid() || !col.isPresent()) continue;
89  ATH_MSG_DEBUG("PRD_MultiTruthCollection " << col.key() << " found");
90  PRD_MultiTruthCollection::const_iterator it = col->begin();
91  PRD_MultiTruthCollection::const_iterator it_end = col->end();
92  for (; it != it_end; ++it) {
93  const HepMcParticleLink& link = it->second;
94  if (link.cptr() && (std::abs(link.cptr()->pdg_id()) == m_selectedPdgId || std::abs(link.cptr()->pdg_id()) == 13)) {
95  int bc = HepMC::barcode(link); // FIXME barcode-based
96  m_truthHits[it->first] = bc; // FIXME barcode-based
97  m_pdgIdLookupFromBarcode[bc] = link.cptr()->pdg_id(); // FIXME barcode-based
98 
99  }
100  }
101  }
102  m_wasInit = true;
103  ATH_MSG_DEBUG(" Total collected muon truth hits " << m_truthHits.size());
104  }
105  }
106 
107  int MuonTruthSummaryTool::getPdgId(int barcode) const { // FIXME barcode-based
108  init();
109  std::scoped_lock lock(m_mutex);
110  auto pos = m_pdgIdLookupFromBarcode.find(barcode);
111  if (pos == m_pdgIdLookupFromBarcode.end()) return 0;
112  return pos->second;
113  }
114 
115  int MuonTruthSummaryTool::getBarcode(const Identifier& id) const { // FIXME barcode-based
116  init();
117  std::scoped_lock lock(m_mutex);
118  auto pos = m_truthHits.find(id);
119  if (pos == m_truthHits.end()) return -1;
120  return pos->second;
121  }
122 
123  void MuonTruthSummaryTool::add(const Identifier& id, int level) const {
124  init();
125  std::scoped_lock lock(m_mutex);
126  if (m_truthHits.count(id)) m_truthDataPerLevel[level].insert(id);
127  }
128 
130 
132  std::scoped_lock lock(m_mutex);
133  const DataVector<const Trk::MeasurementBase>* meas = track.measurementsOnTrack();
134  if (meas) add(meas->stdcont(), level);
135  }
136 
137  void MuonTruthSummaryTool::add(const std::vector<const Trk::MeasurementBase*>& measurements, int level) const {
138  std::scoped_lock lock(m_mutex);
139  for (std::vector<const Trk::MeasurementBase*>::const_iterator it = measurements.begin(); it != measurements.end(); ++it) {
140  Identifier id = m_edmHelperSvc->getIdentifier(**it);
141  if (id.is_valid() && m_idHelperSvc->isMuon(id)) add(id, level);
142  }
143  }
144 
146  std::scoped_lock lock(m_mutex);
147  if (m_truthHits.empty()) return "Event without truth hits";
148  if (m_truthDataPerLevel.empty()) return "No hits added";
149  std::ostringstream sout;
150  sout << "Have " << m_truthHits.size() << " truth hits and " << m_truthDataPerLevel.size() << " levels filled." << std::endl;
151 
152  std::unordered_set<Identifier, IdentifierHash> truthHits;
153  for (auto it = m_truthHits.begin(); it != m_truthHits.end(); ++it) truthHits.insert(it->first);
154 
155  m_truthHitsTotal += truthHits.size();
156  sout << " Summarizing: truth hits " << truthHits.size() << " levels filled " << m_truthDataPerLevel.size() << std::endl;
157  for (auto& pair : m_truthDataPerLevel) {
158  m_level = pair.first - 1;
160  sout << " Comparing truth to level " << m_level << std::endl << printSummary(truthHits, pair.second);
161  m_lossesPerLevel[pair.first] += (truthHits.size() - pair.second.size());
162  }
163  if (m_writeTree) {
164  std::cout << "About to try to fill try tree " << m_tree->GetName() << std::endl;
165  std::cout << "m_numChambers size = " << m_numChambers.size() << ", val [0] = " << m_numChambers[0] << std::endl;
166 
167  m_tree->Fill();
168  }
169  return sout.str();
170  }
171 
172  std::string MuonTruthSummaryTool::printSummary(const std::unordered_set<Identifier, IdentifierHash>& truth,
173  const std::unordered_set<Identifier, MuonTruthSummaryTool::IdentifierHash>& found) {
174  std::scoped_lock lock(m_mutex);
175  std::ostringstream sout;
176  if (truth.size() != found.size()) {
177  sout << " Some truth hits not found: truth " << truth.size() << " found " << found.size() << std::endl;
178  std::set<Identifier> truthset(truth.begin(), truth.end());
179  std::set<Identifier> foundset(found.begin(), found.end());
180  std::vector<Identifier> result(truth.size() - found.size());
182  std::set_difference(truthset.begin(), truthset.end(), foundset.begin(), foundset.end(), result.begin());
183  result.resize(pos - result.begin());
184  int nmm = 0;
185  std::map<Identifier, unsigned int> chambers; // Store counts per chamber Id
186  unsigned int hitNum = 0;
187  for (std::vector<Identifier>::iterator it = result.begin(); it != result.end(); ++it) {
188  sout << hitNum++ << ":\t" << m_idHelperSvc->toString(*it) << std::endl;
189  if (m_idHelperSvc->isMM(*it)) ++nmm;
190  chambers[m_idHelperSvc->chamberId(*it)]++;
191  }
192  if (nmm > 4) sout << " possible missing MM segment : " << nmm << std::endl;
193 
194  sout << std::endl << "++++ Chamber summaries:" << std::endl;
195  for (auto chamber : chambers) {
196  sout << "Chamber " << m_idHelperSvc->toStringChamber(chamber.first) << "\t has " << chamber.second << " missing truth hits"
197  << std::endl;
198  if (m_writeTree) fillChamberVariables(chamber.first, chamber.second);
199  }
200  } else {
201  sout << " All hits found: truth " << truth.size() << " found " << found.size() << std::endl;
202  }
203  return sout.str();
204  }
205 
206  void MuonTruthSummaryTool::initChamberVariables(const unsigned int levels) {
207  std::scoped_lock lock(m_mutex);
208  if (!m_tree) {
209  ATH_MSG_WARNING("Trying to write ntuple, but tree is zero. Setting WriteNtuple to False");
210  m_writeTree = false;
211  }
212  m_numChambers.resize(levels);
213  m_numMissedHits.resize(levels);
214  m_missedHitTechnologyIndex.resize(levels);
215  m_missedHitStationPhi.resize(levels);
216  m_missedHitStationSector.resize(levels);
217  m_missedHitStationEta.resize(levels);
218  // m_missedHitR.resize(levels);
219  // m_missedHitZ.resize(levels);
220  // m_missedHitStationName.resize(levels);
221  m_missedHitStationNameIndex.resize(levels);
222 
223  for (unsigned int level = 0; level < levels; level++) {
224  m_numChambers[level] = 0;
225  m_numMissedHits[level] = new std::vector<uint8_t>;
226  m_missedHitTechnologyIndex[level] = new std::vector<uint8_t>;
227  m_missedHitStationPhi[level] = new std::vector<int>;
228  m_missedHitStationSector[level] = new std::vector<int>;
229  m_missedHitStationEta[level] = new std::vector<int>;
230  // m_missedHitR[level] = new std::vector<float>;
231  // m_missedHitZ[level] = new std::vector<float>;
232  // m_missedHitStationName[level] = new std::vector<std::string>;
233  m_missedHitStationNameIndex[level] = new std::vector<int>;
234 
235  std::string name = "numMissedHitsForLevel" + std::to_string(level);
236  std::string leafThing = name + std::string("/i");
237  // std::cout<<"m_numChambers["<<level<<"] = "<<m_numChambers[level]<<std::endl;
238  m_tree->Branch(name.c_str(), &m_numChambers[level], leafThing.c_str());
239  name = "numMissedHitsForLevel" + std::to_string(level);
240  m_tree->Branch(name.c_str(), &m_numMissedHits[level]);
241  name = "TechnologyIndexForLevel" + std::to_string(level);
242  m_tree->Branch(name.c_str(), &m_missedHitTechnologyIndex[level]);
243  name = "MissedHitStationPhiForLevel" + std::to_string(level);
244  m_tree->Branch(name.c_str(), &m_missedHitStationPhi[level]);
245  name = "MissedHitStationSectorForLevel" + std::to_string(level);
246  m_tree->Branch(name.c_str(), &m_missedHitStationSector[level]);
247  name = "MissedHitStationEtaForLevel" + std::to_string(level);
248  m_tree->Branch(name.c_str(), &(m_missedHitStationEta[level]));
249  // name = "MissedHitRForLevel"+std::to_string(level);
250  // m_tree->Branch(name.c_str(), &(m_missedHitR[level]));
251  // name = "MissedHitZForLevel"+std::to_string(level);
252  // m_tree->Branch(name.c_str(), &(m_missedHitZ[level]));
253  // name = "MissedHitStationName for level "+std::to_string(level);
254  // m_tree->Branch(name.c_str(), &m_missedHitStationName[level]);
255  name = "MissedHitStationNameIndexForLevel" + std::to_string(level);
256  m_tree->Branch(name.c_str(), &m_missedHitStationNameIndex[level]);
257  }
258  }
259 
261  std::scoped_lock lock(m_mutex);
262  ATH_MSG_DEBUG("clearChamberVariables: Level = " << level + 1);
263  m_numChambers[level] = 0;
264  m_numMissedHits[level]->clear();
266  m_missedHitStationPhi[level]->clear();
268  m_missedHitStationEta[level]->clear();
269  // m_missedHitR[level]->clear();
270  // m_missedHitZ[level]->clear();
271  // m_missedHitStationName[level]->clear();
273  }
274 
275  void MuonTruthSummaryTool::fillChamberVariables(const Identifier& chamberId, const unsigned int numMissedHits) {
276  std::scoped_lock lock(m_mutex);
277  ATH_MSG_DEBUG("fillChamberVariables: Level = " << (m_level + 1) << " \t chamber = " << m_idHelperSvc->toStringChamber(chamberId)
278  << " numMissedHits=" << numMissedHits);
279 
281  m_numMissedHits[m_level]->push_back(numMissedHits);
282  m_missedHitTechnologyIndex[m_level]->push_back(m_idHelperSvc->technologyIndex(chamberId));
283  m_missedHitStationPhi[m_level]->push_back(m_idHelperSvc->stationPhi(chamberId));
284  m_missedHitStationSector[m_level]->push_back(m_idHelperSvc->sector(chamberId));
285  m_missedHitStationEta[m_level]->push_back(m_idHelperSvc->stationEta(chamberId));
286  m_missedHitStationNameIndex[m_level]->push_back(m_idHelperSvc->stationIndex(chamberId));
287  }
288 
289  void MuonTruthSummaryTool::handle(const Incident& inc) {
290  // Only clear cache for EndEvent incident
291  if (inc.type() == "EndEvent") {
293  clear();
294  }
295  }
296 } // namespace Muon
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
get_generator_info.result
result
Definition: get_generator_info.py:21
MeasurementBase.h
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Muon::MuonTruthSummaryTool::m_numMissedHits
std::vector< std::vector< uint8_t > * > m_numMissedHits
Definition: MuonTruthSummaryTool.h:128
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
Muon::MuonTruthSummaryTool::printSummary
std::string printSummary()
print summary
Definition: MuonTruthSummaryTool.cxx:145
calibdata.chamber
chamber
Definition: calibdata.py:32
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Muon::MuonTruthSummaryTool::m_TruthNames
SG::ReadHandleKeyArray< PRD_MultiTruthCollection > m_TruthNames
Definition: MuonTruthSummaryTool.h:105
Muon::MuonTruthSummaryTool::m_level
unsigned int m_level
Definition: MuonTruthSummaryTool.h:124
skel.it
it
Definition: skel.GENtoEVGEN.py:396
Muon::MuonTruthSummaryTool::finalize
StatusCode finalize()
Definition: MuonTruthSummaryTool.cxx:71
Muon::MuonTruthSummaryTool::m_missedHitStationPhi
std::vector< std::vector< int > * > m_missedHitStationPhi
Definition: MuonTruthSummaryTool.h:130
Muon::MuonTruthSummaryTool::m_numChambers
std::vector< unsigned int > m_numChambers
Definition: MuonTruthSummaryTool.h:127
Muon::MuonTruthSummaryTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MuonTruthSummaryTool.h:84
Muon::MuonTruthSummaryTool::m_mutex
std::recursive_mutex m_mutex
Definition: MuonTruthSummaryTool.h:117
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Muon::MuonTruthSummaryTool::m_printer
PublicToolHandle< MuonEDMPrinterTool > m_printer
Definition: MuonTruthSummaryTool.h:97
Muon::MuonTruthSummaryTool::handle
void handle(const Incident &inc)
Definition: MuonTruthSummaryTool.cxx:289
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Muon
This class provides conversion from CSC RDO data to CSC Digits.
Definition: TrackSystemController.h:45
GenParticle.h
Muon::MuonTruthSummaryTool::m_writeTree
bool m_writeTree
Definition: MuonTruthSummaryTool.h:121
python.iconfTool.models.loaders.level
level
Definition: loaders.py:20
Muon::MuonTruthSummaryTool::getPdgId
int getPdgId(int barcode) const
get the associated pdgId for a given barcode
Definition: MuonTruthSummaryTool.cxx:107
Track.h
Muon::MuonTruthSummaryTool::m_thistSvc
ServiceHandle< ITHistSvc > m_thistSvc
Definition: MuonTruthSummaryTool.h:120
Muon::MuonTruthSummaryTool::clear
void clear()
clear tool
Definition: MuonTruthSummaryTool.cxx:77
Muon::MuonTruthSummaryTool::clearChamberVariables
void clearChamberVariables(const unsigned int level)
Definition: MuonTruthSummaryTool.cxx:260
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
HepMC::barcode
int barcode(const T *p)
Definition: Barcode.h:16
Muon::MuonTruthSummaryTool::m_wasInit
std::atomic< bool > m_wasInit
Definition: MuonTruthSummaryTool.h:103
Trk::Segment::containedMeasurements
const std::vector< const Trk::MeasurementBase * > & containedMeasurements() const
returns the vector of Trk::MeasurementBase objects
Definition: Tracking/TrkEvent/TrkSegment/TrkSegment/Segment.h:166
Muon::MuonTruthSummaryTool::init
void init() const
init truth
Definition: MuonTruthSummaryTool.cxx:84
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Muon::MuonTruthSummaryTool::initialize
StatusCode initialize()
Definition: MuonTruthSummaryTool.cxx:34
DataVector< const Trk::MeasurementBase >
Muon::MuonTruthSummaryTool::fillChamberVariables
void fillChamberVariables(const Identifier &chamberId, const unsigned int numMissedHits)
Definition: MuonTruthSummaryTool.cxx:275
Muon::MuonTruthSummaryTool::m_lossesPerLevel
std::unordered_map< int, unsigned int > m_lossesPerLevel
Definition: MuonTruthSummaryTool.h:114
TrigConf::MSGTC::NUM_LEVELS
@ NUM_LEVELS
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:30
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
Muon::MuonTruthSummaryTool::m_selectedPdgId
int m_selectedPdgId
Definition: MuonTruthSummaryTool.h:125
Muon::MuonTruthSummaryTool::m_histStream
std::string m_histStream
Definition: MuonTruthSummaryTool.h:123
Muon::MuonTruthSummaryTool::initChamberVariables
void initChamberVariables(const unsigned int levels)
Definition: MuonTruthSummaryTool.cxx:206
query_example.col
col
Definition: query_example.py:7
Muon::MuonTruthSummaryTool::getBarcode
int getBarcode(const Identifier &id) const
get the associated barcode for the identifier, return -1 if the channel was not hit by a muon
Definition: MuonTruthSummaryTool.cxx:115
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
MuonTruthSummaryTool.h
DataVector::stdcont
const PtrVector & stdcont() const
Return the underlying std::vector of the container.
Muon::MuonTruthSummaryTool::add
void add(const Identifier &id, int level) const
add identifier
Definition: MuonTruthSummaryTool.cxx:123
Muon::MuonTruthSummaryTool::m_missedHitStationNameIndex
std::vector< std::vector< int > * > m_missedHitStationNameIndex
Definition: MuonTruthSummaryTool.h:136
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Muon::MuonTruthSummaryTool::m_edmHelperSvc
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
Definition: MuonTruthSummaryTool.h:89
Muon::MuonTruthSummaryTool::MuonTruthSummaryTool
MuonTruthSummaryTool(const std::string &t, const std::string &n, const IInterface *p)
Constructor.
Definition: MuonTruthSummaryTool.cxx:18
Muon::MuonTruthSummaryTool::m_missedHitStationEta
std::vector< std::vector< int > * > m_missedHitStationEta
Definition: MuonTruthSummaryTool.h:132
Muon::MuonTruthSummaryTool::m_missedHitTechnologyIndex
std::vector< std::vector< uint8_t > * > m_missedHitTechnologyIndex
Definition: MuonTruthSummaryTool.h:129
MuonSegment.h
Muon::MuonTruthSummaryTool::m_missedHitStationSector
std::vector< std::vector< int > * > m_missedHitStationSector
Definition: MuonTruthSummaryTool.h:131
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
Muon::MuonSegment
Definition: MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonSegment/MuonSegment/MuonSegment.h:45
AthAlgTool
Definition: AthAlgTool.h:26
Muon::MuonTruthSummaryTool::m_incidentSvc
ServiceHandle< IIncidentSvc > m_incidentSvc
Definition: MuonTruthSummaryTool.h:95
Muon::MuonTruthSummaryTool::m_treeName
std::string m_treeName
Definition: MuonTruthSummaryTool.h:122
Muon::MuonTruthSummaryTool::m_tree
TTree * m_tree
Definition: MuonTruthSummaryTool.h:119
Identifier
Definition: IdentifierFieldParser.cxx:14