26 #include <TGraphAsymmErrors.h>
40 m_histSvc(
"THistSvc",
n),
42 m_numberOfTreeEntries(0),
63 declareInterface<ITruthNtupleTool>(
this);
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);
70 declareProperty(
"NtupleFileName", m_ntupleFileName =
"TRKVAL/Validation",
"Ntuple file handle");
71 declareProperty(
"NtupleTreeName", m_ntupleTreeName =
"Truth",
"Name of the ntuple tree");
85 if (m_etaBins.size()<2) {
87 return StatusCode::FAILURE;
96 m_nt =
new TTree(TString(m_ntupleTreeName),
"Track Validation Truth");
98 std::string fullNtupleName =
"/"+m_ntupleFileName+
"/"+m_ntupleTreeName;
99 ATH_CHECK( m_histSvc->regTree(fullNtupleName, m_nt) );
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 );
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 );
121 return StatusCode::SUCCESS;
126 m_trackTruthClassifiers = classifiers;
127 m_classifications.resize(classifiers.size(), 0);
128 m_recoTrackCounts.resize(classifiers.size());
129 m_truthTrackCounts.resize(classifiers.size());
133 m_nt->Branch(
"JetLinkIndex", &m_mc_jetLinkIndex );
136 for (
unsigned int bin = 0;
bin < m_etaBins.size(); ++
bin ) {
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;
144 std::string classifierName = classifiers[classifierIndex]->nameOfClassifier();
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());
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(),
159 m_recoTrackCounts[classifierIndex].push_back(
new TH1D(
160 (
"reco"+classifiers[classifierIndex]->classificationAsString(clIndex)).c_str(),
161 (
"reco"+classifiers[classifierIndex]->classificationAsString(clIndex)).c_str(),
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;
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]));
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]));
183 return StatusCode::SUCCESS;
196 for (
unsigned int classifierIndex = 0; classifierIndex < m_trackTruthClassifiers.size(); ++classifierIndex ) {
197 for (
unsigned int clIndex = 0; clIndex < m_trackTruthClassifiers[classifierIndex]->numberOfClassifiers(); clIndex++) {
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.) <<
")";
210 TGraphAsymmErrors* effPlot =
new TGraphAsymmErrors(m_recoTrackCounts[classifierIndex][clIndex], m_truthTrackCounts[classifierIndex][clIndex],
"");
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);
220 delete m_recoTrackCounts[classifierIndex][clIndex];
221 m_recoTrackCounts[classifierIndex][clIndex] =
nullptr;
222 delete m_truthTrackCounts[classifierIndex][clIndex];
223 m_truthTrackCounts[classifierIndex][clIndex] =
nullptr;
229 for (
unsigned int trackColIndex = 0; trackColIndex < m_TrackLinkIndex.size(); ++trackColIndex ) {
230 delete m_TrackLinkIndex[trackColIndex];
231 delete m_mc_prob[trackColIndex];
233 return StatusCode::SUCCESS;
240 const std::vector< Trk::ValidationTrackTruthData >& truthData) {
242 ATH_MSG_DEBUG (
"in writeTruthData(...) with ValTrackTruthData size = "<<truthData.size());
246 if (!
evt.isValid()) {
248 return StatusCode::FAILURE;
251 m_runNumber=
evt->runNumber();
252 m_eventNumber=
evt->eventNumber();
257 genParticle = truthData[
index].genParticle;
258 truePerigee = truthData[
index].truthPerigee;
259 if (genParticle==
nullptr || truePerigee==
nullptr) {
261 ", problem with truth selection logic?");
264 for (
unsigned int trackColIndex = 0; trackColIndex < m_mc_prob.size(); ++trackColIndex ) {
265 (m_mc_prob[trackColIndex])->
clear();
266 (m_TrackLinkIndex[trackColIndex])->
clear();
283 m_mc_particleID = genParticle->pdg_id();
284 m_mc_energy = genParticle->momentum().e();
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());
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];
301 m_classifications = truthData[
index].classifications;
304 m_mc_jetLinkIndex = truthData[
index].truthToJetIndex;
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()) {
311 m_recoTrackCounts[classIndex][m_classifications[classIndex]]->Fill(std::fabs(m_mc_eta));
318 m_numberOfTreeEntries++;
320 ATH_MSG_DEBUG (
"filled " << m_numberOfTreeEntries <<
" entries, returning...");
321 return StatusCode::SUCCESS;
326 return m_numberOfTreeEntries;