CbmRoot
Loading...
Searching...
No Matches
CbmKFParticleFinderQa.cxx
Go to the documentation of this file.
1/* Copyright (C) 2014-2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Maksym Zyzak, Volker Friese [committer] */
4
5//-----------------------------------------------------------
6//-----------------------------------------------------------
7
8// Cbm Headers ----------------------
10
11#include "CbmMCDataArray.h"
12#include "CbmMCDataManager.h"
13#include "CbmMCEventList.h"
14#include "CbmMCTrack.h"
15#include "CbmTrack.h"
16#include "CbmTrackMatchNew.h"
17#include "FairRunAna.h"
18
19//KF Particle headers
20#include "KFMCTrack.h"
21#include "KFParticleMatch.h"
22#include "KFParticleTopoReconstructor.h"
23#include "KFTopoPerformance.h"
24
25//ROOT headers
26#include "TCanvas.h"
27#include "TClonesArray.h"
28#include "TDatabasePDG.h"
29#include "TF1.h"
30#include "TFile.h"
31#include "TH1F.h"
32#include "TMath.h"
33#include "TObject.h"
34#include "TSystem.h"
35
36//c++ and std headers
37#include <cmath>
38#include <iomanip>
39#include <iostream>
40#include <vector>
41using std::vector;
42
43CbmKFParticleFinderQa::CbmKFParticleFinderQa(const char* name, Int_t iVerbose, const KFParticleTopoReconstructor* tr,
44 TString outFileName)
45 : FairTask(name, iVerbose)
46 , fOutFileName(outFileName)
47{
48 for (Int_t i = 0; i < 5; i++) {
49 fTime[i] = 0;
50 }
51
52 fTopoPerformance = new KFTopoPerformance;
53 fTopoPerformance->SetTopoReconstructor(tr);
54
55 TFile* curFile = gFile;
56 TDirectory* curDirectory = gDirectory;
57
58 if (!(fOutFileName == "")) {
59 fOutFile = new TFile(fOutFileName.Data(), "RECREATE");
60 }
61 else {
62 fOutFile = gFile;
63 }
64 fTopoPerformance->CreateHistos("KFTopoReconstructor", fOutFile, tr->GetKFParticleFinder()->GetReconstructionList());
65
66 gFile = curFile;
67 gDirectory = curDirectory;
68}
69
71{
72 if (fTopoPerformance) {
73 delete fTopoPerformance;
74 }
75
76 if (fSaveParticles) {
77 fRecParticles->Delete();
78 }
79 if (fSaveMCParticles) {
80 fMCParticles->Delete();
81 fMatchParticles->Delete();
82 }
83}
84
86{
87 std::string prefix = std::string(GetName()) + "::Init: ";
88
89 fIsInitialized = false;
90 fIsMcData = false;
91
92 //Get ROOT Manager
93 FairRootManager* ioman = FairRootManager::Instance();
94
95 if (ioman == nullptr) {
96 LOG(error) << prefix << "FairRootManager not instantiated!";
97 return kERROR;
98 }
99
100 fRecoEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("CbmEvent"));
101 if (nullptr == fRecoEvents) {
102 LOG(error) << prefix << "No event array!";
103 return kERROR;
104 }
105
106 // MC Tracks
107 fIsMcData = ioman->CheckBranch("MCDataManager");
108 if (!fIsMcData) {
109 LOG(warning) << prefix << "MC Data Manager not found, running w/o MC!";
110 }
111 else {
112 CbmMCDataManager* mcManager = (CbmMCDataManager*) ioman->GetObject("MCDataManager");
113 if (mcManager == nullptr) {
114 LOG(error) << prefix << "MC Data Manager not found!";
115 return kERROR;
116 }
117
118 fMCTrackArray = mcManager->InitBranch("MCTrack");
119 if (fMCTrackArray == nullptr) {
120 LOG(error) << prefix << "MC Track array not found!";
121 return kERROR;
122 }
123
124 fMcEventList = (CbmMCEventList*) ioman->GetObject("MCEventList.");
125 if (fMcEventList == nullptr) {
126 LOG(error) << prefix << "MC Event List not found!";
127 return kERROR;
128 }
129
130 fTrackMatchArray = (TClonesArray*) ioman->GetObject("StsTrackMatch");
131 if (fTrackMatchArray == nullptr) {
132 LOG(error) << prefix << " Sts Track Match array not found!";
133 return kERROR;
134 }
135 }
136
137 if (fSaveParticles) {
138 // create and register TClonesArray with output reco particles
139 fRecParticles = new TClonesArray("KFParticle", 100);
140 ioman->Register("RecoParticles", "KFParticle", fRecParticles, IsOutputBranchPersistent("RecoParticles"));
141 }
142
143 if (fSaveMCParticles) {
144 // create and register TClonesArray with output MC particles
145 fMCParticles = new TClonesArray("KFMCParticle", 100);
146 ioman->Register("KFMCParticles", "KFParticle", fMCParticles, IsOutputBranchPersistent("KFMCParticles"));
147
148 // create and register TClonesArray with matching between reco and MC particles
149 fMatchParticles = new TClonesArray("KFParticleMatch", 100);
150 ioman->Register("KFParticleMatch", "KFParticle", fMatchParticles, IsOutputBranchPersistent("KFParticleMatch"));
151 }
152
153 fIsInitialized = true;
154
155 return kSUCCESS;
156}
157
158void CbmKFParticleFinderQa::Exec(Option_t* /*opt*/)
159{
160 std::string prefix = std::string(GetName()) + "::Exec: ";
161
162 if (!fIsInitialized) {
163 LOG(warning) << prefix << "The task can not run! Some data is missing.";
164 return;
165 }
166
168 LOG(error) << GetName() << " SuperEventAnalysis option currently doesn't work";
169 return;
170 }
171
172 if (fSaveParticles) {
173 fRecParticles->Delete();
174 }
175
176 if (fSaveMCParticles) {
177 fMCParticles->Delete();
178 fMatchParticles->Delete();
179 }
180
181 int maxTrackId = -1;
182 for (unsigned int iP = 0; iP < fTopoPerformance->GetTopoReconstructor()->GetParticles().size(); iP++) {
183 auto& p = fTopoPerformance->GetTopoReconstructor()->GetParticles()[iP];
184 if (p.NDaughters() != 1) continue; //use only tracks, not short lived particles
185 maxTrackId = std::max(maxTrackId, p.DaughterIds()[0]);
186 }
187
188 if (fIsMcData) {
189
190 if (!fMCTrackArray) {
191 LOG(fatal) << prefix << "MC track array not found!";
192 }
193
194 if (!fMcEventList) {
195 LOG(fatal) << prefix << "MC event list not found!";
196 }
197
198 int nMCEvents = fMcEventList->GetNofEvents();
199
200 vector<KFMCTrack> mcTracks; // mc tracks for the entire time slice
201
202 vector<int> mcToKFmcMap[nMCEvents]; // map event mc tracks to the mcTracks array
203
204 for (int iMCEvent = 0, mcIndexOffset = 0, nMCTracks = 0; iMCEvent < nMCEvents;
205 iMCEvent++, mcIndexOffset += nMCTracks) {
206
207 CbmLink mcEventLink = fMcEventList->GetEventLinkByIndex(iMCEvent);
208 nMCTracks = fMCTrackArray->Size(mcEventLink);
209 mcToKFmcMap[iMCEvent].resize(nMCTracks, -1);
210
211 for (Int_t iMC = 0; iMC < nMCTracks; iMC++) {
212
213 CbmLink mcTrackLink = mcEventLink;
214 mcTrackLink.SetIndex(iMC);
215 CbmMCTrack* cbmMCTrack = dynamic_cast<CbmMCTrack*>(fMCTrackArray->Get(mcTrackLink));
216 assert(cbmMCTrack);
217
218 KFMCTrack kfMCTrack;
219
220 kfMCTrack.SetX(cbmMCTrack->GetStartX());
221 kfMCTrack.SetY(cbmMCTrack->GetStartY());
222 kfMCTrack.SetZ(cbmMCTrack->GetStartZ());
223 kfMCTrack.SetPx(cbmMCTrack->GetPx());
224 kfMCTrack.SetPy(cbmMCTrack->GetPy());
225 kfMCTrack.SetPz(cbmMCTrack->GetPz());
226
227 Int_t pdg = cbmMCTrack->GetPdgCode();
228 Double_t q = 1;
229 if (pdg < 9999999 && ((TParticlePDG*) TDatabasePDG::Instance()->GetParticle(pdg))) {
230 q = TDatabasePDG::Instance()->GetParticle(pdg)->Charge() / 3.0;
231 }
232 else if (pdg == 1000010020) {
233 q = 1;
234 }
235 else if (pdg == -1000010020) {
236 q = -1;
237 }
238 else if (pdg == 1000010030) {
239 q = 1;
240 }
241 else if (pdg == -1000010030) {
242 q = -1;
243 }
244 else if (pdg == 1000020030) {
245 q = 2;
246 }
247 else if (pdg == -1000020030) {
248 q = -2;
249 }
250 else if (pdg == 1000020040) {
251 q = 2;
252 }
253 else if (pdg == -1000020040) {
254 q = -2;
255 }
256 else {
257 q = 0;
258 }
259
260 Double_t p = cbmMCTrack->GetP();
261
262 if (cbmMCTrack->GetMotherId() >= 0) {
263 kfMCTrack.SetMotherId(cbmMCTrack->GetMotherId() + mcIndexOffset);
264 }
265 else {
266 kfMCTrack.SetMotherId(-iMCEvent - 1);
267 }
268 kfMCTrack.SetQP(q / p);
269 kfMCTrack.SetPDG(pdg);
270 kfMCTrack.SetNMCPoints(0);
271
272 mcToKFmcMap[iMCEvent][iMC] = mcTracks.size();
273
274 mcTracks.push_back(kfMCTrack);
275 } // mc track loop
276
277 } // event loop
278
279
280 Int_t ntrackMatches = fTrackMatchArray->GetEntriesFast();
281
282 if (ntrackMatches < maxTrackId + 1) {
283 LOG(fatal) << prefix << "Number of track matches " << ntrackMatches << " is lower than the max track index "
284 << maxTrackId << " + 1, something goes wrong!";
285 return;
286 }
287
288 vector<int> trackMatch(ntrackMatches, -1);
289
290 for (int iTr = 0; iTr < ntrackMatches; iTr++) {
291
292 CbmTrackMatchNew* stsTrackMatch = dynamic_cast<CbmTrackMatchNew*>(fTrackMatchArray->At(iTr));
293
294 if (stsTrackMatch->GetNofLinks() == 0) {
295 continue;
296 }
297 Float_t bestWeight = 0.f;
298 Float_t totalWeight = 0.f;
299 Int_t mcTrackId = -1;
300 CbmLink link;
301
302 for (int iLink = 0; iLink < stsTrackMatch->GetNofLinks(); iLink++) {
303 totalWeight += stsTrackMatch->GetLink(iLink).GetWeight();
304 if (stsTrackMatch->GetLink(iLink).GetWeight() > bestWeight) {
305 bestWeight = stsTrackMatch->GetLink(iLink).GetWeight();
306 int iMCTrack = stsTrackMatch->GetLink(iLink).GetIndex();
307 link = stsTrackMatch->GetLink(iLink);
308 int eventIndex = fMcEventList->GetEventIndex(link);
309 if (eventIndex >= 0) {
310 mcTrackId = mcToKFmcMap[eventIndex][iMCTrack];
311 }
312 }
313 }
314
315 if (mcTrackId < 0) {
316 continue;
317 }
318
319 if (bestWeight / totalWeight < 0.7) {
320 continue;
321 }
322 // if(mcTrackId >= nMCTracks || mcTrackId < 0)
323 // {
324 // std::cout << "Sts Matching is wrong! StsTackId = " << mcTrackId << " N mc tracks = " << nMCTracks << std::endl;
325 // continue;
326 // }
327
328 if (TMath::Abs(mcTracks[mcTrackId].PDG()) > 4000
329 && !(TMath::Abs(mcTracks[mcTrackId].PDG()) == 1000010020
330 || TMath::Abs(mcTracks[mcTrackId].PDG()) == 1000010030
331 || TMath::Abs(mcTracks[mcTrackId].PDG()) == 1000020030
332 || TMath::Abs(mcTracks[mcTrackId].PDG()) == 1000020040)) {
333 continue;
334 }
335
336 mcTracks[mcTrackId].SetReconstructed();
337 trackMatch[iTr] = mcTrackId;
338 } // track match loop
339
340 fTopoPerformance->SetMCTracks(mcTracks);
341 fTopoPerformance->SetTrackMatch(trackMatch);
342 }
343 else {
344 fTopoPerformance->DoNotStoreMCHistograms();
345
346 vector<int> trackMatch(maxTrackId + 1, -1);
347 fTopoPerformance->SetTrackMatch(trackMatch);
348 }
349
350 fTopoPerformance->CheckMCTracks();
351 fTopoPerformance->MatchTracks();
352 fTopoPerformance->FillHistos();
353
354 fNTimeSlices++;
355 fTime[4] += fTopoPerformance->GetTopoReconstructor()->Time();
356 for (int iT = 0; iT < 4; iT++) {
357 fTime[iT] += fTopoPerformance->GetTopoReconstructor()->StatTime(iT);
358 }
359
360 if (fNTimeSlices % fPrintFrequency == 0) {
361 LOG(info) << prefix << "Topo reconstruction time"
362 << " Real = " << std::setw(10) << fTime[4] / fNTimeSlices * 1.e3 << " ms";
363 LOG(info) << prefix << " Init " << fTime[0] / fNTimeSlices * 1.e3 << " ms";
364 LOG(info) << prefix << " PV Finder " << fTime[1] / fNTimeSlices * 1.e3 << " ms";
365 LOG(info) << prefix << " Sort Tracks " << fTime[2] / fNTimeSlices * 1.e3 << " ms";
366 LOG(info) << prefix << " KF Particle Finder " << fTime[3] / fNTimeSlices * 1.e3 << " ms";
367 }
368
369 // save particles to a ROOT file
370 if (fSaveParticles) {
371 for (unsigned int iP = 0; iP < fTopoPerformance->GetTopoReconstructor()->GetParticles().size(); iP++) {
372 new ((*fRecParticles)[iP]) KFParticle(fTopoPerformance->GetTopoReconstructor()->GetParticles()[iP]);
373 }
374 }
375
376 if (fSaveMCParticles) {
377 for (unsigned int iP = 0; iP < fTopoPerformance->GetTopoReconstructor()->GetParticles().size(); iP++) {
378 new ((*fMatchParticles)[iP]) KFParticleMatch();
380
381 Short_t matchType = 0;
382 int iMCPart = -1;
383 if (!(fTopoPerformance->ParticlesMatch()[iP].IsMatchedWithPdg())) //background
384 {
385 if (fTopoPerformance->ParticlesMatch()[iP].IsMatched()) {
386 iMCPart = fTopoPerformance->ParticlesMatch()[iP].GetBestMatchWithPdg();
387 matchType = 1;
388 }
389 }
390 else {
391 iMCPart = fTopoPerformance->ParticlesMatch()[iP].GetBestMatchWithPdg();
392 matchType = 2;
393 }
394
395 p->SetMatch(iMCPart);
396 p->SetMatchType(matchType);
397 }
398
399 for (unsigned int iP = 0; iP < fTopoPerformance->MCParticles().size(); iP++) {
400 new ((*fMCParticles)[iP]) KFMCParticle(fTopoPerformance->MCParticles()[iP]);
401 }
402 }
403}
404
406{
407 std::string prefix = std::string(GetName()) + "::Finish: ";
408
410 fTopoPerformance->SetPrintEffFrequency(1);
411
412 vector<KFMCTrack> mcTracks(0);
413 Int_t ntrackMatches = fTopoPerformance->GetTopoReconstructor()->GetParticles().size();
414 vector<int> trackMatch(ntrackMatches, -1);
415
416 fTopoPerformance->SetMCTracks(mcTracks);
417 fTopoPerformance->SetTrackMatch(trackMatch);
418 fTopoPerformance->CheckMCTracks();
419 fTopoPerformance->MatchTracks();
420 fTopoPerformance->FillHistos();
421
422 fTime[4] += fTopoPerformance->GetTopoReconstructor()->Time();
423 for (int iT = 0; iT < 4; iT++) {
424 fTime[iT] += fTopoPerformance->GetTopoReconstructor()->StatTime(iT);
425 }
426
427 LOG(info) << prefix << "Topo reconstruction time"
428 << " Real = " << std::setw(10) << fTime[4] * 1.e3 << " ms";
429 LOG(info) << prefix << " Init " << fTime[0] * 1.e3 << " ms";
430 LOG(info) << prefix << " PV Finder " << fTime[1] * 1.e3 << " ms";
431 LOG(info) << prefix << " Sort Tracks " << fTime[2] * 1.e3 << " ms";
432 LOG(info) << prefix << " KF Particle Finder " << fTime[3] * 1.e3 << " ms";
433 }
434
435 TDirectory* curr = gDirectory;
436 TFile* currentFile = gFile;
437 // Open output file and write histograms
438
439 fOutFile->cd();
440 WriteHistosCurFile(fTopoPerformance->GetHistosDirectory());
441
442 if (fCheckDecayQA && fDecayToAnalyse > -1) {
443 if (fDecayToAnalyse < 0) {
444 LOG(fatal) << prefix << "Decay to be analysed is not specified!";
445 }
446 else {
447 CheckDecayQA();
448 }
449 }
450
451 if (!(fOutFileName == "")) {
452 fOutFile->Close();
453 fOutFile->Delete();
454 }
455 gFile = currentFile;
456 gDirectory = curr;
457
458 std::fstream eff(fEfffileName.Data(), std::fstream::out);
459 eff << fTopoPerformance->fParteff;
460 eff.close();
461}
462
464{
465 if (!obj->IsFolder()) {
466 obj->Write();
467 }
468 else {
469 TDirectory* cur = gDirectory;
470 TFile* currentFile = gFile;
471
472 TDirectory* sub = cur->GetDirectory(obj->GetName());
473 sub->cd();
474 TList* listSub = (static_cast<TDirectory*>(obj))->GetList();
475 TIter it(listSub);
476 while (TObject* obj1 = it())
477 WriteHistosCurFile(obj1);
478 cur->cd();
479 gFile = currentFile;
480 gDirectory = cur;
481 }
482}
483
485{
486 fTopoPerformance->SetPrintEffFrequency(n);
487 fPrintFrequency = n;
488}
489
490void CbmKFParticleFinderQa::FitDecayQAHistograms(float sigma[14], const bool saveReferenceResults) const
491{
492 static const int nParameters = 7;
493 TString parameterName[nParameters] = {"X", "Y", "Z", "Px", "Py", "Pz", "E"};
494
495 TH1F* histogram[nParameters * 2];
496 TF1* fit[nParameters * 2];
497
498 for (int iParameter = 0; iParameter < nParameters; iParameter++) {
499 TString cloneResidualName = TString("hResidual") + parameterName[iParameter];
500 histogram[iParameter] =
501 (TH1F*) (fTopoPerformance->GetDecayResidual(fDecayToAnalyse, iParameter)->Clone(cloneResidualName.Data()));
502 fit[iParameter] =
503 new TF1(TString("fitResidual") + parameterName[iParameter], "gaus", histogram[iParameter]->GetXaxis()->GetXmin(),
504 histogram[iParameter]->GetXaxis()->GetXmax());
505 fit[iParameter]->SetLineColor(kRed);
506 histogram[iParameter]->Fit(TString("fitResidual") + parameterName[iParameter], "QN", "",
507 histogram[iParameter]->GetXaxis()->GetXmin(),
508 histogram[iParameter]->GetXaxis()->GetXmax());
509 sigma[iParameter] = fit[iParameter]->GetParameter(2);
510
511 TString clonePullName = TString("hPull") + parameterName[iParameter];
512 histogram[iParameter + nParameters] =
513 (TH1F*) (fTopoPerformance->GetDecayPull(fDecayToAnalyse, iParameter)->Clone(clonePullName.Data()));
514 fit[iParameter + nParameters] = new TF1(TString("fitPull") + parameterName[iParameter], "gaus",
515 histogram[iParameter + nParameters]->GetXaxis()->GetXmin(),
516 histogram[iParameter + nParameters]->GetXaxis()->GetXmax());
517 fit[iParameter + nParameters]->SetLineColor(kRed);
518 histogram[iParameter + nParameters]->Fit(TString("fitPull") + parameterName[iParameter], "QN", "",
519 histogram[iParameter + nParameters]->GetXaxis()->GetXmin(),
520 histogram[iParameter + nParameters]->GetXaxis()->GetXmax());
521 sigma[iParameter + nParameters] = fit[iParameter + nParameters]->GetParameter(2);
522 }
523
524 if (saveReferenceResults) {
525 TCanvas fitCanvas("fitCanvas", "fitCanvas", 1600, 800);
526 fitCanvas.Divide(4, 4);
527
528 int padMap[nParameters * 2] = {1, 2, 3, 9, 10, 11, 12, 5, 6, 7, 13, 14, 15, 16};
529 for (int iHisto = 0; iHisto < nParameters * 2; iHisto++) {
530 fitCanvas.cd(padMap[iHisto]);
531 histogram[iHisto]->Draw();
532 fit[iHisto]->Draw("same");
533 }
534
535 TString canvasFile = TString("FitQA_") + fTopoPerformance->fParteff.partName[fDecayToAnalyse] + TString(".pdf");
536 fitCanvas.SaveAs(canvasFile.Data());
537 }
538
539 for (int iHisto = 0; iHisto < nParameters * 2; iHisto++) {
540 if (fit[iHisto]) {
541 delete fit[iHisto];
542 }
543 }
544}
545
547{
548 float sigma[14];
549 FitDecayQAHistograms(sigma, true);
550
551 TString referenceFileName =
552 fReferenceResults + TString("/qa_") + fTopoPerformance->fParteff.partName[fDecayToAnalyse] + TString(".root");
553 TString qaFileName = TString("qa_") + fTopoPerformance->fParteff.partName[fDecayToAnalyse] + TString(".root");
554
555 int iQAFile = 2;
556 while (!gSystem->AccessPathName(qaFileName)) {
557 qaFileName = TString("qa_") + fTopoPerformance->fParteff.partName[fDecayToAnalyse];
558 qaFileName += iQAFile;
559 qaFileName += TString(".root");
560 iQAFile++;
561 }
562
563 TFile* curFile = gFile;
564 TDirectory* curDirectory = gDirectory;
565 TFile* qaFile = new TFile(qaFileName.Data(), "RECREATE");
566
567 TString qaHistoName = TString("qa_") + fTopoPerformance->fParteff.partName[fDecayToAnalyse];
568 TH1F* qaHisto = new TH1F(qaHistoName.Data(), qaHistoName.Data(), 16, 0, 16);
569
570 TString binLabel[16] = {"#sigma_{x}", "#sigma_{y}", "#sigma_{z}", "#sigma_{p_{x}}",
571 "#sigma_{p_{y}}", "#sigma_{p_{z}}", "#sigma_{E}", "P_{x}",
572 "P_{y}", "P_{z}", "P_{p_{x}}", "P_{p_{y}}",
573 "P_{p_{z}}", "P_{E}", "#varepsilon_{4#pi}", "#varepsilon_{KFP}"};
574 for (int iBin = 0; iBin < 16; iBin++) {
575 qaHisto->GetXaxis()->SetBinLabel(iBin + 1, binLabel[iBin].Data());
576 }
577
578 for (int iSigma = 0; iSigma < 14; iSigma++) {
579 qaHisto->SetBinContent(iSigma + 1, sigma[iSigma]);
580 }
581
582 qaHisto->SetBinContent(15, fTopoPerformance->fParteff.GetTotal4piEfficiency(fDecayToAnalyse));
583 qaHisto->SetBinContent(16, fTopoPerformance->fParteff.GetTotalKFPEfficiency(fDecayToAnalyse));
584
585 qaHisto->Write();
586
587 //compare with the reference results
588 TFile* referenceFile = new TFile(referenceFileName.Data(), "READ");
589 if (referenceFile->IsOpen()) {
590 TH1F* referenceHisto = referenceFile->Get<TH1F>(qaHistoName);
591 if (referenceHisto) {
592 fTestOk = true;
593 for (int iBin = 1; iBin <= 7; iBin++) {
594 fTestOk &=
595 fabs(referenceHisto->GetBinContent(iBin) - qaHisto->GetBinContent(iBin)) / referenceHisto->GetBinContent(iBin)
596 < 0.25;
597 }
598 for (int iBin = 8; iBin <= 14; iBin++) {
599 fTestOk &=
600 fabs(referenceHisto->GetBinContent(iBin) - qaHisto->GetBinContent(iBin)) / referenceHisto->GetBinContent(iBin)
601 < 0.25;
602 }
603 for (int iBin = 15; iBin <= 16; iBin++) {
604 fTestOk &=
605 fabs(referenceHisto->GetBinContent(iBin) - qaHisto->GetBinContent(iBin)) / referenceHisto->GetBinContent(iBin)
606 < 0.1;
607 }
608 }
609 referenceFile->Close();
610 referenceFile->Delete();
611 }
612 else {
613 LOG(error) << "Could not open file " << referenceFileName << " with reference histograms";
614 }
615
616 if (qaFile) {
617 qaFile->Close();
618 qaFile->Delete();
619 }
620
621 gFile = curFile;
622 gDirectory = curDirectory;
623}
624
Int_t nMCTracks
ClassImp(CbmKFParticleFinderQa)
static vector< vector< QAMCTrack > > mcTracks
static constexpr size_t size()
Definition KfSimdPseudo.h:2
void WriteHistosCurFile(TObject *obj)
CbmKFParticleFinderQa(const char *name="CbmKFParticleFinderQa", Int_t iVerbose=0, const KFParticleTopoReconstructor *tr=nullptr, TString outFileName="CbmKFParticleFinderQa.root")
virtual void Exec(Option_t *opt)
CbmMCDataArray * fMCTrackArray
Array of CbmEvent objects.
KFTopoPerformance * fTopoPerformance
void FitDecayQAHistograms(float sigma[14], const bool saveReferenceResults=false) const
TObject * Get(const CbmLink *lnk)
Int_t Size(Int_t fileNumber, Int_t eventNumber)
Task class creating and managing CbmMCDataArray objects.
CbmMCDataObject * GetObject(const char *name)
CbmMCDataArray * InitBranch(const char *name)
Container class for MC events with number, file and start time.
CbmLink GetEventLinkByIndex(uint32_t index)
Event file and event indices as CbmLink.
Int_t GetEventIndex(UInt_t event, UInt_t file)
Event index.
std::size_t GetNofEvents() const
Number of events in the list @value Number of events.
double GetPz() const
Definition CbmMCTrack.h:72
double GetP() const
Definition CbmMCTrack.h:98
double GetPx() const
Definition CbmMCTrack.h:70
double GetStartZ() const
Definition CbmMCTrack.h:75
int32_t GetMotherId() const
Definition CbmMCTrack.h:69
double GetStartX() const
Definition CbmMCTrack.h:73
int32_t GetPdgCode() const
Definition CbmMCTrack.h:68
double GetStartY() const
Definition CbmMCTrack.h:74
double GetPy() const
Definition CbmMCTrack.h:71
const CbmLink & GetLink(int32_t i) const
Definition CbmMatch.h:39
int32_t GetNofLinks() const
Definition CbmMatch.h:42
void SetMatchType(Short_t i)
void SetMatch(Int_t i)