10#include "CbmStsPoint.h"
11#include "CbmStsTrack.h"
12#include "CbmTrackMatch.h"
13#include "CbmGeoStsPar.h"
16#include "FairGeoNode.h"
17#include "FairGeoPassivePar.h"
18#include "FairGeoVector.h"
19#include "CbmMCTrack.h"
20#include "FairRootManager.h"
21#include "FairRunAna.h"
22#include "FairRuntimeDb.h"
26#include "TClonesArray.h"
39 : FairTask(
"STSFindTracksQA", iVerbose),
54 fhMomAccAll(new TH1F()),
55 fhMomRecAll(new TH1F()),
56 fhMomEffAll(new TH1F()),
57 fhMomAccPrim(new TH1F()),
58 fhMomRecPrim(new TH1F()),
59 fhMomEffPrim(new TH1F()),
60 fhMomAccSec(new TH1F()),
61 fhMomRecSec(new TH1F()),
62 fhMomEffSec(new TH1F()),
63 fhNpAccAll(new TH1F()),
64 fhNpRecAll(new TH1F()),
65 fhNpEffAll(new TH1F()),
66 fhNpAccPrim(new TH1F()),
67 fhNpRecPrim(new TH1F()),
68 fhNpEffPrim(new TH1F()),
69 fhNpAccSec(new TH1F()),
70 fhNpRecSec(new TH1F()),
71 fhNpEffSec(new TH1F()),
72 fhZAccSec(new TH1F()),
73 fhZRecSec(new TH1F()),
74 fhZEffSec(new TH1F()),
75 fhNhClones(new TH1F()),
76 fhNhGhosts(new TH1F()),
77 fHistoList(new TList()),
101 : FairTask(
"STSFindTracksQA", iVerbose),
112 fTargetPos(0.,0.,0.),
116 fhMomAccAll(new TH1F()),
117 fhMomRecAll(new TH1F()),
118 fhMomEffAll(new TH1F()),
119 fhMomAccPrim(new TH1F()),
120 fhMomRecPrim(new TH1F()),
121 fhMomEffPrim(new TH1F()),
122 fhMomAccSec(new TH1F()),
123 fhMomRecSec(new TH1F()),
124 fhMomEffSec(new TH1F()),
125 fhNpAccAll(new TH1F()),
126 fhNpRecAll(new TH1F()),
127 fhNpEffAll(new TH1F()),
128 fhNpAccPrim(new TH1F()),
129 fhNpRecPrim(new TH1F()),
130 fhNpEffPrim(new TH1F()),
131 fhNpAccSec(new TH1F()),
132 fhNpRecSec(new TH1F()),
133 fhNpEffSec(new TH1F()),
134 fhZAccSec(new TH1F()),
135 fhZRecSec(new TH1F()),
136 fhZEffSec(new TH1F()),
137 fhNhClones(new TH1F()),
138 fhNhGhosts(new TH1F()),
139 fHistoList(new TList()),
162 fHistoList->Delete();
173 FairRunAna*
run = FairRunAna::Instance();
175 cout <<
"-E- " << GetName() <<
"::SetParContainers: No FairRunAna!"
181 FairRuntimeDb* runDb =
run->GetRuntimeDb();
183 cout <<
"-E- " << GetName() <<
"::SetParContainers: No runtime database!"
191 cout <<
"-E- " << GetName() <<
"::SetParContainers: "
192 <<
"No passive geometry parameters!" << endl;
197 fStsGeo = (
CbmGeoStsPar*) runDb->getContainer(
"CbmGeoStsPar");
199 cout <<
"-E- " << GetName() <<
"::SetParContainers: "
200 <<
"No STS geometry parameters!" << endl;
212 cout <<
"==========================================================="
214 cout << GetName() <<
": Initialising..." << endl;
217 FairRootManager* ioman = FairRootManager::Instance();
219 cout <<
"-E- " << GetName() <<
"::Init: "
220 <<
"RootManager not instantised!" << endl;
225 fMCTracks = (TClonesArray*) ioman->GetObject(
"MCTrack");
227 cout <<
"-E- " << GetName() <<
"::Init: No MCTrack array!" << endl;
232 fStsPoints = (TClonesArray*) ioman->GetObject(
"StsPoint");
233 if ( ! fStsPoints ) {
239 fStsHits = (TClonesArray*) ioman->GetObject(
"StsHit");
241 cout <<
"-E- " << GetName() <<
"::Init: No StsHit array!" << endl;
246 fStsTracks = (TClonesArray*) ioman->GetObject(
"StsTrack");
247 if ( ! fStsTracks ) {
248 cout <<
"-E- " << GetName() <<
"::Init: No StsTrack array!" << endl;
253 fMatches = (TClonesArray*) ioman->GetObject(
"StsTrackMatch");
255 cout <<
"-E- " << GetName() <<
"::Init: No StsTrackMatch array!"
261 InitStatus geoStatus = GetGeometry();
262 if ( geoStatus != kSUCCESS ) {
263 cout <<
"-E- " << GetName() <<
"::Init: Error in reading geometry!"
273 cout <<
" Minimum number of STS hits : " << fMinHits << endl;
274 cout <<
" Matching quota : " << fQuota << endl;
275 cout <<
" Target position ( " << fTargetPos.X() <<
", "
276 << fTargetPos.Y() <<
", " << fTargetPos.Z() <<
") " << endl;
277 cout <<
" Number of STS stations : " << fNStations << endl;
278 if (fActive) cout <<
" ***** Task is ACTIVE *****" << endl;
279 cout <<
"==========================================================="
292 cout <<
"==========================================================="
294 cout << GetName() <<
": Reinitialising..." << endl;
297 InitStatus geoStatus = GetGeometry();
298 if ( geoStatus != kSUCCESS ) {
299 cout <<
"-E- " << GetName() <<
"::ReInit: Error in reading geometry!"
305 cout <<
" Target position ( " << fTargetPos.X() <<
", "
306 << fTargetPos.Y() <<
", " << fTargetPos.Z() <<
") " << endl;
307 cout <<
" Number of STS stations : " << fNStations << endl;
308 if (fActive) cout <<
" ***** Task is ACTIVE *****" << endl;
309 cout <<
"==========================================================="
343 FillMatchMap(nRec, nGhosts, nClones);
346 Int_t nMC = fMCTracks->GetEntriesFast();
347 for (Int_t iMC=0; iMC<nMC; iMC++) {
350 cout <<
"-E- " << GetName() <<
"::Exec: "
351 <<
"No MCTrack at index " << iMC
353 Fatal(
"Exec",
"No MCTrack in array");
358 if ( fHitMap.find(iMC) == fHitMap.end() )
continue;
359 Int_t nHits = fHitMap[iMC];
360 if ( nHits < fMinHits )
continue;
365 Bool_t isPrim = kFALSE;
366 if ( (vertex-fTargetPos).Mag() < 1. ) {
374 Double_t mom = momentum.Mag();
375 Bool_t isRef = kFALSE;
376 if ( mom > 1. && isPrim) {
382 fhMomAccAll->Fill(mom);
383 fhNpAccAll->Fill(Double_t(nHits));
385 fhMomAccPrim->Fill(mom);
386 fhNpAccPrim->Fill(Double_t(nHits));
389 fhMomAccSec->Fill(mom);
390 fhNpAccSec->Fill(Double_t(nHits));
391 fhZAccSec->Fill(vertex.Z());
398 if (fMatchMap.find(iMC) != fMatchMap.end() ) {
399 iRec = fMatchMap[iMC];
403 cout <<
"-E- " << GetName() <<
"::Exec: "
404 <<
"No StsTrack for matched MCTrack " << iMC << endl;
405 Fatal(
"Exec",
"No StsTrack for matched MCTrack");
407 quali = fQualiMap[iMC];
408 if ( quali < fQuota ) {
409 cout <<
"-E- " << GetName() <<
"::Exec: "
410 <<
"Matched StsTrack " << iRec <<
" is below matching "
411 <<
"criterion ( " << quali <<
")" << endl;
412 Fatal(
"Exec",
"Match below matching quota");
416 cout <<
"-E- " << GetName() <<
"::Exec: "
417 <<
"No StsTrackMatch for matched MCTrack " << iMC << endl;
418 Fatal(
"Exec",
"No StsTrackMatch for matched MCTrack");
420 Int_t nTrue =
match->GetNofTrueHits();
421 Int_t nWrong =
match->GetNofWrongHits();
422 Int_t nFake =
match->GetNofFakeHits();
424 if ( nTrue + nWrong + nFake != nAllHits ) {
425 cout <<
"True " << nTrue <<
" wrong " << nWrong <<
" Fake "
426 << nFake <<
" Hits " << nAllHits << endl;
427 Fatal(
"Exec",
"Wrong number of hits");
432 cout <<
"-I- " << GetName() <<
": "
433 <<
"MCTrack " << iMC <<
", hits "
434 << nHits <<
", StsTrack " << iRec <<
", hits " << nAllHits
435 <<
", true hits " << nTrue << endl;
439 fhMomRecAll->Fill(mom);
440 fhNpRecAll->Fill(Double_t(nAllHits));
443 fhMomRecPrim->Fill(mom);
444 fhNpRecPrim->Fill(Double_t(nAllHits));
445 if ( isRef ) nRecRef++;
449 fhMomRecSec->Fill(mom);
450 fhNpRecSec->Fill(Double_t(nAllHits));
451 fhZRecSec->Fill(vertex.Z());
460 Double_t effAll = Double_t(nRecAll) / Double_t(nAcc);
461 Double_t effPrim = Double_t(nRecPrim) / Double_t(nPrim);
462 Double_t effRef = Double_t(nRecRef) / Double_t(nRef);
463 Double_t effSec = Double_t(nRecSec) / Double_t(nSec);
467 if ( fVerbose > 0 ) {
468 cout <<
"---------- StsFindTracksQa : Event summary ------------"
470 cout <<
"MCTracks : " << nAll <<
", reconstructable: " << nAcc
471 <<
", reconstructed: " << nRecAll << endl;
472 cout <<
"Vertex : reconstructable: " << nPrim <<
", reconstructed: "
473 << nRecPrim <<
", efficiency " << effPrim*100. <<
"%" << endl;
474 cout <<
"Reference : reconstructable: " << nRef <<
", reconstructed: "
475 << nRecRef <<
", efficiency " << effRef*100. <<
"%" << endl;
476 cout <<
"Non-vertex : reconstructable: " << nSec <<
", reconstructed: "
477 << nRecSec <<
", efficiency " << effSec*100. <<
"%" << endl;
478 cout <<
"STSTracks " << nRec <<
", ghosts " << nGhosts
479 <<
", clones " << nClones << endl;
480 cout <<
"-----------------------------------------------------------"
484 else cout <<
"+ " << setw(15) << left << fName <<
": " << setprecision(4)
485 << setw(8) << fixed << right << fTimer.RealTime()
486 <<
" s, efficiency all " << effAll*100. <<
" %, vertex "
487 << effPrim*100. <<
" %, reference " << effRef*100. <<
" %" << endl;
495 fNRecPrim += nRecPrim;
501 fTime += fTimer.RealTime();
509void CbmStsFindTracksQa::Finish() {
512 DivideHistos(fhMomRecAll, fhMomAccAll, fhMomEffAll);
513 DivideHistos(fhMomRecPrim, fhMomAccPrim, fhMomEffPrim);
514 DivideHistos(fhMomRecSec, fhMomAccSec, fhMomEffSec);
515 DivideHistos(fhNpRecAll, fhNpAccAll, fhNpEffAll);
516 DivideHistos(fhNpRecPrim, fhNpAccPrim, fhNpEffPrim);
517 DivideHistos(fhNpRecSec, fhNpAccSec, fhNpEffSec);
518 DivideHistos(fhZRecSec, fhZAccSec, fhZEffSec);
522 fhNhClones->Scale(1./Double_t(fNEvents));
523 fhNhGhosts->Scale(1./Double_t(fNEvents));
527 Double_t effAll = Double_t(fNRecAll) / Double_t(fNAccAll);
528 Double_t effPrim = Double_t(fNRecPrim) / Double_t(fNAccPrim);
529 Double_t effRef = Double_t(fNRecRef) / Double_t(fNAccRef);
530 Double_t effSec = Double_t(fNRecSec) / Double_t(fNAccSec);
531 Double_t rateGhosts = Double_t(fNGhosts) / Double_t(fNEvents);
532 Double_t rateClones = Double_t(fNClones) / Double_t(fNEvents);
536 cout <<
"============================================================"
538 cout <<
"===== " << fName <<
": Run summary " << endl;
539 cout <<
"===== " << endl;
540 cout <<
"===== Good events : " << setw(6) << fNEvents << endl;
541 cout <<
"===== Failed events : " << setw(6) << fNEventsFailed << endl;
542 cout <<
"===== Average time : " << setprecision(4) << setw(8) << right
543 << fTime / Double_t(fNEvents) <<
" s" << endl;
544 cout <<
"===== " << endl;
545 cout <<
"===== Efficiency all tracks : " << effAll*100 <<
" % ("
546 << fNRecAll <<
"/" << fNAccAll <<
")" << endl;
547 cout <<
"===== Efficiency vertex tracks : " << effPrim*100 <<
" % ("
548 << fNRecPrim <<
"/" << fNAccPrim <<
")" << endl;
549 cout <<
"===== Efficiency reference tracks : " << effRef*100 <<
" % ("
550 << fNRecRef <<
"/" << fNAccRef <<
")" << endl;
551 cout <<
"===== Efficiency secondary tracks : " << effSec*100 <<
" % ("
552 << fNRecSec <<
"/" << fNAccSec <<
")" << endl;
553 cout <<
"===== Ghost rate " << rateGhosts <<
" per event" << endl;
554 cout <<
"===== Clone rate " << rateClones <<
" per event" << endl;
555 cout <<
"============================================================"
559 gDirectory->mkdir(
"STSFindTracksQA");
560 gDirectory->cd(
"STSFindTracksQA");
561 TIter next(fHistoList);
562 while ( TH1* histo = ((TH1*)next()) ) histo->Write();
563 gDirectory->cd(
"..");
570InitStatus CbmStsFindTracksQa::GetGeometry() {
574 cout <<
"-W- " << GetName() <<
"::GetGeometry: No passive geometry!"
576 fTargetPos.SetXYZ(0., 0., 0.);
581 cout <<
"-W- " << GetName() <<
"::GetGeometry: No passive node array"
583 fTargetPos.SetXYZ(0., 0., 0.);
586 FairGeoNode* target = (FairGeoNode*) passNodes->FindObject(
"targ");
588 cout <<
"-E- " << GetName() <<
"::GetGeometry: No target node"
590 fTargetPos.SetXYZ(0., 0., 0.);
593 FairGeoVector targetPos = target->getLabTransform()->getTranslation();
594 FairGeoVector centerPos = target->getCenterPosition().getTranslation();
595 Double_t targetX = targetPos.X() + centerPos.X();
596 Double_t targetY = targetPos.Y() + centerPos.Y();
597 Double_t targetZ = targetPos.Z() + centerPos.Z();
598 fTargetPos.SetXYZ(targetX, targetY, targetZ);
602 cout <<
"-W- " << GetName() <<
"::GetGeometry: No passive geometry!"
609 cout <<
"-E- " << GetName() <<
"::GetGeometry: No STS node array"
614 fNStations = stsNodes->GetEntries();
624void CbmStsFindTracksQa::CreateHistos() {
627 fHistoList =
new TList();
630 Double_t minMom = 0.;
631 Double_t maxMom = 10.;
633 fhMomAccAll =
new TH1F(
"hMomAccAll",
"all reconstructable tracks",
634 nBinsMom, minMom, maxMom);
635 fhMomRecAll =
new TH1F(
"hMomRecAll",
"all reconstructed tracks",
636 nBinsMom, minMom, maxMom);
637 fhMomEffAll =
new TH1F(
"hMomEffAll",
"efficiency all tracks",
638 nBinsMom, minMom, maxMom);
639 fhMomAccPrim =
new TH1F(
"hMomAccPrim",
"reconstructable vertex tracks",
640 nBinsMom, minMom, maxMom);
641 fhMomRecPrim =
new TH1F(
"hMomRecPrim",
"reconstructed vertex tracks",
642 nBinsMom, minMom, maxMom);
643 fhMomEffPrim =
new TH1F(
"hMomEffPrim",
"efficiency vertex tracks",
644 nBinsMom, minMom, maxMom);
645 fhMomAccSec =
new TH1F(
"hMomAccSec",
"reconstructable non-vertex tracks",
646 nBinsMom, minMom, maxMom);
647 fhMomRecSec =
new TH1F(
"hMomRecSec",
"reconstructed non-vertex tracks",
648 nBinsMom, minMom, maxMom);
649 fhMomEffSec =
new TH1F(
"hMomEffSec",
"efficiency non-vertex tracks",
650 nBinsMom, minMom, maxMom);
651 fHistoList->Add(fhMomAccAll);
652 fHistoList->Add(fhMomRecAll);
653 fHistoList->Add(fhMomEffAll);
654 fHistoList->Add(fhMomAccPrim);
655 fHistoList->Add(fhMomRecPrim);
656 fHistoList->Add(fhMomEffPrim);
657 fHistoList->Add(fhMomAccSec);
658 fHistoList->Add(fhMomRecSec);
659 fHistoList->Add(fhMomEffSec);
662 Double_t minNp = -0.5;
663 Double_t maxNp = 15.5;
665 fhNpAccAll =
new TH1F(
"hNpAccAll",
"all reconstructable tracks",
666 nBinsNp, minNp, maxNp);
667 fhNpRecAll =
new TH1F(
"hNpRecAll",
"all reconstructed tracks",
668 nBinsNp, minNp, maxNp);
669 fhNpEffAll =
new TH1F(
"hNpEffAll",
"efficiency all tracks",
670 nBinsNp, minNp, maxNp);
671 fhNpAccPrim =
new TH1F(
"hNpAccPrim",
"reconstructable vertex tracks",
672 nBinsNp, minNp, maxNp);
673 fhNpRecPrim =
new TH1F(
"hNpRecPrim",
"reconstructed vertex tracks",
674 nBinsNp, minNp, maxNp);
675 fhNpEffPrim =
new TH1F(
"hNpEffPrim",
"efficiency vertex tracks",
676 nBinsNp, minNp, maxNp);
677 fhNpAccSec =
new TH1F(
"hNpAccSec",
"reconstructable non-vertex tracks",
678 nBinsNp, minNp, maxNp);
679 fhNpRecSec =
new TH1F(
"hNpRecSec",
"reconstructed non-vertex tracks",
680 nBinsNp, minNp, maxNp);
681 fhNpEffSec =
new TH1F(
"hNpEffSec",
"efficiency non-vertex tracks",
682 nBinsNp, minNp, maxNp);
683 fHistoList->Add(fhNpAccAll);
684 fHistoList->Add(fhNpRecAll);
685 fHistoList->Add(fhNpEffAll);
686 fHistoList->Add(fhNpAccPrim);
687 fHistoList->Add(fhNpRecPrim);
688 fHistoList->Add(fhNpEffPrim);
689 fHistoList->Add(fhNpAccSec);
690 fHistoList->Add(fhNpRecSec);
691 fHistoList->Add(fhNpEffSec);
697 fhZAccSec =
new TH1F(
"hZAccSec",
"reconstructable non-vertex tracks",
699 fhZRecSec =
new TH1F(
"hZRecSecl",
"reconstructed non-vertex tracks",
701 fhZEffSec =
new TH1F(
"hZEffRec",
"efficiency non-vertex tracks",
703 fHistoList->Add(fhZAccSec);
704 fHistoList->Add(fhZRecSec);
705 fHistoList->Add(fhZEffSec);
708 fhNhClones =
new TH1F(
"hNhClones",
"number of hits for clones",
709 nBinsNp, minNp, maxNp);
710 fhNhGhosts =
new TH1F(
"hNhGhosts",
"number of hits for ghosts",
711 nBinsNp, minNp, maxNp);
712 fHistoList->Add(fhNhClones);
713 fHistoList->Add(fhNhGhosts);
721void CbmStsFindTracksQa::Reset() {
723 TIter next(fHistoList);
724 while ( TH1* histo = ((TH1*)next()) ) histo->Reset();
726 fNAccAll = fNAccPrim = fNAccRef = fNAccSec = 0;
727 fNRecAll = fNRecPrim = fNRecRef = fNRecSec = 0;
728 fNGhosts = fNClones = fNEvents = 0;
736void CbmStsFindTracksQa::FillHitMap() {
738 Int_t nHits = fStsHits->GetEntriesFast();
739 for (Int_t iHit=0; iHit<nHits; iHit++) {
741 Int_t iMc = hit->GetRefIndex();
742 if ( iMc < 0 )
continue;
744 Int_t iTrack = stsPoint->GetTrackID();
753void CbmStsFindTracksQa::FillMatchMap(Int_t& nRec, Int_t& nGhosts,
763 nRec = fStsTracks->GetEntriesFast();
764 Int_t nMtc = fMatches->GetEntriesFast();
765 if ( nMtc != nRec ) {
766 cout <<
"-E- " << GetName() <<
"::Exec: Number of StsMatches ("
767 << nMtc <<
") does not equal number of StsTracks ("
768 << nRec <<
")" << endl;
769 Fatal(
"Exec",
"Inequal number of StsTrack and StsTrackMatch");
771 for (Int_t iRec=0; iRec<nRec; iRec++) {
775 cout <<
"-E- " << GetName() <<
"::Exec: "
776 <<
"No StsTrack at index " << iRec << endl;
777 Fatal(
"Exec",
"No StsTrack in array");
783 cout <<
"-E- " << GetName() <<
"::Exec: "
784 <<
"No StsTrackMatch at index " << iRec << endl;
785 Fatal(
"Exec",
"No StsTrackMatch in array");
787 Int_t nTrue =
match->GetNofTrueHits();
789 Int_t iMC =
match->GetMCTrackId();
792 cout <<
"-I- " << GetName() <<
":"
793 <<
"No MC match for StsTrack " << iRec << endl;
794 fhNhGhosts->Fill(nHits);
800 Double_t quali = Double_t(nTrue) / Double_t(nHits);
801 if ( quali >= fQuota ) {
804 if ( fMatchMap.find(iMC) == fMatchMap.end() ) {
805 fMatchMap[iMC] = iRec;
806 fQualiMap[iMC] = quali;
812 cout <<
"-I- " << GetName() <<
": "
813 <<
"MCTrack " << iMC <<
" doubly matched."
814 <<
"Current match " << iRec
815 <<
", previous match " << fMatchMap[iMC]
817 if ( fQualiMap[iMC] < quali ) {
820 fhNhClones->Fill(Double_t(oldTrack->
GetNStsHits()));
821 fMatchMap[iMC] = iRec;
822 fQualiMap[iMC] = quali;
824 else fhNhClones->Fill(nHits);
833 cout <<
"-I- " << GetName() <<
":"
834 <<
"StsTrack " << iRec <<
" below matching criterion "
835 <<
"(" << quali <<
")" << endl;
836 fhNhGhosts->Fill(nHits);
848void CbmStsFindTracksQa::DivideHistos(TH1* histo1, TH1* histo2,
851 if ( !histo1 || !histo2 || !histo3 ) {
852 cout <<
"-E- " << GetName() <<
"::DivideHistos: "
853 <<
"NULL histogram pointer" << endl;
854 Fatal(
"DivideHistos",
"Null histo pointer");
857 Int_t nBins = histo1->GetNbinsX();
858 if ( histo2->GetNbinsX() != nBins || histo3->GetNbinsX() != nBins ) {
859 cout <<
"-E- " << GetName() <<
"::DivideHistos: "
860 <<
"Different bin numbers in histos" << endl;
861 cout << histo1->GetName() <<
" " << histo1->GetNbinsX() << endl;
862 cout << histo2->GetName() <<
" " << histo2->GetNbinsX() << endl;
863 cout << histo3->GetName() <<
" " << histo3->GetNbinsX() << endl;
867 Double_t c1, c2, c3, ce;
868 for (Int_t iBin=0; iBin<nBins; iBin++) {
869 c1 = histo1->GetBinContent(iBin);
870 c2 = histo2->GetBinContent(iBin);
873 Double_t c4=(c3 * ( 1. - c3 ) / c2);
875 ce = TMath::Sqrt( c3 * ( 1. - c3 ) / c2 );
884 histo3->SetBinContent(iBin, c3);
885 histo3->SetBinError(iBin, ce);
TObjArray * GetGeoSensitiveNodes()
void GetMomentum(TVector3 &momentum) const
void GetStartVertex(TVector3 &vertex) const
CbmStsFindTracksQa(Int_t iVerbose=1)
virtual InitStatus Init()
virtual ~CbmStsFindTracksQa()
virtual void Exec(Option_t *opt)
virtual void SetParContainers()
virtual InitStatus ReInit()
Int_t GetNStsHits() const
TObjArray * GetGeoPassiveNodes()