CbmRoot
Loading...
Searching...
No Matches
CbmStsFindTracksQa.cxx
Go to the documentation of this file.
1/* Copyright (C) 2006-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergey Gorbunov, Denis Bertini [committer], Volker Friese, Florian Uhlig */
4
5// -------------------------------------------------------------------------
6// ----- CbmStsFindTracksQa source file -----
7// ----- Created 11/01/06 by V. Friese -----
8// -------------------------------------------------------------------------
9
10// Includes class header
11#include "CbmStsFindTracksQa.h"
12
13// Includes from C++
14#include <cassert>
15#include <iomanip>
16
17// Includes from ROOT
18#include "TClonesArray.h"
19#include "TGeoManager.h"
20#include "TH1F.h"
21
22// Includes from FairRoot
23#include "FairEventHeader.h"
24#include "FairRun.h"
25
26#include <Logger.h>
27
28// Includes from CbmRoot
29#include "CbmMCDataArray.h"
30#include "CbmMCDataManager.h"
31#include "CbmMCTrack.h"
32#include "CbmMvdDetector.h"
33#include "CbmMvdHit.h"
34#include "CbmMvdPoint.h"
35#include "CbmMvdStationPar.h"
36#include "CbmStsHit.h"
37#include "CbmStsPoint.h"
38#include "CbmStsSetup.h"
39#include "CbmStsTrack.h"
40#include "CbmTimeSlice.h"
41#include "CbmTrackMatchNew.h"
42#include "FairRunAna.h"
43
44using std::fixed;
45using std::right;
46using std::setprecision;
47using std::setw;
48
49
50// ----- Default constructor -------------------------------------------
51CbmStsFindTracksQa::CbmStsFindTracksQa(Int_t iVerbose) : FairTask("STSFindTracksQA", iVerbose) {}
52
53// -------------------------------------------------------------------------
54
55
56// ----- Standard constructor ------------------------------------------
57CbmStsFindTracksQa::CbmStsFindTracksQa(Int_t minStations, Double_t quota, Int_t iVerbose)
58 : FairTask("STSFindTracksQA", iVerbose)
59 , fMinStations(minStations)
60 , fQuota(quota)
61{
62}
63// -------------------------------------------------------------------------
64
65
66// ----- Destructor ----------------------------------------------------
73// -------------------------------------------------------------------------
74
75
76// ----- Task execution ------------------------------------------------
77void CbmStsFindTracksQa::Exec(Option_t* /*opt*/)
78{
79
80 LOG(debug) << GetName() << ": Process event ";
81
82 // Timer
83 fTimer.Start();
84
85 // Eventwise counters
86 // Int_t nMCTracks = 0;
87 Int_t nTracks = 0;
88 Int_t nGhosts = 0;
89 Int_t nClones = 0;
90 Int_t nAll = 0;
91 Int_t nAcc = 0;
92 Int_t nRecAll = 0;
93 Int_t nPrim = 0;
94 Int_t nRecPrim = 0;
95 Int_t nRef = 0;
96 Int_t nRecRef = 0;
97 Int_t nRefLong = 0;
98 Int_t nRecRefLong = 0;
99 Int_t nSec = 0;
100 Int_t nRecSec = 0;
101 TVector3 momentum;
102 TVector3 vertex;
103
104 // check consistency
105 assert(fStsTracks->GetEntriesFast() == fStsTrackMatches->GetEntriesFast());
106
107 {
108 fMcTrackInfoMap.clear();
109 std::vector<CbmLink> events = fTimeSlice->GetMatch().GetLinks();
110 std::sort(events.begin(), events.end());
111 McTrackInfo info;
112 for (uint iLink = 0; iLink < events.size(); iLink++) {
113 CbmLink link = events[iLink];
114 Int_t nMCTracks = fMCTracks->Size(link);
115 for (Int_t iTr = 0; iTr < nMCTracks; iTr++) {
116 link.SetIndex(iTr);
117 fMcTrackInfoMap.insert({link, info});
118 }
119 }
120 }
121
122 // Fill hit and track maps
123 FillHitMap();
124 FillMatchMap(nTracks, nGhosts, nClones);
125
126 int nMcTracks = fMcTrackInfoMap.size();
127
128 // Loop over MCTracks
129 int iMcTrack = 0;
130 for (auto itTrack = fMcTrackInfoMap.begin(); itTrack != fMcTrackInfoMap.end(); ++itTrack, ++iMcTrack) {
131 const CbmLink& link = itTrack->first;
132 McTrackInfo& info = itTrack->second;
133 CbmMCTrack* mcTrack = dynamic_cast<CbmMCTrack*>(fMCTracks->Get(link));
134 assert(mcTrack);
135
136 // Continue only for reconstructible tracks
137 nAll++;
138 Int_t nStations = info.fHitMap.size();
139 if (nStations < fMinStations) continue; // Too few stations
140
141 int nContStations = 0; // Number of continious stations
142 {
143 int istaprev = -1;
144 int len = 0;
145 for (auto itSta = info.fHitMap.begin(); itSta != info.fHitMap.end(); itSta++) {
146 if (len == 0 || itSta->first == istaprev + 1) {
147 len++;
148 }
149 else {
150 len = 1;
151 }
152 if (nContStations < len) {
153 nContStations = len;
154 }
155 istaprev = itSta->first;
156 }
157 }
158 if (nContStations < fMinStations) continue; // Too few stations
159
160 nAcc++;
161
162 // Check origin of MCTrack
163 // TODO: Track origin should rather be compared to MC event vertex
164 // But that is not available from MCDataManager
165 mcTrack->GetStartVertex(vertex);
166 Bool_t isPrim = kFALSE;
167 if (TMath::Abs(vertex.Z() - fTargetPos.Z()) < 1.) {
168 isPrim = kTRUE;
169 nPrim++;
170 }
171 else
172 nSec++;
173
174 // Get momentum
175 mcTrack->GetMomentum(momentum);
176 Double_t mom = momentum.Mag();
177 Bool_t isRef = kFALSE;
178 if (mom > 1. && isPrim) {
179 isRef = kTRUE;
180 nRef++;
181 }
182
183 Bool_t isRefLong = kFALSE;
184 if (isRef && nContStations >= fStsNstations) {
185 isRefLong = kTRUE;
186 nRefLong++;
187 }
188
189 // Fill histograms for reconstructible tracks
190 fhMomAccAll->Fill(mom);
191 fhNpAccAll->Fill(Double_t(nStations));
192 if (isPrim) {
193 fhMomAccPrim->Fill(mom);
194 fhNpAccPrim->Fill(Double_t(nStations));
195 }
196 else {
197 fhMomAccSec->Fill(mom);
198 fhNpAccSec->Fill(Double_t(nStations));
199 fhZAccSec->Fill(vertex.Z());
200 }
201
202 // Get matched StsTrack
203 Int_t trackId = info.fStsTrackMatch;
204 Double_t quali = info.fQuali;
205 // Bool_t isRec = kFALSE;
206 if (trackId >= 0) {
207 // isRec = kTRUE;
208 CbmStsTrack* stsTrack = (CbmStsTrack*) fStsTracks->At(trackId);
209 assert(stsTrack);
210 assert(quali >= fQuota);
211 CbmTrackMatchNew* match = (CbmTrackMatchNew*) fStsTrackMatches->At(trackId);
212 assert(match);
213 Int_t nTrue = match->GetNofTrueHits();
214 Int_t nWrong = match->GetNofWrongHits();
215 //Int_t nFake = match->GetNofFakeHits();
216 Int_t nFake = 0;
217 Int_t nAllHits = stsTrack->GetNofStsHits() + stsTrack->GetNofMvdHits();
218 if (!fIsMvdActive) {
219 assert(stsTrack->GetNofMvdHits() == 0);
220 }
221 assert(nTrue + nWrong + nFake == nAllHits);
222 // Verbose output
223 LOG(debug1) << GetName() << ": MCTrack " << iMcTrack << ", stations " << nStations << ", hits " << nAllHits
224 << ", true hits " << nTrue;
225
226 // Fill histograms for reconstructed tracks
227 nRecAll++;
228 fhMomRecAll->Fill(mom);
229 fhNpRecAll->Fill(Double_t(nAllHits));
230 if (isPrim) {
231 nRecPrim++;
232 fhMomRecPrim->Fill(mom);
233 fhNpRecPrim->Fill(Double_t(nAllHits));
234 }
235 else {
236 nRecSec++;
237 fhMomRecSec->Fill(mom);
238 fhNpRecSec->Fill(Double_t(nAllHits));
239 fhZRecSec->Fill(vertex.Z());
240 }
241 if (isRef) nRecRef++;
242 if (isRefLong) nRecRefLong++;
243
244 } // Match found in map?
245
246 } // Loop over MCTracks
247
248 // Calculate efficiencies
249 Double_t effAll = Double_t(nRecAll) / Double_t(nAcc);
250 Double_t effPrim = Double_t(nRecPrim) / Double_t(nPrim);
251 Double_t effRef = Double_t(nRecRef) / Double_t(nRef);
252 Double_t effRefLong = Double_t(nRecRefLong) / Double_t(nRefLong);
253 Double_t effSec = Double_t(nRecSec) / Double_t(nSec);
254
255 fTimer.Stop();
256
257
258 // Event summary
259 LOG(info) << "+ " << setw(20) << GetName() << ": Event " << setw(6) << right << fNEvents << ", real time " << fixed
260 << setprecision(6) << fTimer.RealTime() << " s, MC tracks: all " << nMcTracks << ", acc. " << nAcc
261 << ", rec. " << nRecAll << ", eff. " << setprecision(2) << 100. * effAll << " %";
262 if (fair::Logger::Logging(fair::Severity::debug)) {
263 LOG(debug) << "---------- StsFindTracksQa : Event summary ------------";
264 LOG(debug) << "MCTracks : " << nAll << ", reconstructible: " << nAcc << ", reconstructed: " << nRecAll;
265 LOG(debug) << "Vertex : reconstructible: " << nPrim << ", reconstructed: " << nRecPrim << ", efficiency "
266 << effPrim * 100. << "%";
267 LOG(debug) << "Reference : reconstructible: " << nRef << ", reconstructed: " << nRecRef << ", efficiency "
268 << effRef * 100. << "%";
269 LOG(debug) << "Reference long : reconstructible: " << nRefLong << ", reconstructed: " << nRecRefLong
270 << ", efficiency " << effRefLong * 100. << "%";
271 LOG(debug) << "Non-vertex : reconstructible: " << nSec << ", reconstructed: " << nRecSec << ", efficiency "
272 << effSec * 100. << "%";
273 LOG(debug) << "STSTracks " << nTracks << ", ghosts " << nGhosts << ", clones " << nClones;
274 LOG(debug) << "-----------------------------------------------------------\n";
275 }
276
277
278 // Increase counters
279 fNAll += nAll;
280 fNAccAll += nAcc;
281 fNAccPrim += nPrim;
282 fNAccRef += nRef;
283 fNAccRefLong += nRefLong;
284 fNAccSec += nSec;
285 fNRecAll += nRecAll;
286 fNRecPrim += nRecPrim;
287 fNRecRef += nRecRef;
288 fNRecRefLong += nRecRefLong;
289 fNRecSec += nRecSec;
290 fNGhosts += nGhosts;
291 fNClones += nClones;
292 fNEvents++;
293 fTime += fTimer.RealTime();
294}
295// -------------------------------------------------------------------------
296
297
298// ----- Public method SetParContainers --------------------------------
300// -------------------------------------------------------------------------
301
302
303// ----- Public method Init --------------------------------------------
305{
306
307 LOG(info) << "\n\n====================================================";
308 LOG(info) << GetName() << ": Initialising...";
309
310 // Get STS setup
312 assert(fStsSetup);
313 if (!fStsSetup->IsInit()) {
314 fStsSetup->Init();
315 }
316
317 fManager = FairRootManager::Instance();
318 assert(fManager);
319
320 fMcManager = dynamic_cast<CbmMCDataManager*>(fManager->GetObject("MCDataManager"));
321
322 assert(fMcManager);
323
324 fTimeSlice = static_cast<CbmTimeSlice*>(fManager->GetObject("TimeSlice."));
325
326 if (fTimeSlice == nullptr) {
327 LOG(fatal) << "CbmStsFindTracksQa: No time slice object";
328 }
329
330 if (fMcManager) {
331 fMCTracks = fMcManager->InitBranch("MCTrack");
332 fStsPoints = fMcManager->InitBranch("StsPoint");
333 }
334
335 assert(fMCTracks);
336 assert(fStsPoints);
337
338 // Get the geometry
339 InitStatus geoStatus = GetGeometry();
340 if (geoStatus != kSUCCESS) {
341 LOG(error) << GetName() << "::Init: Error in reading geometry!";
342 return geoStatus;
343 }
344
345 // MVD
346
347 fMvdPoints = fMcManager->InitBranch("MvdPoint");
348 fMvdCluster = (TClonesArray*) (fManager->GetObject("MvdCluster"));
349 fMvdHits = (TClonesArray*) (fManager->GetObject("MvdHit"));
350 fMvdHitMatch = (TClonesArray*) fManager->GetObject("MvdHitMatch");
351
352 // Currently in the time-based mode MVD is present but not reconstructed
353 // TODO: remove the check once the reconstruction works
354 if (fIsMvdActive && !fMvdHits) {
355 LOG(warning) << "CbmStsFindTracksQa: MVD hits are missing, MVD will not be "
356 "included to the STS track match";
357 fIsMvdActive = false;
358 }
359
360 if (fIsMvdActive) {
361 assert(fMvdPoints);
362 assert(fMvdCluster);
363 assert(fMvdHits);
364 assert(fMvdHitMatch);
365 }
366
367 // STS
368
369 // Get StsHit array
370 fStsHits = (TClonesArray*) fManager->GetObject("StsHit");
371 assert(fStsHits);
372
373 // Get StsHitMatch array
374 fStsHitMatch = (TClonesArray*) fManager->GetObject("StsHitMatch");
375 assert(fStsHitMatch);
376
377 // Get StsHitMatch array
378 fStsClusterMatch = (TClonesArray*) fManager->GetObject("StsClusterMatch");
379 assert(fStsClusterMatch);
380
381 // Get StsTrack array
382 fStsTracks = (TClonesArray*) fManager->GetObject("StsTrack");
383 assert(fStsTracks);
384
385 // Get StsTrackMatch array
386 fStsTrackMatches = (TClonesArray*) fManager->GetObject("StsTrackMatch");
387 assert(fStsTrackMatches);
388
389
390 // Create histograms
391 CreateHistos();
392 Reset();
393
394 // Output
395 LOG(info) << " Number of STS stations : " << fStsNstations;
396 LOG(info) << " Target position ( " << fTargetPos.X() << ", " << fTargetPos.Y() << ", " << fTargetPos.Z() << ") cm";
397 LOG(info) << " Minimum number of STS stations : " << fMinStations;
398 LOG(info) << " Matching quota : " << fQuota;
399 LOG(info) << "====================================================";
400
401 return geoStatus;
402}
403// -------------------------------------------------------------------------
404
405
406// ----- Public method ReInit ------------------------------------------
408{
409
410 LOG(info) << "\n\n====================================================";
411 LOG(info) << GetName() << ": Re-initialising...";
412
413 // Get the geometry of target and STS
414 InitStatus geoStatus = GetGeometry();
415 if (geoStatus != kSUCCESS) {
416 LOG(error) << GetName() << "::Init: Error in reading geometry!";
417 return geoStatus;
418 }
419
420 // --- Screen log
421 LOG(info) << " Number of STS stations : " << fStsNstations;
422 LOG(info) << " Target position ( " << fTargetPos.X() << ", " << fTargetPos.Y() << ", " << fTargetPos.Z() << ") cm";
423 LOG(info) << " Minimum number of STS stations : " << fMinStations;
424 LOG(info) << " Matching quota : " << fQuota;
425 LOG(info) << "====================================================";
426
427 return geoStatus;
428}
429// -------------------------------------------------------------------------
430
431
432// ----- Private method Finish -----------------------------------------
434{
435
436 // Divide histograms for efficiency calculation
444
445 // Normalise histos for clones and ghosts to one event
446 if (fNEvents) {
447 fhNhClones->Scale(1. / Double_t(fNEvents));
448 fhNhGhosts->Scale(1. / Double_t(fNEvents));
449 }
450
451 // Calculate integrated efficiencies and rates
452 Double_t effAll = Double_t(fNRecAll) / Double_t(fNAccAll);
453 Double_t effPrim = Double_t(fNRecPrim) / Double_t(fNAccPrim);
454 Double_t effRef = Double_t(fNRecRef) / Double_t(fNAccRef);
455 Double_t effRefLong = Double_t(fNRecRefLong) / Double_t(fNAccRefLong);
456 Double_t effSec = Double_t(fNRecSec) / Double_t(fNAccSec);
457 Double_t rateGhosts = Double_t(fNGhosts) / Double_t(fNRecAll);
458 Double_t rateClones = Double_t(fNClones) / Double_t(fNRecAll);
459
460 // Run summary to screen
461 std::cout << std::endl;
462 LOG(info) << "=====================================";
463 LOG(info) << fName << ": Run summary ";
464 LOG(info) << "Events processed : " << fNEvents << setprecision(2);
465 LOG(info) << "Eff. all tracks : " << effAll * 100 << " % (" << fNRecAll << "/" << fNAccAll << ")";
466 LOG(info) << "Eff. vertex tracks : " << effPrim * 100 << " % (" << fNRecPrim << "/" << fNAccPrim << ")";
467 LOG(info) << "Eff. reference tracks : " << effRef * 100 << " % (" << fNRecRef << "/" << fNAccRef << ")";
468 LOG(info) << "Eff. reference long tracks : " << effRefLong * 100 << " % (" << fNRecRefLong << "/" << fNAccRefLong
469 << ")";
470 LOG(info) << "Eff. secondary tracks : " << effSec * 100 << " % (" << fNRecSec << "/" << fNAccSec << ")";
471 LOG(info) << "Ghost rate : " << rateGhosts * 100 << " % (" << fNGhosts << "/" << fNRecAll << ")";
472 LOG(info) << "Clone rate : " << rateClones * 100 << " % (" << fNClones << "/" << fNRecAll << ")";
473 LOG(info) << "mc tracks/event " << fNAll / fNEvents << " accepted " << fNRecAll / fNEvents;
474 LOG(info) << "Time per event : " << setprecision(6) << fTime / Double_t(fNEvents) << " s";
475
476 if (fMvdNstations > 0 && !fIsMvdActive) {
477 LOG(warning) << "CbmStsFindTracksQa: MVD hits are missing, MVD is not "
478 "included to the STS track match";
479 }
480
481 LOG(info) << "=====================================";
482
483 // Write histos to output
484 /*
485 gDirectory->mkdir("STSFindTracksQA");
486 gDirectory->cd("STSFindTracksQA");
487 TIter next(fHistoList);
488 while (TH1* histo = ((TH1*) next()))
489 histo->Write();
490 gDirectory->cd("..");
491*/
492 FairSink* sink = FairRootManager::Instance()->GetSink();
493 sink->WriteObject(&fOutFolder, nullptr);
494}
495// -------------------------------------------------------------------------
496
497
498// ----- Private method GetGeometry ------------------------------------
500{
501 // Get target geometry
503 fMvdNstations = 0;
504 // CbmMvdDetector may issue an error when there is no MVD in the setup
505 // For now we determine the presence of MVD from the presence of the mvd hit branch
506 // TODO: use CbmSetup to determine if MVD is present
507 if (fManager->GetObject("MvdHit")) {
509 if (mvdDetector) {
510 CbmMvdStationPar* mvdStationPar = mvdDetector->GetParameterFile();
511 assert(mvdStationPar);
512 fMvdNstations = mvdStationPar->GetStationCount();
513 }
514 }
517 return kSUCCESS;
518}
519// -------------------------------------------------------------------------
520
521
522// ----- Get target node -----------------------------------------------
524{
525
526 TGeoNode* target = NULL;
527
528 gGeoManager->CdTop();
529 TGeoNode* cave = gGeoManager->GetCurrentNode();
530 for (Int_t iNode1 = 0; iNode1 < cave->GetNdaughters(); iNode1++) {
531 TString name = cave->GetDaughter(iNode1)->GetName();
532 if (name.Contains("pipe", TString::kIgnoreCase)) {
533 LOG(debug) << "Found pipe node " << name;
534 gGeoManager->CdDown(iNode1);
535 break;
536 }
537 }
538 for (Int_t iNode2 = 0; iNode2 < gGeoManager->GetCurrentNode()->GetNdaughters(); iNode2++) {
539 TString name = gGeoManager->GetCurrentNode()->GetDaughter(iNode2)->GetName();
540 if (name.Contains("pipevac1", TString::kIgnoreCase)) {
541 LOG(debug) << "Found vacuum node " << name;
542 gGeoManager->CdDown(iNode2);
543 break;
544 }
545 }
546 for (Int_t iNode3 = 0; iNode3 < gGeoManager->GetCurrentNode()->GetNdaughters(); iNode3++) {
547 TString name = gGeoManager->GetCurrentNode()->GetDaughter(iNode3)->GetName();
548 if (name.Contains("target", TString::kIgnoreCase)) {
549 LOG(debug) << "Found target node " << name;
550 gGeoManager->CdDown(iNode3);
551 target = gGeoManager->GetCurrentNode();
552 break;
553 }
554 }
555 if (!target) {
556 fTargetPos[0] = 0.;
557 fTargetPos[1] = 0.;
558 fTargetPos[2] = 0.;
559 }
560 else {
561 TGeoHMatrix* glbMatrix = gGeoManager->GetCurrentMatrix();
562 Double_t* pos = glbMatrix->GetTranslation();
563 fTargetPos[0] = pos[0];
564 fTargetPos[1] = pos[1];
565 fTargetPos[2] = pos[2];
566 }
567
568 gGeoManager->CdTop();
569}
570// -------------------------------------------------------------------------
571
572
573// ----- Private method CreateHistos -----------------------------------
575{
576
577 fOutFolder.Clear();
578
579 // Histogram list
580 fHistoList = new TList();
581
582 // Momentum distributions
583 Double_t minMom = 0.;
584 Double_t maxMom = 10.;
585 Int_t nBinsMom = 40;
586 fhMomAccAll = new TH1F("hMomAccAll", "all reconstructable tracks", nBinsMom, minMom, maxMom);
587 fhMomRecAll = new TH1F("hMomRecAll", "all reconstructed tracks", nBinsMom, minMom, maxMom);
588 fhMomEffAll = new TH1F("hMomEffAll", "efficiency all tracks", nBinsMom, minMom, maxMom);
589 fhMomAccPrim = new TH1F("hMomAccPrim", "reconstructable vertex tracks", nBinsMom, minMom, maxMom);
590 fhMomRecPrim = new TH1F("hMomRecPrim", "reconstructed vertex tracks", nBinsMom, minMom, maxMom);
591 fhMomEffPrim = new TH1F("hMomEffPrim", "efficiency vertex tracks", nBinsMom, minMom, maxMom);
592 fhMomAccSec = new TH1F("hMomAccSec", "reconstructable non-vertex tracks", nBinsMom, minMom, maxMom);
593 fhMomRecSec = new TH1F("hMomRecSec", "reconstructed non-vertex tracks", nBinsMom, minMom, maxMom);
594 fhMomEffSec = new TH1F("hMomEffSec", "efficiency non-vertex tracks", nBinsMom, minMom, maxMom);
604
605 // Number-of-points distributions
606 Double_t minNp = -0.5;
607 Double_t maxNp = 15.5;
608 Int_t nBinsNp = 16;
609 fhNpAccAll = new TH1F("hNpAccAll", "all reconstructable tracks", nBinsNp, minNp, maxNp);
610 fhNpRecAll = new TH1F("hNpRecAll", "all reconstructed tracks", nBinsNp, minNp, maxNp);
611 fhNpEffAll = new TH1F("hNpEffAll", "efficiency all tracks", nBinsNp, minNp, maxNp);
612 fhNpAccPrim = new TH1F("hNpAccPrim", "reconstructable vertex tracks", nBinsNp, minNp, maxNp);
613 fhNpRecPrim = new TH1F("hNpRecPrim", "reconstructed vertex tracks", nBinsNp, minNp, maxNp);
614 fhNpEffPrim = new TH1F("hNpEffPrim", "efficiency vertex tracks", nBinsNp, minNp, maxNp);
615 fhNpAccSec = new TH1F("hNpAccSec", "reconstructable non-vertex tracks", nBinsNp, minNp, maxNp);
616 fhNpRecSec = new TH1F("hNpRecSec", "reconstructed non-vertex tracks", nBinsNp, minNp, maxNp);
617 fhNpEffSec = new TH1F("hNpEffSec", "efficiency non-vertex tracks", nBinsNp, minNp, maxNp);
627
628 // z(vertex) distributions
629 Double_t minZ = 0.;
630 Double_t maxZ = 50.;
631 Int_t nBinsZ = 50;
632 fhZAccSec = new TH1F("hZAccSec", "reconstructable non-vertex tracks", nBinsZ, minZ, maxZ);
633 fhZRecSec = new TH1F("hZRecSecl", "reconstructed non-vertex tracks", nBinsZ, minZ, maxZ);
634 fhZEffSec = new TH1F("hZEffRec", "efficiency non-vertex tracks", nBinsZ, minZ, maxZ);
635 fHistoList->Add(fhZAccSec);
636 fHistoList->Add(fhZRecSec);
637 fHistoList->Add(fhZEffSec);
638
639 // Number-of-hit distributions
640 fhNhClones = new TH1F("hNhClones", "number of hits for clones", nBinsNp, minNp, maxNp);
641 fhNhGhosts = new TH1F("hNhGhosts", "number of hits for ghosts", nBinsNp, minNp, maxNp);
644
645 TIter next(fHistoList);
646 while (TH1* histo = ((TH1*) next())) {
647 fOutFolder.Add(histo);
648 }
649}
650// -------------------------------------------------------------------------
651
652
653// ----- Private method Reset ------------------------------------------
655{
656
657 TIter next(fHistoList);
658 while (TH1* histo = ((TH1*) next()))
659 histo->Reset();
660
663 fNGhosts = fNClones = fNEvents = 0;
664}
665// -------------------------------------------------------------------------
666
667
668// ----- Private method FillHitMap -------------------------------------
670{
671
672 // --- Fill hit map ( mcTrack -> ( station -> number of hits ) )
673
674 // pocess MVD hits
675
676 if (fIsMvdActive) {
677 assert(fMvdHits);
678 assert(fMvdHitMatch);
679 assert(fMvdPoints);
680 for (Int_t iHit = 0; iHit < fMvdHits->GetEntriesFast(); iHit++) {
681 CbmMvdHit* hit = (CbmMvdHit*) fMvdHits->At(iHit);
682 assert(hit);
683 Int_t station = hit->GetStationNr();
684 assert(station >= 0 && station < fMvdNstations);
685 const CbmMatch* match = (const CbmMatch*) fMvdHitMatch->At(iHit);
686 assert(match);
687 if (match->GetNofLinks() <= 0) continue;
688 CbmLink link = match->GetMatchedLink();
689 CbmMvdPoint* pt = (CbmMvdPoint*) fMvdPoints->Get(link);
690 assert(pt);
691 link.SetIndex(pt->GetTrackID());
692 McTrackInfo& info = getMcTrackInfo(link);
693 info.fHitMap[station]++;
694 }
695 }
696
697 // pocess STS hits
698
699 for (Int_t iHit = 0; iHit < fStsHits->GetEntriesFast(); iHit++) {
700 CbmStsHit* hit = (CbmStsHit*) fStsHits->At(iHit);
701 assert(hit);
702
703 Int_t station = fStsSetup->GetStationNumber(hit->GetAddress());
704
705 // carefully check the hit match by looking at the strips from both sides
706
707 const CbmMatch* frontMatch = dynamic_cast<const CbmMatch*>(fStsClusterMatch->At(hit->GetFrontClusterId()));
708 assert(frontMatch);
709 if (frontMatch->GetNofLinks() <= 0) continue;
710
711 const CbmMatch* backMatch = dynamic_cast<const CbmMatch*>(fStsClusterMatch->At(hit->GetBackClusterId()));
712 assert(backMatch);
713 if (backMatch->GetNofLinks() <= 0) continue;
714
715 if (frontMatch->GetMatchedLink() == backMatch->GetMatchedLink()) {
716 CbmLink link = frontMatch->GetMatchedLink();
717 CbmStsPoint* pt = (CbmStsPoint*) fStsPoints->Get(link);
718 assert(pt);
719 link.SetIndex(pt->GetTrackID());
720 McTrackInfo& info = getMcTrackInfo(link);
721 info.fHitMap[fMvdNstations + station]++;
722 }
723 }
724 LOG(debug) << GetName() << ": Filled hit map from " << fStsHits->GetEntriesFast() << " STS hits";
725}
726// -------------------------------------------------------------------------
727
728
729// ------ Private method FillMatchMap ----------------------------------
730void CbmStsFindTracksQa::FillMatchMap(Int_t& nRec, Int_t& nGhosts, Int_t& nClones)
731{
732
733 // Clear matching maps
734 for (auto it = fMcTrackInfoMap.begin(); it != fMcTrackInfoMap.end(); ++it) {
735 McTrackInfo& info = it->second;
736 info.fStsTrackMatch = -1;
737 info.fQuali = 0.;
738 info.fMatchedNHitsAll = 0;
739 info.fMatchedNHitsTrue = 0;
740 }
741
742 // Loop over StsTracks. Check matched MCtrack and fill maps.
743 nGhosts = 0;
744 nClones = 0;
745
746 Int_t nTracks = fStsTracks->GetEntriesFast();
747 for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
748
749 // --- StsTrack
750 CbmStsTrack* stsTrack = (CbmStsTrack*) fStsTracks->At(iTrack);
751 assert(stsTrack);
752 Int_t nHits = stsTrack->GetTotalNofHits();
753
754 // --- TrackMatch
755
756 assert(iTrack >= 0 && iTrack < fStsTrackMatches->GetEntriesFast());
757 CbmTrackMatchNew* match = (CbmTrackMatchNew*) fStsTrackMatches->At(iTrack);
758 assert(match);
759 Int_t nTrue = match->GetNofTrueHits();
760
761 // Check matching criterion (quota)
762 Double_t quali = Double_t(nTrue) / Double_t(nHits);
763
764 // Quality isn't good, it's a ghost
765
766 if (quali < fQuota) {
767 fhNhGhosts->Fill(nHits);
768 nGhosts++;
769 continue;
770 }
771
772 // Quality is good
773
774 // --- Matched MCTrack
775 assert(match->GetNofLinks() > 0);
776 const CbmLink& link = match->GetMatchedLink();
777 assert(link.GetIndex() >= 0);
778 McTrackInfo& info = getMcTrackInfo(link);
779
780 // previous match is better, this track is a clone
781 if ((quali < info.fQuali) || ((quali == info.fQuali) && (nTrue < info.fMatchedNHitsTrue))) {
782 fhNhClones->Fill(nHits);
783 nClones++;
784 continue;
785 }
786
787 // this track is better than the old one
788 if (info.fMatchedNHitsAll > 0) {
789 fhNhClones->Fill(info.fMatchedNHitsAll);
790 nClones++;
791 }
792 info.fStsTrackMatch = iTrack;
793 info.fQuali = quali;
794 info.fMatchedNHitsAll = nHits;
795 info.fMatchedNHitsTrue = nTrue;
796
797 } // Loop over StsTracks
798
799 nRec = nTracks;
800 LOG(debug) << GetName() << ": Filled match map for " << nRec << " STS tracks. Ghosts " << nGhosts << " Clones "
801 << nClones;
802}
803// -------------------------------------------------------------------------
804
805
806// ----- Private method DivideHistos -----------------------------------
807void CbmStsFindTracksQa::DivideHistos(TH1* histo1, TH1* histo2, TH1* histo3)
808{
809
810 if (!histo1 || !histo2 || !histo3) {
811 LOG(fatal) << GetName() << "::DivideHistos: "
812 << "NULL histogram pointer";
813 }
814
815 Int_t nBins = histo1->GetNbinsX();
816 if (histo2->GetNbinsX() != nBins || histo3->GetNbinsX() != nBins) {
817 LOG(error) << GetName() << "::DivideHistos: "
818 << "Different bin numbers in histos";
819 LOG(error) << histo1->GetName() << " " << histo1->GetNbinsX();
820 LOG(error) << histo2->GetName() << " " << histo2->GetNbinsX();
821 LOG(error) << histo3->GetName() << " " << histo3->GetNbinsX();
822 return;
823 }
824
825 Double_t c1, c2, c3, ce;
826 for (Int_t iBin = 0; iBin < nBins; iBin++) {
827 c1 = histo1->GetBinContent(iBin);
828 c2 = histo2->GetBinContent(iBin);
829 if (c2 != 0.) {
830 c3 = c1 / c2;
831 Double_t c4 = (c3 * (1. - c3) / c2);
832 if (c4 >= 0.) {
833 ce = TMath::Sqrt(c3 * (1. - c3) / c2);
834 }
835 else {
836 ce = 0;
837 }
838 }
839 else {
840 c3 = 0.;
841 ce = 0.;
842 }
843 histo3->SetBinContent(iBin, c3);
844 histo3->SetBinError(iBin, ce);
845 }
846}
847// -------------------------------------------------------------------------
848
849
ClassImp(CbmConverterManager)
Int_t nMCTracks
Data class for a reconstructed hit in the STS.
Data class for STS tracks.
int32_t GetAddress() const
Definition CbmHit.h:74
TObject * Get(const CbmLink *lnk)
Int_t Size(Int_t fileNumber, Int_t eventNumber)
Task class creating and managing CbmMCDataArray objects.
CbmMCDataArray * InitBranch(const char *name)
void GetMomentum(TVector3 &momentum) const
Definition CbmMCTrack.h:170
void GetStartVertex(TVector3 &vertex) const
Definition CbmMCTrack.h:176
int32_t GetNofLinks() const
Definition CbmMatch.h:42
const CbmLink & GetMatchedLink() const
Definition CbmMatch.h:41
const std::vector< CbmLink > & GetLinks() const
Definition CbmMatch.h:40
static CbmMvdDetector * Instance()
CbmMvdStationPar * GetParameterFile()
virtual int32_t GetStationNr() const
Definition CbmMvdHit.h:61
Int_t GetStationCount() const
TClonesArray * fMvdHitMatch
std::map< CbmLink, McTrackInfo > fMcTrackInfoMap
CbmStsFindTracksQa(Int_t iVerbose=1)
CbmMCDataArray * fStsPoints
CbmMCDataArray * fMvdPoints
CbmMCDataManager * fMcManager
TClonesArray * fStsTracks
StsClusterMatch.
CbmStsSetup * fStsSetup
STS.
TVector3 fTargetPos
StsTrackMatch.
virtual InitStatus Init()
CbmTimeSlice * fTimeSlice
TClonesArray * fStsHits
StsPoints.
void FillMatchMap(Int_t &nRec, Int_t &nGhosts, Int_t &nClones)
CbmMCDataArray * fMCTracks
MC tracks.
TClonesArray * fStsClusterMatch
StsHitMatch.
virtual void Exec(Option_t *opt)
TClonesArray * fMvdCluster
TH1F * fhMomAccAll
output folder with histos and canvases
McTrackInfo & getMcTrackInfo(const CbmLink &link)
TClonesArray * fStsHitMatch
StsHits.
FairRootManager * fManager
map track link -> track info
virtual void SetParContainers()
TClonesArray * fStsTrackMatches
StsTrack.
Bool_t fIsMvdActive
MCtrack.
void DivideHistos(TH1 *histo1, TH1 *histo2, TH1 *histo3)
virtual InitStatus ReInit()
data class for a reconstructed 3-d hit in the STS
Definition CbmStsHit.h:35
int32_t GetFrontClusterId() const
Definition CbmStsHit.h:105
int32_t GetBackClusterId() const
Definition CbmStsHit.h:65
Bool_t Init(const char *geometryFile=nullptr)
Initialise the setup.
Int_t GetNofStations() const
Definition CbmStsSetup.h:94
static CbmStsSetup * Instance()
Int_t GetStationNumber(Int_t address)
Bool_t IsInit() const
Initialisation status for sensor parameters.
int32_t GetNofMvdHits() const
Definition CbmStsTrack.h:87
virtual int32_t GetTotalNofHits() const
Definition CbmStsTrack.h:81
int32_t GetNofStsHits() const
Definition CbmStsTrack.h:93
Bookkeeping of time-slice content.
const CbmMatch & GetMatch() const
int32_t GetNofWrongHits() const
int32_t GetNofTrueHits() const
Int_t fMatchedNHitsAll
percentage of matched hits
std::map< Int_t, Int_t > fHitMap
Int_t fStsTrackMatch
Mvd / Sts station -> number of attached hits.
Int_t fMatchedNHitsTrue
number of matched hits
Double_t fQuali
matched StsTrack index