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 
10 #include "GaudiKernel/ITHistSvc.h"
12 #include "TTree.h"
14 #include "TrkTrack/Track.h"
15 
16 namespace Muon {
17 
19  MuonTruthSummaryTool::MuonTruthSummaryTool(const std::string& t, const std::string& n, const IInterface* p) :
20  AthAlgTool(t, n, p),
21  m_incidentSvc("IncidentSvc", n),
22  m_wasInit(false),
23  m_truthHitsTotal(0),
24  m_tree(nullptr),
25  m_thistSvc(nullptr),
26  m_writeTree(false),
27  m_level(0) {
28  declareInterface<IMuonTruthSummaryTool>(this);
29  declareProperty("WriteNtuple", m_writeTree);
30  declareProperty("NtupleTreeName", m_treeName = "MuonTruthSummaryTree");
31  declareProperty("HistStream", m_histStream = "Summary");
32  declareProperty("SelectedPdgId", m_selectedPdgId = 13, "Should be positive as absolute value is used");
33  }
34 
36  ATH_MSG_VERBOSE("Initializing ...");
37  ATH_CHECK(m_idHelperSvc.retrieve());
38  ATH_CHECK(m_printer.retrieve());
39  ATH_CHECK(m_edmHelperSvc.retrieve());
40  ATH_CHECK(m_incidentSvc.retrieve());
41 
42  m_incidentSvc->addListener(this, std::string("EndEvent"));
43 
44  if (m_writeTree) {
45  ATH_CHECK(service("THistSvc", m_thistSvc));
46 
47  m_tree = new TTree(m_treeName.c_str(), "Ntuple of MuonTruthSummary");
48  constexpr int NUM_LEVELS = 3; // Hardcoding to 3 levels for the moment.
49 
50  std::string treePathAndName("/");
51  treePathAndName += m_histStream;
52  treePathAndName += "/";
53  treePathAndName += m_treeName;
54 
55  ATH_CHECK(m_thistSvc->regTree(treePathAndName.c_str(), m_tree));
56  ATH_MSG_VERBOSE("Registered tree as " << treePathAndName);
57 
59  }
60  if (m_selectedPdgId < 0) {
61  ATH_MSG_WARNING("SelectedPdgId should be positive, taking the absolute value");
63  }
64 
65  if (m_idHelperSvc->hasMM()) m_TruthNames.emplace_back("MM_TruthMap");
66  if (m_idHelperSvc->hasSTGC()) m_TruthNames.emplace_back("STGC_TruthMap");
67  if (m_idHelperSvc->hasCSC()) m_TruthNames.emplace_back("CSC_TruthMap");
68  ATH_CHECK(m_TruthNames.initialize());
69  return StatusCode::SUCCESS;
70  }
71 
73  ATH_MSG_INFO("Of " << m_truthHitsTotal << " truth hits in total...");
74  for (auto level : m_lossesPerLevel) { ATH_MSG_INFO(level.second << " \ttruth hits lost at level :" << level.first); }
75  return StatusCode::SUCCESS;
76  }
77 
79  std::scoped_lock lock(m_mutex);
80  m_wasInit = false;
81  m_truthHits.clear();
82  m_truthDataPerLevel.clear();
83  }
84 
86  std::scoped_lock lock(m_mutex);
87  if (!m_wasInit) {
89  if (!col.isValid() || !col.isPresent()) continue;
90  ATH_MSG_DEBUG("PRD_MultiTruthCollection " << col.key() << " found");
91  PRD_MultiTruthCollection::const_iterator it = col->begin();
92  PRD_MultiTruthCollection::const_iterator it_end = col->end();
93  for (; it != it_end; ++it) {
94  const HepMcParticleLink& link = it->second;
95  if (link.cptr() && (std::abs(link.cptr()->pdg_id()) == m_selectedPdgId || std::abs(link.cptr()->pdg_id()) == 13)) {
96  int bc = HepMC::barcode(link); // FIXME barcode-based
97  m_truthHits[it->first] = bc; // FIXME barcode-based
98  m_pdgIdLookupFromBarcode[bc] = link.cptr()->pdg_id(); // FIXME barcode-based
99 
100  }
101  }
102  }
103  m_wasInit = true;
104  ATH_MSG_DEBUG(" Total collected muon truth hits " << m_truthHits.size());
105  }
106  }
107 
108  int MuonTruthSummaryTool::getPdgId(int barcode) const { // FIXME barcode-based
109  init();
110  std::scoped_lock lock(m_mutex);
111  auto pos = m_pdgIdLookupFromBarcode.find(barcode);
112  if (pos == m_pdgIdLookupFromBarcode.end()) return 0;
113  return pos->second;
114  }
115 
116  int MuonTruthSummaryTool::getBarcode(const Identifier& id) const { // FIXME barcode-based
117  init();
118  std::scoped_lock lock(m_mutex);
119  auto pos = m_truthHits.find(id);
120  if (pos == m_truthHits.end()) return -1;
121  return pos->second;
122  }
123 
124  void MuonTruthSummaryTool::add(const Identifier& id, int level) const {
125  init();
126  std::scoped_lock lock(m_mutex);
127  if (m_truthHits.count(id)) m_truthDataPerLevel[level].insert(id);
128  }
129 
131 
133  std::scoped_lock lock(m_mutex);
134  const DataVector<const Trk::MeasurementBase>* meas = track.measurementsOnTrack();
135  if (meas) add(meas->stdcont(), level);
136  }
137 
138  void MuonTruthSummaryTool::add(const std::vector<const Trk::MeasurementBase*>& measurements, int level) const {
139  std::scoped_lock lock(m_mutex);
140  for (std::vector<const Trk::MeasurementBase*>::const_iterator it = measurements.begin(); it != measurements.end(); ++it) {
141  Identifier id = m_edmHelperSvc->getIdentifier(**it);
142  if (id.is_valid() && m_idHelperSvc->isMuon(id)) add(id, level);
143  }
144  }
145 
147  std::scoped_lock lock(m_mutex);
148  if (m_truthHits.empty()) return "Event without truth hits";
149  if (m_truthDataPerLevel.empty()) return "No hits added";
150  std::ostringstream sout;
151  sout << "Have " << m_truthHits.size() << " truth hits and " << m_truthDataPerLevel.size() << " levels filled." << std::endl;
152 
153  std::unordered_set<Identifier, IdentifierHash> truthHits;
154  for (auto it = m_truthHits.begin(); it != m_truthHits.end(); ++it) truthHits.insert(it->first);
155 
156  m_truthHitsTotal += truthHits.size();
157  sout << " Summarizing: truth hits " << truthHits.size() << " levels filled " << m_truthDataPerLevel.size() << std::endl;
158  for (auto& pair : m_truthDataPerLevel) {
159  m_level = pair.first - 1;
161  sout << " Comparing truth to level " << m_level << std::endl << printSummary(truthHits, pair.second);
162  m_lossesPerLevel[pair.first] += (truthHits.size() - pair.second.size());
163  }
164  if (m_writeTree) {
165  std::cout << "About to try to fill try tree " << m_tree->GetName() << std::endl;
166  std::cout << "m_numChambers size = " << m_numChambers.size() << ", val [0] = " << m_numChambers[0] << std::endl;
167 
168  m_tree->Fill();
169  }
170  return sout.str();
171  }
172 
173  std::string MuonTruthSummaryTool::printSummary(const std::unordered_set<Identifier, IdentifierHash>& truth,
174  const std::unordered_set<Identifier, MuonTruthSummaryTool::IdentifierHash>& found) {
175  std::scoped_lock lock(m_mutex);
176  std::ostringstream sout;
177  if (truth.size() != found.size()) {
178  sout << " Some truth hits not found: truth " << truth.size() << " found " << found.size() << std::endl;
179  std::set<Identifier> truthset(truth.begin(), truth.end());
180  std::set<Identifier> foundset(found.begin(), found.end());
181  std::vector<Identifier> result(truth.size() - found.size());
183  std::set_difference(truthset.begin(), truthset.end(), foundset.begin(), foundset.end(), result.begin());
184  result.resize(pos - result.begin());
185  int nmm = 0;
186  std::map<Identifier, unsigned int> chambers; // Store counts per chamber Id
187  unsigned int hitNum = 0;
188  for (std::vector<Identifier>::iterator it = result.begin(); it != result.end(); ++it) {
189  sout << hitNum++ << ":\t" << m_idHelperSvc->toString(*it) << std::endl;
190  if (m_idHelperSvc->isMM(*it)) ++nmm;
191  chambers[m_idHelperSvc->chamberId(*it)]++;
192  }
193  if (nmm > 4) sout << " possible missing MM segment : " << nmm << std::endl;
194 
195  sout << std::endl << "++++ Chamber summaries:" << std::endl;
196  for (auto chamber : chambers) {
197  sout << "Chamber " << m_idHelperSvc->toStringChamber(chamber.first) << "\t has " << chamber.second << " missing truth hits"
198  << std::endl;
199  if (m_writeTree) fillChamberVariables(chamber.first, chamber.second);
200  }
201  } else {
202  sout << " All hits found: truth " << truth.size() << " found " << found.size() << std::endl;
203  }
204  return sout.str();
205  }
206 
207  void MuonTruthSummaryTool::initChamberVariables(const unsigned int levels) {
208  std::scoped_lock lock(m_mutex);
209  if (!m_tree) {
210  ATH_MSG_WARNING("Trying to write ntuple, but tree is zero. Setting WriteNtuple to False");
211  m_writeTree = false;
212  }
213  m_numChambers.resize(levels);
214  m_numMissedHits.resize(levels);
215  m_missedHitTechnologyIndex.resize(levels);
216  m_missedHitStationPhi.resize(levels);
217  m_missedHitStationSector.resize(levels);
218  m_missedHitStationEta.resize(levels);
219  // m_missedHitR.resize(levels);
220  // m_missedHitZ.resize(levels);
221  // m_missedHitStationName.resize(levels);
222  m_missedHitStationNameIndex.resize(levels);
223 
224  for (unsigned int level = 0; level < levels; level++) {
225  m_numChambers[level] = 0;
226  m_numMissedHits[level] = new std::vector<uint8_t>;
227  m_missedHitTechnologyIndex[level] = new std::vector<uint8_t>;
228  m_missedHitStationPhi[level] = new std::vector<int>;
229  m_missedHitStationSector[level] = new std::vector<int>;
230  m_missedHitStationEta[level] = new std::vector<int>;
231  // m_missedHitR[level] = new std::vector<float>;
232  // m_missedHitZ[level] = new std::vector<float>;
233  // m_missedHitStationName[level] = new std::vector<std::string>;
234  m_missedHitStationNameIndex[level] = new std::vector<int>;
235 
236  std::string name = "numMissedHitsForLevel" + std::to_string(level);
237  std::string leafThing = name + std::string("/i");
238  // std::cout<<"m_numChambers["<<level<<"] = "<<m_numChambers[level]<<std::endl;
239  m_tree->Branch(name.c_str(), &m_numChambers[level], leafThing.c_str());
240  name = "numMissedHitsForLevel" + std::to_string(level);
241  m_tree->Branch(name.c_str(), &m_numMissedHits[level]);
242  name = "TechnologyIndexForLevel" + std::to_string(level);
243  m_tree->Branch(name.c_str(), &m_missedHitTechnologyIndex[level]);
244  name = "MissedHitStationPhiForLevel" + std::to_string(level);
245  m_tree->Branch(name.c_str(), &m_missedHitStationPhi[level]);
246  name = "MissedHitStationSectorForLevel" + std::to_string(level);
247  m_tree->Branch(name.c_str(), &m_missedHitStationSector[level]);
248  name = "MissedHitStationEtaForLevel" + std::to_string(level);
249  m_tree->Branch(name.c_str(), &(m_missedHitStationEta[level]));
250  // name = "MissedHitRForLevel"+std::to_string(level);
251  // m_tree->Branch(name.c_str(), &(m_missedHitR[level]));
252  // name = "MissedHitZForLevel"+std::to_string(level);
253  // m_tree->Branch(name.c_str(), &(m_missedHitZ[level]));
254  // name = "MissedHitStationName for level "+std::to_string(level);
255  // m_tree->Branch(name.c_str(), &m_missedHitStationName[level]);
256  name = "MissedHitStationNameIndexForLevel" + std::to_string(level);
257  m_tree->Branch(name.c_str(), &m_missedHitStationNameIndex[level]);
258  }
259  }
260 
262  std::scoped_lock lock(m_mutex);
263  ATH_MSG_DEBUG("clearChamberVariables: Level = " << level + 1);
264  m_numChambers[level] = 0;
265  m_numMissedHits[level]->clear();
267  m_missedHitStationPhi[level]->clear();
269  m_missedHitStationEta[level]->clear();
270  // m_missedHitR[level]->clear();
271  // m_missedHitZ[level]->clear();
272  // m_missedHitStationName[level]->clear();
274  }
275 
276  void MuonTruthSummaryTool::fillChamberVariables(const Identifier& chamberId, const unsigned int numMissedHits) {
277  std::scoped_lock lock(m_mutex);
278  ATH_MSG_DEBUG("fillChamberVariables: Level = " << (m_level + 1) << " \t chamber = " << m_idHelperSvc->toStringChamber(chamberId)
279  << " numMissedHits=" << numMissedHits);
280 
282  m_numMissedHits[m_level]->push_back(numMissedHits);
283  m_missedHitTechnologyIndex[m_level]->push_back(m_idHelperSvc->technologyIndex(chamberId));
284  m_missedHitStationPhi[m_level]->push_back(m_idHelperSvc->stationPhi(chamberId));
285  m_missedHitStationSector[m_level]->push_back(m_idHelperSvc->sector(chamberId));
286  m_missedHitStationEta[m_level]->push_back(m_idHelperSvc->stationEta(chamberId));
287  m_missedHitStationNameIndex[m_level]->push_back(m_idHelperSvc->stationIndex(chamberId));
288  }
289 
290  void MuonTruthSummaryTool::handle(const Incident& inc) {
291  // Only clear cache for EndEvent incident
292  if (inc.type() == "EndEvent") {
294  clear();
295  }
296  }
297 } // namespace Muon
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
get_generator_info.result
result
Definition: get_generator_info.py:21
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
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:146
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:423
Muon::MuonTruthSummaryTool::finalize
StatusCode finalize()
Definition: MuonTruthSummaryTool.cxx:72
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:290
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:49
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:108
Track.h
Muon::MuonTruthSummaryTool::clear
void clear()
clear tool
Definition: MuonTruthSummaryTool.cxx:78
Muon::MuonTruthSummaryTool::clearChamberVariables
void clearChamberVariables(const unsigned int level)
Definition: MuonTruthSummaryTool.cxx:261
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
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: TrkEvent/TrkSegment/TrkSegment/Segment.h:166
Muon::MuonTruthSummaryTool::init
void init() const
init truth
Definition: MuonTruthSummaryTool.cxx:85
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Muon::MuonTruthSummaryTool::initialize
StatusCode initialize()
Definition: MuonTruthSummaryTool.cxx:35
DataVector< const Trk::MeasurementBase >
Muon::MuonTruthSummaryTool::fillChamberVariables
void fillChamberVariables(const Identifier &chamberId, const unsigned int numMissedHits)
Definition: MuonTruthSummaryTool.cxx:276
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:192
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:207
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:116
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:124
Muon::MuonTruthSummaryTool::m_missedHitStationNameIndex
std::vector< std::vector< int > * > m_missedHitStationNameIndex
Definition: MuonTruthSummaryTool.h:136
Muon::MuonTruthSummaryTool::m_thistSvc
ITHistSvc * m_thistSvc
Definition: MuonTruthSummaryTool.h:120
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:19
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