9#include "CbmStsPoint.h"
10#include "CbmStsTrack.h"
11#include "CbmTrackMatch.h"
15#include "FairGeoNode.h"
16#include "FairGeoPassivePar.h"
17#include "FairGeoVector.h"
18#include "CbmMCTrack.h"
19#include "FairRootManager.h"
20#include "FairRunAna.h"
21#include "FairRuntimeDb.h"
29#include "TClonesArray.h"
45: FairTask(
"STSReconstructionQA", iVerbose),
114 fOnlineAnalysis(kFALSE),
123: FairTask(
"STSReconstructionQA", iVerbose),
192 fOnlineAnalysis(visualizeBool),
198 fPartPdgTable[0] = 11;
199 fPartPdgTable[1] = - 11;
200 fPartPdgTable[2] = 211;
201 fPartPdgTable[3] = - 211;
202 fPartPdgTable[4] = 321;
203 fPartPdgTable[5] = - 321;
204 fPartPdgTable[6] = 2212;
205 fPartPdgTable[7] = -2212;
206 fPartPdgTable[8] = -7777;
207 fPartPdgTable[9] = -7777;
214 fHistoList->Delete();
216 fOccupHList->Delete();
224 FairRunAna*
run = FairRunAna::Instance();
226 cout <<
"-E- " << GetName() <<
"::SetParContainers: No FairRunAna!"
232 FairRuntimeDb* runDb =
run->GetRuntimeDb();
234 cout <<
"-E- " << GetName() <<
"::SetParContainers: No runtime database!"
242 cout <<
"-E- " << GetName() <<
"::SetParContainers: "
243 <<
"No passive geometry parameters!" << endl;
248 fStsGeo = (
CbmGeoStsPar*) runDb->getContainer(
"CbmGeoStsPar");
250 cout <<
"-E- " << GetName() <<
"::SetParContainers: "
251 <<
"No STS geometry parameters!" << endl;
262 cout <<
"==========================================================="
264 cout << GetName() <<
": Initialising..." << endl;
267 FairRootManager* ioman = FairRootManager::Instance();
269 cout <<
"-E- " << GetName() <<
"::Init: "
270 <<
"RootManager not instantised!" << endl;
275 fMCTracks = (TClonesArray*) ioman->GetObject(
"MCTrack");
277 cout <<
"-E- " << GetName() <<
"::Init: No MCTrack array!" << endl;
282 fStsPoints = (TClonesArray*) ioman->GetObject(
"StsPoint");
283 if ( ! fStsPoints ) {
289 fStsHits = (TClonesArray*) ioman->GetObject(
"StsHit");
291 cout <<
"-E- " << GetName() <<
"::Init: No StsHit array!" << endl;
296 fStsTracks = (TClonesArray*) ioman->GetObject(
"StsTrack");
297 if ( ! fStsTracks ) {
298 cout <<
"-E- " << GetName() <<
"::Init: No StsTrack array!" << endl;
303 fMatches = (TClonesArray*) ioman->GetObject(
"StsTrackMatch");
305 cout <<
"-E- " << GetName() <<
"::Init: No StsTrackMatch array!"
311 fStsDigis = (TClonesArray*) ioman->GetObject(
"StsDigi");
313 cout <<
"-E- " << GetName() <<
"::Init: No StsDigi array!"
328 InitStatus geoStatus = GetGeometry();
329 if ( geoStatus != kSUCCESS ) {
330 cout <<
"-E- " << GetName() <<
"::Init: Error in reading geometry!"
339 if ( fOnlineAnalysis ) {
340 fOnlineCanvas =
new TCanvas(
"StsRecoOnline",
"Sts reconstruction online" ,10,10,600,900);
341 fOnlinePad[0] =
new TPad(
"titlePad",
"Title pad" ,0.01,0.91,0.99,0.99);
342 fOnlinePad[1] =
new TPad(
"efficiencyPad",
"Efficiency pad" ,0.01,0.61,0.39,0.89);
343 fOnlinePad[2] =
new TPad(
"resolutionPad",
"Momentum resolution pad" ,0.01,0.31,0.39,0.59);
344 fOnlinePad[3] =
new TPad(
"hNpAccAll",
"Nof points reconstructuble tracks" ,0.41,0.66,0.69,0.89);
345 fOnlinePad[4] =
new TPad(
"hNpRecAll",
"Nof points reconstructed track" ,0.71,0.66,0.99,0.89);
346 fOnlinePad[5] =
new TPad(
"hStsTrackFPosZ",
"Param First pos Z" ,0.41,0.41,0.69,0.64);
347 fOnlinePad[6] =
new TPad(
"hStsTrackLPosZ",
"Param Last pos Z" ,0.71,0.41,0.99,0.64);
348 fOnlinePad[7] =
new TPad(
"hMomPrim",
"Momentum of primary tracks" ,0.41,0.16,0.69,0.41);
349 fOnlinePad[8] =
new TPad(
"hMomSec",
"Momentum of secondary tracks" ,0.71,0.16,0.99,0.41);
350 fOnlinePad[9] =
new TPad(
"printoutPad",
"Print information pad" ,0.01,0.01,0.39,0.29);
351 fOnlinePad[7]->SetLogy();
352 fOnlinePad[8]->SetLogy();
353 for ( Int_t ipad = 0 ; ipad < 10 ; ipad++ ) {
354 fOnlinePad[ipad]->SetFillColor(0);
355 fOnlinePad[ipad]->SetBorderMode(0);
356 fOnlinePad[ipad]->Draw();
360 TLegend* brp =
new TLegend(0.1,0.1,0.9,0.9,
"Online STS reconstruction");
361 brp->SetTextAlign(22);
362 brp->SetTextSize(0.6);
363 brp->SetTextColor(1);
364 brp->SetBorderSize(0);
365 brp->SetFillColor(0);
367 fOnlinePad[0]->Update();
371 cout <<
" Minimum number of STS hits : " << fMinHits << endl;
372 cout <<
" Matching quota : " << fQuota << endl;
373 cout <<
" Target position ( " << fTargetPos.X() <<
", "
374 << fTargetPos.Y() <<
", " << fTargetPos.Z() <<
") " << endl;
375 cout <<
" Number of STS stations : " << fNStations << endl;
376 if (fActive) cout <<
" ***** Task is ACTIVE *****" << endl;
377 cout <<
"==========================================================="
388 cout <<
"==========================================================="
390 cout << GetName() <<
": Reinitialising..." << endl;
393 InitStatus geoStatus = GetGeometry();
394 if ( geoStatus != kSUCCESS ) {
395 cout <<
"-E- " << GetName() <<
"::ReInit: Error in reading geometry!"
401 cout <<
" Target position ( " << fTargetPos.X() <<
", "
402 << fTargetPos.Y() <<
", " << fTargetPos.Z() <<
") " << endl;
403 cout <<
" Number of STS stations : " << fNStations << endl;
404 if (fActive) cout <<
" ***** Task is ACTIVE *****" << endl;
405 cout <<
"==========================================================="
438 for ( Int_t istat = 0 ; istat < fNStations ; istat++ ) {
439 for ( Int_t isect = 0 ; isect < fNSectors[istat] ; isect++ ) {
440 fNofHits[istat][isect] = 0;
441 for ( Int_t iside = 0 ; iside < 2 ; iside++ ) {
442 fNofFiredDigis[istat][isect][iside] = 0;
443 for ( Int_t ichip = 0 ; ichip < 8 ; ichip++ )
444 fNofDigisPChip[istat][isect][iside][ichip] = 0;
450 Int_t nMC = fMCTracks->GetEntriesFast();
453 FillMatchMap(nRec, nGhosts, nClones);
454 for (Int_t iMC=0; iMC<nMC; iMC++) {
457 cout <<
"-E- " << GetName() <<
"::Exec: "
458 <<
"No MCTrack at index " << iMC
460 Fatal(
"Exec",
"No MCTrack in array");
464 Bool_t isPrim = kFALSE;
466 Double_t mom = momentum.Mag();
468 if ( (vertex-fTargetPos).Mag() < 1. )
489 if ( fHitMap.find(iMC) == fHitMap.end() )
continue;
490 Int_t nHits = fHitMap[iMC];
492 Int_t minHits = fMinHits;
493 for (Int_t
i=0;
i<9;
i++) {
495 nHitsSt = HitSt[iMC][
i];
500 if (minHits>4) minHits=minHits-1;
502 if ( nHits < (minHits) )
continue;
506 if ( isPrim ) nPrim++;
512 Bool_t isRef = kFALSE;
513 if ( mom > 1. && isPrim) {
519 fhMomAccAll->Fill(mom);
520 fhNpAccAll->Fill(Double_t(nHits));
522 fhMomAccPrim->Fill(mom);
523 fhNpAccPrim->Fill(Double_t(nHits));
532 fhMomAccSec->Fill(mom);
533 fhNpAccSec->Fill(Double_t(nHits));
534 fhZAccSec->Fill(vertex.Z());
540 Bool_t isRec = kFALSE;
541 if (fMatchMap.find(iMC) != fMatchMap.end() ) {
548 iRec = fMatchMap[iMC];
552 cout <<
"-E- " << GetName() <<
"::Exec: "
553 <<
"No StsTrack for matched MCTrack " << iMC << endl;
554 Fatal(
"Exec",
"No StsTrack for matched MCTrack");
556 quali = fQualiMap[iMC];
557 if ( quali < fQuota ) {
558 cout <<
"-E- " << GetName() <<
"::Exec: "
559 <<
"Matched StsTrack " << iRec <<
" is below matching "
560 <<
"criterion ( " << quali <<
")" << endl;
561 Fatal(
"Exec",
"Match below matching quota");
565 cout <<
"-E- " << GetName() <<
"::Exec: "
566 <<
"No StsTrackMatch for matched MCTrack " << iMC << endl;
567 Fatal(
"Exec",
"No StsTrackMatch for matched MCTrack");
569 Int_t nTrue =
match->GetNofTrueHits();
570 Int_t nWrong =
match->GetNofWrongHits();
571 Int_t nFake =
match->GetNofFakeHits();
573 if ( nTrue + nWrong + nFake != nAllHits ) {
574 cout <<
"True " << nTrue <<
" wrong " << nWrong <<
" Fake "
575 << nFake <<
" Hits " << nAllHits << endl;
576 Fatal(
"Exec",
"Wrong number of hits");
581 cout <<
"-I- " << GetName() <<
": "
582 <<
"MCTrack " << iMC <<
", hits "
583 << nAllHits <<
", StsTrack " << iRec <<
", hits " << nHits
584 <<
", true hits " << nTrue << endl;
588 fhMomResAll->Fill(mom,100.*(mom-1./TMath::Abs(stsTrack->
GetParamFirst()->GetQp()))/mom);
590 fhMomRecAll->Fill(mom);
591 fhNpRecAll->Fill(Double_t(nAllHits));
594 fhMomRecPrim->Fill(mom);
595 fhNpRecPrim->Fill(Double_t(nAllHits));
604 if ( isRef ) nRecRef++;
606 fhMomResPrim->Fill(mom,100.*(mom-1./TMath::Abs(stsTrack->
GetParamFirst()->GetQp()))/mom);
610 fhMomRecSec->Fill(mom);
611 fhNpRecSec->Fill(Double_t(nHits));
612 fhZRecSec->Fill(vertex.Z());
614 fhMomResSec->Fill(mom,100.*(mom-1./TMath::Abs(stsTrack->
GetParamFirst()->GetQp()))/mom);
620 for ( Int_t itemp = 0 ; itemp < 10 ; itemp++ ) {
621 if ( fPartPdgTable[itemp] == -7777 )
break;
622 if ( fPartPdgTable[itemp] != partPdgCode )
continue;
623 fhMomAccPart[itemp]->Fill(mom);
625 fhMomRecPart[itemp]->Fill(mom);
630 Int_t nofStsHits = fStsHits->GetEntriesFast();
633 Int_t hitStationLimits[2][100];
635 for ( Int_t ist = 0 ; ist < fNStations ; ist++ ) {
636 hitStationLimits[0][ist] = -1;
637 hitStationLimits[1][ist] = -1;
641 Int_t nofStsDigis = fStsDigis->GetEntriesFast();
642 for ( Int_t idigi = 0 ; idigi < nofStsDigis ; idigi++ ) {
651 for ( Int_t ihit = 0 ; ihit < nofStsHits ; ihit++ ) {
654 if ( hitStationLimits[0][stsHit->
GetStationNr()-1] == -1 )
657 if ( hitStationLimits[1][stsHitBack->
GetStationNr()-1] == -1 ) {
658 hitStationLimits[1][stsHitBack->
GetStationNr()-1] = nofStsHits-ihit;
704 Double_t effAll = 1.;
705 if ( nAcc ) effAll = Double_t(nRecAll) / Double_t(nAcc);
706 Double_t effPrim = 1.;
707 if ( nPrim ) effPrim = Double_t(nRecPrim) / Double_t(nPrim);
708 Double_t effRef = 1.;
709 if ( nRef ) effRef = Double_t(nRecRef) / Double_t(nRef);
710 Double_t effSec = 1.;
711 if ( nSec ) effSec = Double_t(nRecSec) / Double_t(nSec);
713 fhRefTracks ->SetBinContent(fNEvents+1,nRef);
714 fhRecRefTracks->SetBinContent(fNEvents+1,nRecRef);
717 if ( fVerbose > 1 ) {
718 cout <<
"---------- StsReconstructionQa : Event " << fNEvents+1 <<
" summary ------------"
720 cout <<
"MCTracks : " << nAll <<
", reconstructable: " << nAcc
721 <<
", reconstructed: " << nRecAll << endl;
722 cout <<
"Vertex : reconstructable: " << nPrim <<
", reconstructed: "
723 << nRecPrim <<
", efficiency " << effPrim*100. <<
"%" << endl;
724 cout <<
"Reference : reconstructable: " << nRef <<
", reconstructed: "
725 << nRecRef <<
", efficiency " << effRef*100. <<
"%" << endl;
726 cout <<
"Non-vertex : reconstructable: " << nSec <<
", reconstructed: "
727 << nRecSec <<
", efficiency " << effSec*100. <<
"%" << endl;
728 cout <<
"STSTracks " << nRec <<
", ghosts " << nGhosts
729 <<
", clones " << nClones << endl;
730 cout <<
"-----------------------------------------------------------"
734 if ( fVerbose == 1 ) {
735 cout <<
"\r+ " << setw(15) << left << fName <<
": event " << fNEvents+1 <<
" " << setprecision(4)
736 << setw(8) << fixed << right << fTimer.RealTime()
737 <<
" s, efficiency all " << effAll*100. <<
" %, vertex "
738 << effPrim*100. <<
" %, reference " << effRef*100. <<
" %" << endl;
747 fNRecPrim += nRecPrim;
754 fTime += fTimer.RealTime();
758 effRef = Double_t(fNRecRef) / Double_t(fNAccRef);
760 if ( fOnlineAnalysis ) {
762 DivideHistos(fhMomRecAll, fhMomAccAll, fhMomEffAll );
763 DivideHistos(fhMomRecPrim, fhMomAccPrim, fhMomEffPrim);
764 DivideHistos(fhMomRecSec, fhMomAccSec, fhMomEffSec );
765 fhMomEffAll->SetAxisRange(0.,1.1,
"Y");
766 fhMomEffAll->SetLineWidth(2);
767 fhMomEffAll->SetLineColor(1);
768 fhMomEffAll->SetTitle(
"Efficiency");
770 fhMomEffPrim->SetLineWidth(2);
771 fhMomEffPrim->SetLineColor(2);
772 fhMomEffPrim->Draw(
"same");
773 fhMomEffSec->SetLineWidth(2);
774 fhMomEffSec->SetLineColor(3);
775 fhMomEffSec->Draw(
"same");
776 TLegend* effLeg =
new TLegend(0.3,0.15,0.48,0.4);
777 effLeg->SetBorderSize(0);
778 effLeg->SetFillColor(0);
779 effLeg->AddEntry(fhMomEffAll,
"all" ,
"pl");
780 effLeg->AddEntry(fhMomEffPrim,
"prim",
"pl");
781 effLeg->AddEntry(fhMomEffSec,
"sec" ,
"pl");
783 TLine* oneLine =
new TLine(0.0,1.0,10.0,1.0);
784 oneLine->SetLineStyle(2);
786 fOnlinePad[1]->Update();
789 if ( fhMomResPrim->Integral() )
790 fOnlinePad[2]->SetLogz();
791 fhMomResPrim->SetAxisRange(0.,3.,
"Y");
792 fhMomResPrim->Draw(
"cont0");
793 for ( Int_t ibin = fhMomResPrim->GetXaxis()->GetNbins() ; ibin > 1 ; ibin-- ) {
794 TF1* gausFit =
new TF1(
"gausFit",
"gaus");
795 TH1F* tempProjY = (TH1F*)fhMomResPrim->ProjectionY(
"tempProjY",ibin,ibin);
796 tempProjY->Fit(
"gausFit",
"QN",
"",-5.,5.);
797 fhLowBand->SetBinContent(ibin,gausFit->GetParameter(1)-gausFit->GetParameter(2));
798 fhLowBand->SetBinError(ibin,0.01);
799 fhHigBand->SetBinContent(ibin,gausFit->GetParameter(2));
800 fhHigBand->SetBinError(ibin,gausFit->GetParError(2));
804 fhLowBand->SetMarkerSize(0.2);
805 fhLowBand->SetLineWidth(2);
806 fhHigBand->SetMarkerSize(0.1);
807 fhHigBand->SetLineWidth(2);
808 fhLowBand->Draw(
"Psame");
809 fhHigBand->Draw(
"Psame");
810 fOnlinePad[2]->Update();
814 fOnlinePad[3]->Update();
818 fOnlinePad[4]->Update();
821 fhStsTrackFPos[2]->Draw();
822 fOnlinePad[5]->Update();
825 fhStsTrackLPos[2]->Draw();
826 fOnlinePad[6]->Update();
829 fhMomAccPrim->SetLineWidth(2);
830 fhMomAccPrim->SetLineColor(3);
831 fhMomAccPrim->Draw();
832 fhMomRecPrim->SetLineColor(2);
834 fhMomRecPrim->Draw(
"same");
835 TLegend* momLeg =
new TLegend(0.55,0.45,0.72,0.8);
836 momLeg->SetBorderSize(0);
837 momLeg->SetFillColor(0);
838 momLeg->SetTextSize(0.07);
839 momLeg->AddEntry(fhMomAccPrim,
"acc prim" ,
"pl");
840 momLeg->AddEntry(fhMomRecPrim,
"rec prim" ,
"pl");
842 fOnlinePad[7]->Update();
845 fhMomAccSec->SetLineWidth(2);
846 fhMomAccSec->SetLineColor(3);
848 fhMomRecSec->SetLineColor(2);
850 fhMomRecSec->Draw(
"same");
851 TLegend* momsLeg =
new TLegend(0.55,0.45,0.72,0.8);
852 momsLeg->SetBorderSize(0);
853 momsLeg->SetFillColor(0);
854 momsLeg->SetTextSize(0.07);
855 momsLeg->AddEntry(fhMomAccSec,
"acc sec" ,
"pl");
856 momsLeg->AddEntry(fhMomRecSec,
"rec sec" ,
"pl");
858 fOnlinePad[8]->Update();
860 TF1* allEffFit =
new TF1 (
"allEffFit",
"pol0",1.,10.);
861 fhMomEffAll->Fit(allEffFit,
"QN",
"",1,10);
862 Double_t allEff = allEffFit->GetParameter(0);
864 if ( fhMomAccAll->Integral() )
865 effAll = fhMomRecAll->Integral()/fhMomAccAll->Integral();
866 TF1* primEffFit =
new TF1 (
"primEffFit",
"pol0",1.,10.);
867 fhMomEffPrim->Fit(primEffFit,
"QN",
"",1,10);
868 Double_t primEff = primEffFit->GetParameter(0);
870 if ( fhMomAccPrim->Integral() )
871 effPrim = fhMomRecPrim->Integral()/fhMomAccPrim->Integral();
872 TF1* secEffFit =
new TF1 (
"secEffFit",
"pol0",1.,10.);
873 fhMomEffSec->Fit(secEffFit,
"QN",
"",1,10);
874 Double_t secEff = secEffFit->GetParameter(0);
876 if ( fhMomAccSec->Integral() )
877 effSec = fhMomRecSec->Integral()/fhMomAccSec->Integral();
879 TF1* momentumResFuncPrim =
new TF1(
"momentumResFuncPrim",
"gaus",-10.,10.);
880 TH1F* momentumResHistPrim = (TH1F*)fhMomResPrim->ProjectionY(
"momentumResHistPrim");
881 momentumResHistPrim->Fit(momentumResFuncPrim,
"QN",
"",-10.,10.);
882 Double_t momentumResolutionPrim = momentumResFuncPrim->GetParameter(2);
883 TF1* momentumResFuncAll =
new TF1(
"momentumResFuncAll",
"gaus",-10.,10.);
884 TH1F* momentumResHistAll = (TH1F*)fhMomResAll->ProjectionY(
"momentumResHistAll");
885 momentumResHistAll->Fit(momentumResFuncAll,
"QN",
"",-10.,10.);
886 Double_t momentumResolutionAll = momentumResFuncAll->GetParameter(2);
889 TPaveText* printoutPave =
new TPaveText(0.0,0.0,1.0,1.0);
890 printoutPave->SetTextAlign(23);
891 printoutPave->SetTextSize(0.05);
892 printoutPave->SetTextColor(1);
893 printoutPave->SetBorderSize(0);
894 printoutPave->SetFillColor(0);
895 printoutPave->AddText(Form(
"%i events",fNEvents));
896 printoutPave->AddText(Form(
"%3.2f prim, %3.2f sec, %3.2f gh, %3.2f cl",
897 Double_t (fNRecPrim)/Double_t (fNEvents),
898 Double_t (fNRecSec) /Double_t (fNEvents),
899 Double_t (fNGhosts) /Double_t (fNEvents),
900 Double_t (fNClones) /Double_t (fNEvents)));
906 printoutPave->AddText(
"Tracking efficiencies (p>1.0 GeV/c):");
907 printoutPave->AddText(Form(
"all = %2.2f%%(%2.2f%%)",100.*effAll,100.*allEff));
908 printoutPave->AddText(Form(
"vertex = %2.2f%%(%2.2f%%)",100.*effPrim,100.*primEff));
909 printoutPave->AddText(Form(
"reference = %2.2f%%",100.*effRef));
910 printoutPave->AddText(Form(
"non-vertex = %2.2f%%(%2.2f%%)",100.*effSec,100.*secEff));
911 printoutPave->AddText(Form(
"Momentum resolution = %3.2f%%(%3.2f%%)",momentumResolutionAll,momentumResolutionPrim));
912 fOnlinePad[9]->Clear();
913 printoutPave->Draw();
914 fOnlinePad[9]->Update();
921void CbmStsReconstructionQa::Finish() {
924 DivideHistos(fhMomRecAll, fhMomAccAll, fhMomEffAll);
925 DivideHistos(fhMomRecPrim, fhMomAccPrim, fhMomEffPrim);
926 DivideHistos(fhMomRecSec, fhMomAccSec, fhMomEffSec);
927 DivideHistos(fhNpRecAll, fhNpAccAll, fhNpEffAll);
928 DivideHistos(fhNpRecPrim, fhNpAccPrim, fhNpEffPrim);
929 DivideHistos(fhNpRecSec, fhNpAccSec, fhNpEffSec);
930 DivideHistos(fhZRecSec, fhZAccSec, fhZEffSec);
939 for ( Int_t itemp = 0 ; itemp < 10 ; itemp++ ) {
940 if ( fPartPdgTable[itemp] == -7777 )
break;
941 DivideHistos(fhMomRecPart[itemp], fhMomAccPart[itemp], fhMomEffPart[itemp]);
946 fhNhClones->Scale(1./Double_t(fNEvents));
947 fhNhGhosts->Scale(1./Double_t(fNEvents));
951 Double_t effAll = 1.;
952 if ( fNAccAll ) effAll = Double_t(fNRecAll) / Double_t(fNAccAll);
953 Double_t effPrim = 1.;
954 if ( fNAccPrim ) effPrim = Double_t(fNRecPrim) / Double_t(fNAccPrim);
955 Double_t effRef = 1.;
956 if ( fNAccRef ) effRef = Double_t(fNRecRef) / Double_t(fNAccRef);
957 Double_t effSec = 1.;
958 if ( fNAccSec ) effSec = Double_t(fNRecSec) / Double_t(fNAccSec);
959 Double_t rateGhosts = Double_t(fNGhosts) / Double_t(fNEvents);
960 Double_t rateClones = Double_t(fNClones) / Double_t(fNEvents);
964 cout <<
"============================================================"
966 cout <<
"===== " << fName <<
": Run summary " << endl;
967 cout <<
"===== " << endl;
968 cout <<
"===== Good events : " << setw(6) << fNEvents << endl;
969 cout <<
"===== Failed events : " << setw(6) << fNEventsFailed << endl;
970 cout <<
"===== Average time : " << setprecision(4) << setw(8) << right
971 << fTime / Double_t(fNEvents) <<
" s" << endl;
972 cout <<
"===== " << endl;
973 cout <<
"===== Efficiency all tracks : " << effAll*100 <<
" % ("
974 << fNRecAll <<
"/" << fNAccAll <<
")" << endl;
975 cout <<
"===== Efficiency vertex tracks : " << effPrim*100 <<
" % ("
976 << fNRecPrim <<
"/" << fNAccPrim <<
")" << endl;
977 cout <<
"===== Efficiency reference tracks : " << effRef*100 <<
" % ("
978 << fNRecRef <<
"/" << fNAccRef <<
")" << endl;
979 cout <<
"===== Efficiency secondary tracks : " << effSec*100 <<
" % ("
980 << fNRecSec <<
"/" << fNAccSec <<
")" << endl;
981 cout <<
"===== Ghost rate " << rateGhosts <<
" per event" << endl;
982 cout <<
"===== Clone rate " << rateClones <<
" per event" << endl;
983 cout <<
"============================================================"
987 gDirectory->mkdir(
"STSReconstructionQA");
988 gDirectory->cd(
"STSReconstructionQA");
989 TIter next(fHistoList);
990 while ( TH1* histo = ((TH1*)next()) ) histo->Write();
998 gDirectory->cd(
"..");
1004InitStatus CbmStsReconstructionQa::GetGeometry() {
1008 cout <<
"-W- " << GetName() <<
"::GetGeometry: No passive geometry!"
1010 fTargetPos.SetXYZ(0., 0., 0.);
1014 if ( ! passNodes ) {
1015 cout <<
"-W- " << GetName() <<
"::GetGeometry: No passive node array"
1017 fTargetPos.SetXYZ(0., 0., 0.);
1020 FairGeoNode* target = (FairGeoNode*) passNodes->FindObject(
"targ");
1022 cout <<
"-E- " << GetName() <<
"::GetGeometry: No target node"
1024 fTargetPos.SetXYZ(0., 0., 0.);
1027 FairGeoVector targetPos = target->getLabTransform()->getTranslation();
1028 FairGeoVector centerPos = target->getCenterPosition().getTranslation();
1029 Double_t targetX = targetPos.X() + centerPos.X();
1030 Double_t targetY = targetPos.Y() + centerPos.Y();
1031 Double_t targetZ = targetPos.Z() + centerPos.Z();
1032 fTargetPos.SetXYZ(targetX, targetY, targetZ);
1036 cout <<
"-W- " << GetName() <<
"::GetGeometry: No passive geometry!"
1043 cout <<
"-E- " << GetName() <<
"::GetGeometry: No STS node array"
1048 Int_t tempNofStations = stsNodes->GetEntries();
1051 cout <<
"There are " << tempNofStations <<
" nodes"
1052 << (tempNofStations > 10 ?
"!!!" :
"" ) << endl;
1054 TString geoNodeName;
1056 TString stationNames[100];
1057 Bool_t stationKnown = kFALSE;
1059 for ( Int_t istat = 0 ; istat < 20 ; istat++ )
1060 fNSectors[istat] = 0;
1062 for ( Int_t ist = 0 ; ist < tempNofStations ; ist++ ) {
1064 FairGeoNode* stsNode = (FairGeoNode*)stsNodes->At(ist);
1066 cout <<
"-W- CbmStsDigiScheme::Init: station#" << ist
1067 <<
" not found among sensitive nodes " << endl;
1070 geoNodeName = stsNode->GetName();
1073 stationKnown = kFALSE;
1075 FairGeoVector* pt1 = stsNode->getPoint(0);
1076 FairGeoVector* pt2 = stsNode->getPoint(1);
1077 Double_t sectorWidth = TMath::Abs(pt1->getX()-pt2->getX());
1081 for ( Int_t ikst = 0 ; ikst < fNStations ; ikst++ )
1082 if ( geoNodeName.Contains(stationNames[ikst]) ) {
1083 fStationNrFromMcId[stsNode->getMCid()] = ikst;
1084 stationKnown = kTRUE;
1085 fWidthSectors[ikst][fNSectors[ikst]] = sectorWidth;
1089 if ( stationKnown )
continue;
1092 fStationNrFromMcId[stsNode->getMCid()] = fNStations;
1093 fWidthSectors[fNStations][fNSectors[fNStations]] = sectorWidth;
1094 fNSectors[fNStations]++;
1099 geoNodeName.Remove(12,geoNodeName.Length()-12);
1100 stationNames[fNStations] = geoNodeName.Data();
1104 cout <<
"station #" << fNStations <<
" has MCID = "
1105 << stsNode->getMCid() <<
" and name " << stsNode->GetName() << endl;
1109 cout <<
" Stations: " << fNStations <<
" contain" << flush;
1110 for ( Int_t istat = 0 ; istat < fNStations ; istat++ )
1111 cout <<
" " << fNSectors[istat] << flush;
1112 cout <<
" sensors" << endl;
1120void CbmStsReconstructionQa::CreateHistos() {
1123 fHistoList =
new TList();
1127 Double_t minMom = 0.;
1128 Double_t maxMom = 10.;
1129 Int_t nBinsMom = 40;
1130 fhMomAccAll =
new TH1F(
"hMomAccAll",
"all reconstructable tracks",
1131 nBinsMom, minMom, maxMom);
1132 fhMomRecAll =
new TH1F(
"hMomRecAll",
"all reconstructed tracks",
1133 nBinsMom, minMom, maxMom);
1134 fhMomEffAll =
new TH1F(
"hMomEffAll",
"efficiency all tracks",
1135 nBinsMom, minMom, maxMom);
1136 fhMomEffAll->SetXTitle(
"p [GeV/c]");
1137 fhMomEffAll->SetYTitle(
"efficiency");
1138 fhMomAccPrim =
new TH1F(
"hMomAccPrim",
"reconstructable vertex tracks",
1139 nBinsMom, minMom, maxMom);
1140 fhMomRecPrim =
new TH1F(
"hMomRecPrim",
"reconstructed vertex tracks",
1141 nBinsMom, minMom, maxMom);
1142 fhMomEffPrim =
new TH1F(
"hMomEffPrim",
"efficiency vertex tracks",
1143 nBinsMom, minMom, maxMom);
1144 fhMomAccSec =
new TH1F(
"hMomAccSec",
"reconstructable non-vertex tracks",
1145 nBinsMom, minMom, maxMom);
1146 fhMomRecSec =
new TH1F(
"hMomRecSec",
"reconstructed non-vertex tracks",
1147 nBinsMom, minMom, maxMom);
1148 fhMomEffSec =
new TH1F(
"hMomEffSec",
"efficiency non-vertex tracks",
1149 nBinsMom, minMom, maxMom);
1150 fhMomGhosts =
new TH1F(
"hMomGhosts",
"momenta of ghosts",
1151 nBinsMom, minMom, maxMom);
1152 fhMomClones =
new TH1F(
"hMomClones",
"momenta of clones",
1153 nBinsMom, minMom, maxMom);
1154 fHistoList->Add(fhMomAccAll);
1155 fHistoList->Add(fhMomRecAll);
1156 fHistoList->Add(fhMomEffAll);
1157 fHistoList->Add(fhMomAccPrim);
1158 fHistoList->Add(fhMomRecPrim);
1159 fHistoList->Add(fhMomEffPrim);
1160 fHistoList->Add(fhMomAccSec);
1161 fHistoList->Add(fhMomRecSec);
1162 fHistoList->Add(fhMomEffSec);
1163 fHistoList->Add(fhMomClones);
1164 fHistoList->Add(fhMomGhosts);
1200 for ( Int_t itemp = 0 ; itemp < 10 ; itemp++ ) {
1201 if ( fPartPdgTable[itemp] == -7777 )
break;
1203 cout <<
"fpart pdg table content for itemp = " << itemp
1204 <<
" equals " << fPartPdgTable[itemp] << endl;
1205 fhMomAccPart[itemp] =
new TH1F(Form(
"hMomAccPart%s%d",(fPartPdgTable[itemp]>0?
"P":
"M"),TMath::Abs(fPartPdgTable[itemp])),
1206 Form(
"reconstruable particle%d tracks",fPartPdgTable[itemp]),
1207 nBinsMom, minMom, maxMom);
1208 fhMomRecPart[itemp] =
new TH1F(Form(
"hMomRecPart%s%d",(fPartPdgTable[itemp]>0?
"P":
"M"),TMath::Abs(fPartPdgTable[itemp])),
1209 Form(
"reconstructed particle%d tracks",fPartPdgTable[itemp]),
1210 nBinsMom, minMom, maxMom);
1211 fhMomEffPart[itemp] =
new TH1F(Form(
"hMomEffPart%s%d",(fPartPdgTable[itemp]>0?
"P":
"M"),TMath::Abs(fPartPdgTable[itemp])),
1212 Form(
"efficiency particle%d tracks",fPartPdgTable[itemp]),
1213 nBinsMom, minMom, maxMom);
1214 fHistoList->Add(fhMomAccPart[itemp]);
1215 fHistoList->Add(fhMomRecPart[itemp]);
1216 fHistoList->Add(fhMomEffPart[itemp]);
1221 Double_t minNp = -0.5;
1222 Double_t maxNp = 15.5;
1224 fhNpAccAll =
new TH1F(
"hNpAccAll",
"all reconstructable tracks",
1225 nBinsNp, minNp, maxNp);
1226 fhNpRecAll =
new TH1F(
"hNpRecAll",
"all reconstructed tracks",
1227 nBinsNp, minNp, maxNp);
1228 fhNpEffAll =
new TH1F(
"hNpEffAll",
"efficiency all tracks",
1229 nBinsNp, minNp, maxNp);
1230 fhNpAccPrim =
new TH1F(
"hNpAccPrim",
"reconstructable vertex tracks",
1231 nBinsNp, minNp, maxNp);
1232 fhNpRecPrim =
new TH1F(
"hNpRecPrim",
"reconstructed vertex tracks",
1233 nBinsNp, minNp, maxNp);
1234 fhNpEffPrim =
new TH1F(
"hNpEffPrim",
"efficiency vertex tracks",
1235 nBinsNp, minNp, maxNp);
1236 fhNpAccSec =
new TH1F(
"hNpAccSec",
"reconstructable non-vertex tracks",
1237 nBinsNp, minNp, maxNp);
1238 fhNpRecSec =
new TH1F(
"hNpRecSec",
"reconstructed non-vertex tracks",
1239 nBinsNp, minNp, maxNp);
1240 fhNpEffSec =
new TH1F(
"hNpEffSec",
"efficiency non-vertex tracks",
1241 nBinsNp, minNp, maxNp);
1242 fHistoList->Add(fhNpAccAll);
1243 fHistoList->Add(fhNpRecAll);
1244 fHistoList->Add(fhNpEffAll);
1245 fHistoList->Add(fhNpAccPrim);
1246 fHistoList->Add(fhNpRecPrim);
1247 fHistoList->Add(fhNpEffPrim);
1248 fHistoList->Add(fhNpAccSec);
1249 fHistoList->Add(fhNpRecSec);
1250 fHistoList->Add(fhNpEffSec);
1254 Double_t maxZ = 50.;
1256 fhZAccSec =
new TH1F(
"hZAccSec",
"reconstructable non-vertex tracks",
1257 nBinsZ, minZ, maxZ);
1258 fhZRecSec =
new TH1F(
"hZRecSecl",
"reconstructed non-vertex tracks",
1259 nBinsZ, minZ, maxZ);
1260 fhZEffSec =
new TH1F(
"hZEffRec",
"efficiency non-vertex tracks",
1261 nBinsZ, minZ, maxZ);
1262 fHistoList->Add(fhZAccSec);
1263 fHistoList->Add(fhZRecSec);
1264 fHistoList->Add(fhZEffSec);
1267 fhNhClones =
new TH1F(
"hNhClones",
"number of hits for clones",
1268 nBinsNp, minNp, maxNp);
1269 fhNhGhosts =
new TH1F(
"hNhGhosts",
"number of hits for ghosts",
1270 nBinsNp, minNp, maxNp);
1271 fhNhGhosts->SetXTitle(
"# of hits");
1272 fhNhGhosts->SetYTitle(
"yield [a.u.]");
1273 fHistoList->Add(fhNhClones);
1274 fHistoList->Add(fhNhGhosts);
1276 fhMomResAll =
new TH2F(
"hMomResAll",
"momentum resolution vs p for all tracks",
1277 nBinsMom,minMom,maxMom,
1279 fhMomResPrim =
new TH2F(
"hMomResPrim",
"momentum resolution vs p for vertex tracks",
1280 nBinsMom,minMom,maxMom,
1282 fhMomResPrim->SetXTitle(
"p [GeV/c]");
1283 fhMomResPrim->SetYTitle(
"#delta p/p [%%]");
1284 fhMomResSec =
new TH2F(
"hMomResSec",
"momentum resolution vs p for non-vertex tracks",
1285 nBinsMom,minMom,maxMom,
1287 fHistoList->Add(fhMomResAll);
1288 fHistoList->Add(fhMomResPrim);
1289 fHistoList->Add(fhMomResSec);
1290 fhLowBand =
new TH1F(
"hLowBand",
"Lower Band",nBinsMom,minMom,maxMom);
1291 fhHigBand =
new TH1F(
"hHigBand",
"Higher band",nBinsMom,minMom,maxMom);
1292 fHistoList->Add(fhLowBand);
1293 fHistoList->Add(fhHigBand);
1304 fhPrimaryVertex =
new TH3F(
"hPrimaryVertex",
"Primary vertex",200,-0.1,0.1,200,-0.1,0.1,200,-0.1,0.1);
1305 fHistoList->Add(fhPrimaryVertex);
1307 fhRefTracks =
new TH1F (
"hRefTracks" ,
"Nof reconstructed reference tracks",100,-0.5,999.5);
1308 fhRecRefTracks =
new TH1F (
"hRecRefTracks",
"Nof reconstruable reference tracks",100,-0.5,999.5);
1309 fHistoList->Add(fhRefTracks);
1310 fHistoList->Add(fhRecRefTracks);
1312 Char_t lett[5] = {
'X',
'Y',
'Z',
'x',
'y'};
1314 for ( Int_t itemp = 0 ; itemp < 15 ; itemp++ ) {
1355 if ( itemp >= 3 )
continue;
1357 Double_t beg = -50.;
1359 if ( itemp == 2 ) { nof = 120; beg = -10.; end = 110.; }
1360 fhStsTrackFPos[itemp] =
new TH1F(Form(
"hStsTrackFPos%c",lett[itemp]),
1361 Form(
"StsTrack ParamFirst pos %c",lett[itemp]),
1363 fhStsTrackLPos[itemp] =
new TH1F(Form(
"hStsTrackLPos%c",lett[itemp]),
1364 Form(
"StsTrack ParamLast pos %c",lett[itemp]),
1366 fHistoList->Add(fhStsTrackFPos[itemp]);
1367 fHistoList->Add(fhStsTrackLPos[itemp]);
1369 if ( itemp >= 2 )
continue;
1370 fhStsTrackFDir[itemp] =
new TH1F(Form(
"hStsTrackFDir%c",lett[itemp+3]),
1371 Form(
"StsTrack ParamFirst dir %c",lett[itemp+3]),
1373 fhStsTrackLDir[itemp] =
new TH1F(Form(
"hStsTrackLDir%c",lett[itemp+3]),
1374 Form(
"StsTrack ParamLast dir %c",lett[itemp+3]),
1376 fHistoList->Add(fhStsTrackFDir[itemp]);
1377 fHistoList->Add(fhStsTrackLDir[itemp]);
1379 fhStsTrackFMom =
new TH1F(
"hStsTrackFMom",
"Momentum of rec. tracks ParFirst", 100,-50.,50.);
1380 fhStsTrackLMom =
new TH1F(
"hStsTrackLMom",
"Momentum of rec. tracks ParLast" , 100,-50.,50.);
1381 fhStsTrackChiSq =
new TH1F(
"hStsTrackChiSq",
"Chi square of rec. tracks",100,0.,1000.);
1382 fHistoList->Add(fhStsTrackFMom);
1383 fHistoList->Add(fhStsTrackLMom);
1384 fHistoList->Add(fhStsTrackChiSq);
1443void CbmStsReconstructionQa::Reset() {
1445 TIter next(fHistoList);
1446 while ( TH1* histo = ((TH1*)next()) ) histo->Reset();
1447 TIter next0(fOccupHList);
1448 while ( TH1* histo = ((TH1*)next0()) ) histo->Reset();
1450 fNAccAll = fNAccPrim = fNAccRef = fNAccSec = 0;
1451 fNRecAll = fNRecPrim = fNRecRef = fNRecSec = 0;
1452 fNGhosts = fNClones = fNEvents = 0;
1459void CbmStsReconstructionQa::FillHitMap() {
1461 Int_t nMC = fMCTracks->GetEntriesFast();
1462 for (Int_t
i=0;
i<nMC;
i++) {
1463 for (Int_t j=0; j<10; j++){
1467 Int_t nHits = fStsHits->GetEntriesFast();
1468 for (Int_t iHit=0; iHit<nHits; iHit++) {
1470 Int_t iMc = hit->GetRefIndex();
1471 if ( iMc < 0 )
continue;
1473 Int_t iTrack = stsPoint->GetTrackID();
1482void CbmStsReconstructionQa::FillMatchMap(Int_t& nRec, Int_t& nGhosts,
1492 nRec = fStsTracks->GetEntriesFast();
1493 Int_t nMtc = fMatches->GetEntriesFast();
1494 if ( nMtc != nRec ) {
1495 cout <<
"-E- " << GetName() <<
"::Exec: Number of StsMatches ("
1496 << nMtc <<
") does not equal number of StsTracks ("
1497 << nRec <<
")" << endl;
1498 Fatal(
"Exec",
"Inequal number of StsTrack and StsTrackMatch");
1500 for (Int_t iRec=0; iRec<nRec; iRec++) {
1504 cout <<
"-E- " << GetName() <<
"::Exec: "
1505 <<
"No StsTrack at index " << iRec << endl;
1506 Fatal(
"Exec",
"No StsTrack in array");
1510 FairTrackParam* trParF = (FairTrackParam*)stsTrack->
GetParamFirst();
1511 FairTrackParam* trParL = (FairTrackParam*)stsTrack->
GetParamLast();
1512 fhStsTrackFPos[0]->Fill(trParF->GetX());
1513 fhStsTrackFPos[1]->Fill(trParF->GetY());
1514 fhStsTrackFPos[2]->Fill(trParF->GetZ());
1515 fhStsTrackLPos[0]->Fill(trParL->GetX());
1516 fhStsTrackLPos[1]->Fill(trParL->GetY());
1517 fhStsTrackLPos[2]->Fill(trParL->GetZ());
1518 fhStsTrackFDir[0]->Fill(trParF->GetTx());fhStsTrackFDir[1]->Fill(trParF->GetTy());
1519 fhStsTrackLDir[0]->Fill(trParL->GetTx());fhStsTrackLDir[1]->Fill(trParL->GetTy());
1521 for ( Int_t ixx = 0 ; ixx < 5 ; ixx++ ) {
1522 for ( Int_t iyy = ixx ; iyy < 5 ; iyy++ ) {
1528 fhStsTrackFMom->Fill(trParF->GetQp());
1529 fhStsTrackLMom->Fill(trParL->GetQp());
1530 fhStsTrackChiSq->Fill(stsTrack->
GetChi2());
1534 cout <<
"-E- " << GetName() <<
"::Exec: "
1535 <<
"No StsTrackMatch at index " << iRec << endl;
1536 Fatal(
"Exec",
"No StsTrackMatch in array");
1538 Int_t nTrue =
match->GetNofTrueHits();
1540 Int_t iMC =
match->GetMCTrackId();
1543 cout <<
"-I- " << GetName() <<
":"
1544 <<
"No MC match for StsTrack " << iRec << endl;
1545 fhNhGhosts->Fill(nHits);
1547 fhMomGhosts->Fill(1./TMath::Abs(stsTrack->
GetParamFirst()->GetQp()));
1553 Double_t quali = 1.;
1555 quali = Double_t(nTrue) / Double_t(nHits);
1556 if ( quali >= fQuota ) {
1559 if ( fMatchMap.find(iMC) == fMatchMap.end() ) {
1560 fMatchMap[iMC] = iRec;
1561 fQualiMap[iMC] = quali;
1567 cout <<
"-I- " << GetName() <<
": "
1568 <<
"MCTrack " << iMC <<
" doubly matched."
1569 <<
"Current match " << iRec
1570 <<
", previous match " << fMatchMap[iMC]
1572 if ( fQualiMap[iMC] < quali ) {
1575 fhNhClones->Fill(Double_t(oldTrack->
GetNStsHits()));
1577 fhMomClones->Fill(1./TMath::Abs(oldTrack->
GetParamFirst()->GetQp()));
1578 fMatchMap[iMC] = iRec;
1579 fQualiMap[iMC] = quali;
1582 fhNhClones->Fill(nHits);
1584 fhMomClones->Fill(1./TMath::Abs(stsTrack->
GetParamFirst()->GetQp()));
1594 cout <<
"-I- " << GetName() <<
":"
1595 <<
"StsTrack " << iRec <<
" below matching criterion "
1596 <<
"(" << quali <<
")" << endl;
1597 fhNhGhosts->Fill(nHits);
1599 fhMomGhosts->Fill(1./TMath::Abs(stsTrack->
GetParamFirst()->GetQp()));
1609void CbmStsReconstructionQa::DivideHistos(TH1* histo1, TH1* histo2,
1612 if ( !histo1 || !histo2 || !histo3 ) {
1613 cout <<
"-E- " << GetName() <<
"::DivideHistos: "
1614 <<
"NULL histogram pointer" << endl;
1615 Fatal(
"DivideHistos",
"Null histo pointer");
1618 Int_t nBins = histo1->GetNbinsX();
1619 if ( histo2->GetNbinsX() != nBins || histo3->GetNbinsX() != nBins ) {
1620 cout <<
"-E- " << GetName() <<
"::DivideHistos: "
1621 <<
"Different bin numbers in histos" << endl;
1622 cout << histo1->GetName() <<
" " << histo1->GetNbinsX() << endl;
1623 cout << histo2->GetName() <<
" " << histo2->GetNbinsX() << endl;
1624 cout << histo3->GetName() <<
" " << histo3->GetNbinsX() << endl;
1628 Double_t c1, c2, c3, ce;
1629 for (Int_t iBin=0; iBin<nBins; iBin++) {
1630 c1 = histo1->GetBinContent(iBin);
1631 c2 = histo2->GetBinContent(iBin);
1635 ce = TMath::Sqrt( c3 * ( 1. - c3 ) / c2 );
1637 ce = TMath::Sqrt( c3 * ( 1. + c3 ) / c2 );
1643 histo3->SetBinContent(iBin, c3);
1644 histo3->SetBinError(iBin, ce);
TObjArray * GetGeoSensitiveNodes()
void GetMomentum(TVector3 &momentum) const
void GetStartVertex(TVector3 &vertex) const
Int_t GetSectorNr() const
Int_t GetChannelNr() const
Int_t GetStationNr() const
virtual Int_t GetStationNr() const
Int_t GetSectorNr() const
virtual void Exec(Option_t *opt)
virtual void SetParContainers()
virtual InitStatus ReInit()
virtual InitStatus Init()
CbmStsReconstructionQa(Int_t iVerbose=1)
virtual ~CbmStsReconstructionQa()
FairTrackParam * GetParamLast()
Int_t GetNStsHits() const
FairTrackParam * GetParamFirst()
TObjArray * GetGeoPassiveNodes()