16 #include "GaudiKernel/ITHistSvc.h"
30 #include <TGraphAsymmErrors.h>
45 m_numberOfTreeEntries(0),
66 declareInterface<ITruthNtupleTool>(
this);
68 m_etaBins.push_back(0.0);
69 m_etaBins.push_back(0.8);
70 m_etaBins.push_back(1.6);
71 m_etaBins.push_back(2.5);
73 declareProperty(
"NtupleFileName", m_ntupleFileName =
"TRKVAL/Validation",
"Ntuple file handle");
74 declareProperty(
"NtupleTreeName", m_ntupleTreeName =
"Truth",
"Name of the ntuple tree");
88 if (m_etaBins.size()<2) {
90 return StatusCode::FAILURE;
103 m_nt =
new TTree(TString(m_ntupleTreeName),
"Track Validation Truth");
105 std::string fullNtupleName =
"/"+m_ntupleFileName+
"/"+m_ntupleTreeName;
106 sc = tHistSvc->regTree(fullNtupleName, m_nt);
107 if (
sc.isFailure()) {
108 ATH_MSG_ERROR (
"Unable to register TTree : " << m_ntupleTreeName);
115 m_nt->Branch(
"RunNumber", &m_runNumber );
116 m_nt->Branch(
"EventNumber", &m_eventNumber );
117 m_nt->Branch(
"truth_d0", &m_mc_d0 );
118 m_nt->Branch(
"truth_z0", &m_mc_z0 );
119 m_nt->Branch(
"truth_phi0", &m_mc_phi0 );
120 m_nt->Branch(
"truth_theta", &m_mc_theta );
121 m_nt->Branch(
"truth_qOverP", &m_mc_qOverP );
122 m_nt->Branch(
"truth_qOverPt", &m_mc_qOverPt );
123 m_nt->Branch(
"truth_eta", &m_mc_eta );
124 m_nt->Branch(
"truth_particleID", &m_mc_particleID );
125 m_nt->Branch(
"truth_barcode", &m_mc_barcode );
126 m_nt->Branch(
"truth_energy", &m_mc_energy );
127 m_nt->Branch(
"truth_prod_R", &m_mc_prodR );
128 m_nt->Branch(
"truth_prod_z", &m_mc_prodz );
132 return StatusCode::SUCCESS;
137 m_trackTruthClassifiers = classifiers;
138 m_classifications.resize(classifiers.size(), 0);
139 m_recoTrackCounts.resize(classifiers.size());
140 m_truthTrackCounts.resize(classifiers.size());
144 m_nt->Branch(
"JetLinkIndex", &m_mc_jetLinkIndex );
147 for (
unsigned int bin = 0;
bin < m_etaBins.size(); ++
bin ) {
150 for (
unsigned int classifierIndex = 0; classifierIndex < classifiers.size(); ++classifierIndex ) {
151 if (!(classifiers[classifierIndex])) {
152 ATH_MSG_ERROR (
"Got NULL pointer to truth classifier tool!");
153 return StatusCode::FAILURE;
155 std::string classifierName = classifiers[classifierIndex]->nameOfClassifier();
158 std::string branchName =
"Class_" + classifierName;
159 std::string branchDescription =
"Class_" + classifierName +
"/I";
160 m_nt->Branch(branchName.c_str(), &(m_classifications[classifierIndex]), branchDescription.c_str());
162 for (
unsigned int clIndex = 0; clIndex < classifiers[classifierIndex]->numberOfClassifiers(); clIndex++) {
163 m_truthTrackCounts[classifierIndex].push_back(
new TH1D(
164 (
"true"+classifiers[classifierIndex]->classificationAsString(clIndex)).c_str(),
165 (
"true"+classifiers[classifierIndex]->classificationAsString(clIndex)).c_str(),
170 m_recoTrackCounts[classifierIndex].push_back(
new TH1D(
171 (
"reco"+classifiers[classifierIndex]->classificationAsString(clIndex)).c_str(),
172 (
"reco"+classifiers[classifierIndex]->classificationAsString(clIndex)).c_str(),
180 if (!m_TrackLinkIndex.empty()) {
181 ATH_MSG_ERROR (
"Track links seem to be already initialized! Do NOT call initBranches() twice!");
182 return StatusCode::FAILURE;
184 m_TrackLinkIndex.resize(trackCollectionNames.size(),
nullptr);
185 m_mc_prob.resize(trackCollectionNames.size(),
nullptr);
186 for (
unsigned int trackColIndex = 0; trackColIndex < trackCollectionNames.size(); ++trackColIndex ) {
187 m_TrackLinkIndex[trackColIndex] =
new std::vector<unsigned int>();
188 std::string branchName =
"TrackLinkIndex_" + trackCollectionNames[trackColIndex];
189 m_nt->Branch(branchName.c_str(), &(m_TrackLinkIndex[trackColIndex]));
190 m_mc_prob[trackColIndex] =
new std::vector<float>();
191 branchName =
"truth_prob_" + trackCollectionNames[trackColIndex];
192 m_nt->Branch(branchName.c_str(), &(m_mc_prob[trackColIndex]));
194 return StatusCode::SUCCESS;
207 if (
sc.isFailure()) {
215 for (
unsigned int classifierIndex = 0; classifierIndex < m_trackTruthClassifiers.size(); ++classifierIndex ) {
216 for (
unsigned int clIndex = 0; clIndex < m_trackTruthClassifiers[classifierIndex]->numberOfClassifiers(); clIndex++) {
219 msg() << std::resetiosflags(std::ios::right) << std::setiosflags(std::ios::left) << std::setw(15) << m_trackTruthClassifiers[classifierIndex]->classificationAsString(clIndex);
220 msg() << std::resetiosflags(std::ios::left) << std::setiosflags(std::ios::right);
221 for (
int etaBin = 0;
etaBin < m_recoTrackCounts[classifierIndex][clIndex]->GetNbinsX();
etaBin++) {
222 double truth = m_truthTrackCounts[classifierIndex][clIndex]->GetBinContent(
etaBin+1);
223 double reco = m_recoTrackCounts[classifierIndex][clIndex]->GetBinContent(
etaBin+1);
224 msg() << std::resetiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(8) << std::setw(8) <<
reco <<
"/" << std::setw(8) << truth;
225 msg() << std::setiosflags(std::ios::fixed | std::ios::showpoint | std::ios::right ) << std::setw(7)
226 <<
" (" << std::setprecision(4) << (truth>0. ?
reco/truth : 0.) <<
")";
229 TGraphAsymmErrors* effPlot =
new TGraphAsymmErrors(m_recoTrackCounts[classifierIndex][clIndex], m_truthTrackCounts[classifierIndex][clIndex],
"");
231 std::string graphName =
"trackEff_" + m_trackTruthClassifiers[classifierIndex]->classificationAsString(clIndex);
232 effPlot->SetNameTitle(graphName.c_str(), graphName.c_str());
233 StatusCode sc = tHistSvc->regGraph(
"/"+m_ntupleFileName+
"/"+graphName, effPlot);
239 delete m_recoTrackCounts[classifierIndex][clIndex];
240 m_recoTrackCounts[classifierIndex][clIndex] =
nullptr;
241 delete m_truthTrackCounts[classifierIndex][clIndex];
242 m_truthTrackCounts[classifierIndex][clIndex] =
nullptr;
248 for (
unsigned int trackColIndex = 0; trackColIndex < m_TrackLinkIndex.size(); ++trackColIndex ) {
249 delete m_TrackLinkIndex[trackColIndex];
250 delete m_mc_prob[trackColIndex];
252 return StatusCode::SUCCESS;
259 const std::vector< Trk::ValidationTrackTruthData >& truthData) {
261 ATH_MSG_DEBUG (
"in writeTruthData(...) with ValTrackTruthData size = "<<truthData.size());
265 if (!
evt.isValid()) {
267 return StatusCode::FAILURE;
270 m_runNumber=
evt->runNumber();
271 m_eventNumber=
evt->eventNumber();
276 genParticle = truthData[
index].genParticle;
277 truePerigee = truthData[
index].truthPerigee;
278 if (genParticle==
nullptr || truePerigee==
nullptr) {
280 ", problem with truth selection logic?");
283 for (
unsigned int trackColIndex = 0; trackColIndex < m_mc_prob.size(); ++trackColIndex ) {
284 (m_mc_prob[trackColIndex])->
clear();
285 (m_TrackLinkIndex[trackColIndex])->
clear();
302 m_mc_particleID = genParticle->pdg_id();
303 m_mc_energy = genParticle->momentum().e();
305 m_mc_d0 = truePerigee->parameters()[
Trk::d0];
306 m_mc_z0 = truePerigee->parameters()[
Trk::z0];
307 m_mc_phi0 = truePerigee->parameters()[
Trk::phi0];
308 m_mc_theta = truePerigee->parameters()[
Trk::theta];
309 m_mc_qOverP = truePerigee->parameters()[
Trk::qOverP];
310 m_mc_qOverPt = (
std::sin( m_mc_theta ) != 0.) ? m_mc_qOverP /
std::sin( m_mc_theta ) : 0.;
311 m_mc_eta = truePerigee->
eta();
312 m_mc_prodR = fabs(genParticle->production_vertex()->position().perp());
313 m_mc_prodz = fabs(genParticle->production_vertex()->position().z());
315 for (
unsigned int trackColIndex = 0; trackColIndex < truthData[
index].truthToTrackIndices.size(); ++trackColIndex ) {
316 (*(m_TrackLinkIndex[trackColIndex])) = truthData[
index].truthToTrackIndices[trackColIndex];
317 (*(m_mc_prob[trackColIndex])) = truthData[
index].truthToTrackMatchingProbabilities[trackColIndex];
320 m_classifications = truthData[
index].classifications;
323 m_mc_jetLinkIndex = truthData[
index].truthToJetIndex;
326 for (
unsigned int classIndex = 0; classIndex < m_classifications.size(); ++classIndex ) {
327 m_truthTrackCounts[classIndex][m_classifications[classIndex]]->Fill(std::fabs(m_mc_eta));
328 if (!truthData[
index].truthToTrackIndices[0].
empty()) {
330 m_recoTrackCounts[classIndex][m_classifications[classIndex]]->Fill(std::fabs(m_mc_eta));
337 m_numberOfTreeEntries++;
339 ATH_MSG_DEBUG (
"filled " << m_numberOfTreeEntries <<
" entries, returning...");
340 return StatusCode::SUCCESS;
345 return m_numberOfTreeEntries;