ATLAS Offline Software
Loading...
Searching...
No Matches
TruthNtupleTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// TruthNtupleTool.cxx
7// Source file for class TruthNtupleTool
9// (c) ATLAS Detector software
11// Sebastian.Fleischmann@cern.ch
13
14// Trk
17// Truth
19
22
23// root
24#include "TTree.h"
25#include <TH1D.h>
26#include <TGraphAsymmErrors.h>
27
28
29#include <cmath>
30
31
32// constructor
34 const std::string& t,
35 const std::string& n,
36 const IInterface* p )
37 :
38 AthAlgTool(t,n,p),
39 m_fillJets(false),
40 m_histSvc("THistSvc", n),
41 m_nt(nullptr),
46 m_mc_prob{},
48 m_mc_d0{},
49 m_mc_z0{},
50 m_mc_phi0{},
51 m_mc_theta{},
52 m_mc_qOverP{},
53 m_mc_qOverPt{},
54 m_mc_eta{},
55
58 m_mc_energy{},
60 m_mc_prodR{},
62{
63 declareInterface<ITruthNtupleTool>(this);
64
65 m_etaBins.push_back(0.0);
66 m_etaBins.push_back(0.8);
67 m_etaBins.push_back(1.6);
68 m_etaBins.push_back(2.5);
69 // Declare the properties
70 declareProperty("NtupleFileName", m_ntupleFileName = "TRKVAL/Validation", "Ntuple file handle");
71 declareProperty("NtupleTreeName", m_ntupleTreeName = "Truth", "Name of the ntuple tree");
72}
73
74// destructor
76
77
78
79
80// initialize
82
83 ATH_CHECK( m_evt.initialize() );
84
85 if (m_etaBins.size()<2) {
86 ATH_MSG_ERROR ("Vector of eta bins too small");
87 return StatusCode::FAILURE;
88 }
89
90 // ---------------------------
91 // retrieve pointer to THistSvc
92 ATH_CHECK( m_histSvc.retrieve() );
93
94 // ---------------------------
95 // create tree and register it to THistSvc
96 m_nt = new TTree(TString(m_ntupleTreeName), "Track Validation Truth");
97 // NB: we must not delete the tree, this is done by THistSvc
98 std::string fullNtupleName = "/"+m_ntupleFileName+"/"+m_ntupleTreeName;
99 ATH_CHECK( m_histSvc->regTree(fullNtupleName, m_nt) );
100
101 //-----------------
102 // add items
103 // event info:
104 m_nt->Branch( "RunNumber", &m_runNumber );
105 m_nt->Branch( "EventNumber", &m_eventNumber );
106 m_nt->Branch( "truth_d0", &m_mc_d0 );
107 m_nt->Branch( "truth_z0", &m_mc_z0 );
108 m_nt->Branch( "truth_phi0", &m_mc_phi0 );
109 m_nt->Branch( "truth_theta", &m_mc_theta );
110 m_nt->Branch( "truth_qOverP", &m_mc_qOverP );
111 m_nt->Branch( "truth_qOverPt", &m_mc_qOverPt );
112 m_nt->Branch( "truth_eta", &m_mc_eta );
113 m_nt->Branch( "truth_particleID", &m_mc_particleID );
114 m_nt->Branch( "truth_barcode", &m_mc_uniqueID ); // TODO Update variable name to be consistent
115 m_nt->Branch( "truth_energy", &m_mc_energy );
116 m_nt->Branch( "truth_prod_R", &m_mc_prodR );
117 m_nt->Branch( "truth_prod_z", &m_mc_prodz );
118
119 ATH_MSG_VERBOSE ("added items to ntuple");
120
121 return StatusCode::SUCCESS;
122
123}
124
125StatusCode Trk::TruthNtupleTool::initBranches(const std::vector<const Trk::ITrackTruthClassifier*>& classifiers, bool fillJets, const std::vector<std::string>& trackCollectionNames) {
126 m_trackTruthClassifiers = classifiers;
127 m_classifications.resize(classifiers.size(), 0);
128 m_recoTrackCounts.resize(classifiers.size());
129 m_truthTrackCounts.resize(classifiers.size());
130 m_fillJets = fillJets;
131
132 if (m_fillJets)
133 m_nt->Branch("JetLinkIndex", &m_mc_jetLinkIndex );// link to MC jets
134
135 double etaBins[100];
136 for (unsigned int bin = 0; bin < m_etaBins.size(); ++bin ) {
137 etaBins[bin] = m_etaBins[bin];
138 }
139 for (unsigned int classifierIndex = 0; classifierIndex < classifiers.size(); ++classifierIndex ) {
140 if (!(classifiers[classifierIndex])) {
141 ATH_MSG_ERROR ("Got NULL pointer to truth classifier tool!");
142 return StatusCode::FAILURE;
143 }
144 std::string classifierName = classifiers[classifierIndex]->nameOfClassifier();
145 // add branch for classifier
146 ATH_MSG_INFO ("using classifier " << classifierName);
147 std::string branchName = "Class_" + classifierName;
148 std::string branchDescription = "Class_" + classifierName + "/I";
149 m_nt->Branch(branchName.c_str(), &(m_classifications[classifierIndex]), branchDescription.c_str());
150 // init statistic counters
151 for (unsigned int clIndex = 0; clIndex < classifiers[classifierIndex]->numberOfClassifiers(); clIndex++) {
152 m_truthTrackCounts[classifierIndex].push_back( new TH1D(
153 ("true"+classifiers[classifierIndex]->classificationAsString(clIndex)).c_str(),
154 ("true"+classifiers[classifierIndex]->classificationAsString(clIndex)).c_str(),
155 m_etaBins.size()-1,
156 etaBins
157 ) );
158 // TODO: do statistics for each input track collection
159 m_recoTrackCounts[classifierIndex].push_back( new TH1D(
160 ("reco"+classifiers[classifierIndex]->classificationAsString(clIndex)).c_str(),
161 ("reco"+classifiers[classifierIndex]->classificationAsString(clIndex)).c_str(),
162 m_etaBins.size()-1,
163 etaBins
164 ) );
165 }
166 }
167
168 // add branches with links to the reconstructed tracks:
169 if (!m_TrackLinkIndex.empty()) {
170 ATH_MSG_ERROR ("Track links seem to be already initialized! Do NOT call initBranches() twice!");
171 return StatusCode::FAILURE;
172 }
173 m_TrackLinkIndex.resize(trackCollectionNames.size(), nullptr);
174 m_mc_prob.resize(trackCollectionNames.size(), nullptr);
175 for (unsigned int trackColIndex = 0; trackColIndex < trackCollectionNames.size(); ++trackColIndex ) {
176 m_TrackLinkIndex[trackColIndex] = new std::vector<unsigned int>();
177 std::string branchName = "TrackLinkIndex_" + trackCollectionNames[trackColIndex];
178 m_nt->Branch(branchName.c_str(), &(m_TrackLinkIndex[trackColIndex])); // link to tracks
179 m_mc_prob[trackColIndex] = new std::vector<float>();
180 branchName = "truth_prob_" + trackCollectionNames[trackColIndex];
181 m_nt->Branch(branchName.c_str(), &(m_mc_prob[trackColIndex])); // matching probability
182 }
183 return StatusCode::SUCCESS;
184}
185
190
191 ATH_MSG_INFO ("start finalize() in " << name());
192
193 ATH_MSG_INFO ( "Efficiencies:" );
194
195 //Double_t* efficiencyValues;
196 for (unsigned int classifierIndex = 0; classifierIndex < m_trackTruthClassifiers.size(); ++classifierIndex ) {
197 for (unsigned int clIndex = 0; clIndex < m_trackTruthClassifiers[classifierIndex]->numberOfClassifiers(); clIndex++) {
198 // output:
199
200 msg() << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::left) << std::setw(15) << m_trackTruthClassifiers[classifierIndex]->classificationAsString(clIndex);
201 msg() << std::resetiosflags(std::ios::left) << std::setiosflags(std::ios::right);
202 for (int etaBin = 0; etaBin < m_recoTrackCounts[classifierIndex][clIndex]->GetNbinsX(); etaBin++) {
203 double truth = m_truthTrackCounts[classifierIndex][clIndex]->GetBinContent(etaBin+1);
204 double reco = m_recoTrackCounts[classifierIndex][clIndex]->GetBinContent(etaBin+1);
205 msg() << std::resetiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(8) << std::setw(8) << reco << "/" << std::setw(8) << truth;
206 msg() << std::setiosflags(std::ios::fixed | std::ios::showpoint | std::ios::right ) << std::setw(7)
207 << " (" << std::setprecision(4) << (truth>0. ? reco/truth : 0.) << ")";
208 }
209 // calc efficiency:
210 TGraphAsymmErrors* effPlot = new TGraphAsymmErrors(m_recoTrackCounts[classifierIndex][clIndex], m_truthTrackCounts[classifierIndex][clIndex], "");
211 // add graph to ROOT file
212 std::string graphName = "trackEff_" + m_trackTruthClassifiers[classifierIndex]->classificationAsString(clIndex);
213 effPlot->SetNameTitle(graphName.c_str(), graphName.c_str());
214 StatusCode sc = m_histSvc->regGraph("/"+m_ntupleFileName+"/"+graphName, effPlot);
215 if(sc.isFailure()){
216 ATH_MSG_ERROR ("ROOT Graph registration failed");
217 return sc;
218 }
219 msg() << "\n";
220 delete m_recoTrackCounts[classifierIndex][clIndex];
221 m_recoTrackCounts[classifierIndex][clIndex] = nullptr;
222 delete m_truthTrackCounts[classifierIndex][clIndex];
223 m_truthTrackCounts[classifierIndex][clIndex] = nullptr;
224 }
225 }
226 msg() << endmsg;
227
228 // delete track links and probs
229 for (unsigned int trackColIndex = 0; trackColIndex < m_TrackLinkIndex.size(); ++trackColIndex ) {
230 delete m_TrackLinkIndex[trackColIndex];
231 delete m_mc_prob[trackColIndex];
232 }
233 return StatusCode::SUCCESS;
234}
235
240 const std::vector< Trk::ValidationTrackTruthData >& truthData) {
241
242 ATH_MSG_DEBUG ("in writeTruthData(...) with ValTrackTruthData size = "<<truthData.size());
243 // ---------------------------------------
244 // fill event data
246 if (!evt.isValid()) {
247 ATH_MSG_WARNING ("Could not retrieve event info");
248 return StatusCode::FAILURE;
249 }
250
251 m_runNumber=evt->runNumber();
252 m_eventNumber=evt->eventNumber();
253
254 HepMC::ConstGenParticlePtr genParticle{nullptr};
255 const Trk::TrackParameters* truePerigee = nullptr;
256 for (unsigned int index = 0; index < truthData.size(); index++) {
257 genParticle = truthData[index].genParticle;
258 truePerigee = truthData[index].truthPerigee;
259 if (genParticle==nullptr || truePerigee==nullptr) {
260 if (genParticle==nullptr) ATH_MSG_WARNING ("NULL pointer to gen particle at index "<<index<<
261 ", problem with truth selection logic?");
262 else ATH_MSG_DEBUG ("NULL pointer perigee from TruthToTrack. Index is "<<index);
264 for (unsigned int trackColIndex = 0; trackColIndex < m_mc_prob.size(); ++trackColIndex ) {
265 (m_mc_prob[trackColIndex])->clear();
266 (m_TrackLinkIndex[trackColIndex])->clear();
267 }
268 //m_classifications->clear(); do not clear! vector needs to be the same
269 m_mc_particleID = 0;
270 m_mc_energy = 0.;
271
272 m_mc_d0 = 0.;
273 m_mc_z0 = 0.;
274 m_mc_phi0 = 0.;
275 m_mc_theta = 0.;
276 m_mc_qOverP = 0.;
277 m_mc_qOverPt = 0.;
278 m_mc_eta = 0.;
279 m_mc_prodR = 0.;
280 m_mc_prodz = 0.;
281 } else {
282 m_mc_uniqueID = HepMC::uniqueID(genParticle);
283 m_mc_particleID = genParticle->pdg_id();
284 m_mc_energy = genParticle->momentum().e();
285
286 m_mc_d0 = truePerigee->parameters()[Trk::d0];
287 m_mc_z0 = truePerigee->parameters()[Trk::z0];
288 m_mc_phi0 = truePerigee->parameters()[Trk::phi0];
289 m_mc_theta = truePerigee->parameters()[Trk::theta];
290 m_mc_qOverP = truePerigee->parameters()[Trk::qOverP];
291 m_mc_qOverPt = (std::sin( m_mc_theta ) != 0.) ? m_mc_qOverP / std::sin( m_mc_theta ) : 0.;
292 m_mc_eta = truePerigee->eta();
293 m_mc_prodR = fabs(genParticle->production_vertex()->position().perp());
294 m_mc_prodz = fabs(genParticle->production_vertex()->position().z());
295
296 for (unsigned int trackColIndex = 0; trackColIndex < truthData[index].truthToTrackIndices.size(); ++trackColIndex ) {
297 (*(m_TrackLinkIndex[trackColIndex])) = truthData[index].truthToTrackIndices[trackColIndex];
298 (*(m_mc_prob[trackColIndex])) = truthData[index].truthToTrackMatchingProbabilities[trackColIndex];
299 }
300 // get classification
301 m_classifications = truthData[index].classifications;
302
303 if (m_fillJets)
304 m_mc_jetLinkIndex = truthData[index].truthToJetIndex;
305
306 // do statistics:
307 for (unsigned int classIndex = 0; classIndex < m_classifications.size(); ++classIndex ) {
308 m_truthTrackCounts[classIndex][m_classifications[classIndex]]->Fill(std::fabs(m_mc_eta));
309 if (!truthData[index].truthToTrackIndices[0].empty()) {
310 // TODO: do statistics for each input track collection
311 m_recoTrackCounts[classIndex][m_classifications[classIndex]]->Fill(std::fabs(m_mc_eta));
312 }
313
314 }
315
316 }
317 m_nt->Fill();
319 }
320 ATH_MSG_DEBUG ("filled " << m_numberOfTreeEntries << " entries, returning...");
321 return StatusCode::SUCCESS;
322}
323
324
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t sc
static const Attributes_t empty
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
double eta() const
Access method for pseudorapidity - from momentum.
float m_mc_d0
d0 of MC truth particle's perigee parameters
virtual StatusCode initBranches(const std::vector< const Trk::ITrackTruthClassifier * > &classifiers, bool, const std::vector< std::string > &trackCollectionNames)
int m_eventNumber
event number to which this MC truth particle belongs
int m_mc_jetLinkIndex
link to jet this particle belongs to (if jet tree is ON)
std::vector< std::vector< TH1D * > > m_truthTrackCounts
std::vector< std::vector< TH1D * > > m_recoTrackCounts
float m_mc_prodR
Rxy of particle's production vertex.
bool m_fillJets
jO: jet filling, set from external call
std::string m_ntupleFileName
jobOption: Ntuple file and dir name
float m_mc_theta
theta of MC truth particle's perigee parameters
std::string m_ntupleTreeName
jobOption: Ntuple tree name
float m_mc_z0
z of MC truth particle's perigee parameters
TruthNtupleTool(const std::string &, const std::string &, const IInterface *)
virtual StatusCode writeTruthData(const std::vector< Trk::ValidationTrackTruthData > &truthData)
write track data to ntuple
unsigned int m_numberOfTreeEntries
float m_mc_qOverPt
q/pT of MC truth particle's perigee parameters
int m_mc_particleID
PDG ID of MC truth particle.
float m_mc_energy
MC truth particle's energy at production vertex.
virtual unsigned int getNumberOfTreeRecords() const
std::vector< double > m_etaBins
std::vector< unsigned int > m_classifications
int m_mc_uniqueID
MC truth particle's uniqueID.
std::vector< const Trk::ITrackTruthClassifier * > m_trackTruthClassifiers
the truth classifiers
std::vector< std::vector< float > * > m_mc_prob
int m_runNumber
run number to which this MC truth particle belongs
ServiceHandle< ITHistSvc > m_histSvc
StatusCode finalize()
finalize
float m_mc_eta
eta of MC truth particle's perigee parameters
TTree * m_nt
Pointer to the NTuple tree.
float m_mc_phi0
phi of MC truth particle's perigee parameters
SG::ReadHandleKey< xAOD::EventInfo > m_evt
float m_mc_prodz
z coordinate of particle's production vertex
std::vector< std::vector< unsigned int > * > m_TrackLinkIndex
float m_mc_qOverP
q/p of MC truth particle's perigee parameters
int uniqueID(const T &p)
constexpr int UNDEFINED_ID
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
@ phi0
Definition ParamDefs.h:65
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
ParametersBase< TrackParametersDim, Charged > TrackParameters
Definition index.py:1
MsgStream & msg
Definition testRead.cxx:32