CbmRoot
Loading...
Searching...
No Matches
CbmTrackingTrdQa.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// ----- CbmTrackingTrdQa source file -----
7// ----- Created 11/01/06 by V. Friese -----
8// -------------------------------------------------------------------------
9
10// Includes class header
11#include "CbmTrackingTrdQa.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#include "TH2F.h"
22
23#include <TPDGCode.h>
24
25// Includes from FairRoot
26#include "FairEventHeader.h"
27#include "FairRun.h"
28
29#include <Logger.h>
30
31// Includes from CbmRoot
32#include "CbmGlobalTrack.h"
33#include "CbmMCDataArray.h"
34#include "CbmMCDataManager.h"
35#include "CbmMCTrack.h"
36#include "CbmStsTrack.h"
37#include "CbmTimeSlice.h"
38#include "CbmTrackMatchNew.h"
39#include "CbmTrdHit.h"
40#include "CbmTrdPoint.h"
41#include "CbmTrdTrack.h"
43#include "FairRunAna.h"
44
45using std::fixed;
46using std::right;
47using std::setprecision;
48using std::setw;
49
50const char* CbmTrackingTrdQa::fgkIdxName[fgkNpdg] = {"e", "#mu", "#pi", "K", "#bf{p}", "any"};
51const char* CbmTrackingTrdQa::fgkIdxSymb[fgkNpdg] = {"e", "mu", "pi", "K", "p", "x"};
52
53// -------------------------------------------------------------------------
55{
56 int idx(5);
57 switch (pdg) {
58 case kElectron:
59 case kPositron: idx = 0; break;
60 case kMuonMinus:
61 case kMuonPlus: idx = 1; break;
62 case kPiMinus:
63 case kPiPlus: idx = 2; break;
64 case kKMinus:
65 case kKPlus: idx = 3; break;
66 case kProton:
67 case kProtonBar: idx = 4; break;
68 default: idx = 5; break;
69 }
70 return idx;
71}
73{
74 if (idx < 0 || idx >= 5) return 0;
75 int pdg = 0;
76 switch (idx) {
77 case 0: pdg = kElectron; break;
78 case 1: pdg = kMuonMinus; break;
79 case 2: pdg = kPiPlus; break;
80 case 3: pdg = kKPlus; break;
81 case 4: pdg = kProton; break;
82 }
83 return pdg;
84}
85const char* CbmTrackingTrdQa::Idx2Name(int idx)
86{
87 if (idx < 0 || idx >= 5) return "non";
88 return fgkIdxName[idx];
89}
90const char* CbmTrackingTrdQa::Idx2Symb(int idx)
91{
92 if (idx < 0 || idx >= 5) return "o";
93 return fgkIdxSymb[idx];
94}
95
96
97// ----- Default constructor -------------------------------------------
98CbmTrackingTrdQa::CbmTrackingTrdQa(Int_t iVerbose) : FairTask("CbmTrackingTrdQa", iVerbose) {}
99
100// -------------------------------------------------------------------------
101
102
103// ----- Standard constructor ------------------------------------------
104CbmTrackingTrdQa::CbmTrackingTrdQa(Int_t minStations, Double_t quota, Int_t iVerbose)
105 : FairTask("CbmTrackingTrdQa", iVerbose)
106 , fMinStations(minStations)
107 , fQuota(quota)
108{
109}
110// -------------------------------------------------------------------------
111
112
113// ----- Destructor ----------------------------------------------------
115{
116 fHistoList->Delete();
117 delete fHistoList;
118}
119// -------------------------------------------------------------------------
120
121
122// ----- Task execution ------------------------------------------------
123void CbmTrackingTrdQa::Exec(Option_t* /*opt*/)
124{
125
126 LOG(debug) << GetName() << ": Process event ";
127
128 // Timer
129 fTimer.Start();
130
131 // Eventwise counters
132 // Int_t nMCTracks = 0;
133 Int_t nTracks = 0;
134 Int_t nGhosts = 0;
135 Int_t nClones = 0;
136 Int_t nAll = 0;
137 Int_t nAcc = 0;
138 Int_t nRecAll = 0;
139 Int_t nPrim = 0;
140 Int_t nRecPrim = 0;
141 Int_t nFast = 0;
142 Int_t nRecFast = 0;
143 Int_t nFastLong = 0;
144 Int_t nRecFastLong = 0;
145 Int_t nSec = 0;
146 Int_t nRecSec = 0;
147 TVector3 momentum;
148 TVector3 vertex;
149
150 // check consistency
151 //assert(fGlobalTracks->GetEntriesFast() == fGlobalTrackMatches->GetEntriesFast());
152 assert(fTrdTracks->GetEntriesFast() == fTrdTrackMatches->GetEntriesFast());
153 assert(fStsTracks->GetEntriesFast() == fStsTrackMatches->GetEntriesFast());
154
155 std::vector<CbmLink> events = fTimeSlice->GetMatch().GetLinks();
156 std::sort(events.begin(), events.end());
157
158 {
159 fMcTrackInfoMap.clear();
160 McTrackInfo info;
161 info.fIsAccepted = false;
162 info.fNtimesReconstructed = 0;
163 info.fIsPrimary = false;
164 info.fIsFast = false;
165 info.fIsLong = false;
166
167 std::cout << "MC events in slice : " << events.size() << std::endl;
168
169 for (uint iLink = 0; iLink < events.size(); iLink++) {
170 CbmLink link = events[iLink];
171 Int_t nMCTracks = fMCTracks->Size(link);
172 std::cout << "MC event " << iLink << " n mc tracks " << nMCTracks << std::endl;
173 for (Int_t iTr = 0; iTr < nMCTracks; iTr++) {
174 link.SetIndex(iTr);
175 fMcTrackInfoMap.insert({link, info});
176 }
177 }
178 }
179
180 // Fill hit and track maps
181 FillHitMap();
182 FillTrackMatchMap(nTracks, nGhosts, nClones);
183
184 int nMcTracks = fMcTrackInfoMap.size();
185
186 // Loop over MCTracks
187 int iMcTrack = 0;
188 for (auto itTrack = fMcTrackInfoMap.begin(); itTrack != fMcTrackInfoMap.end(); ++itTrack, ++iMcTrack) {
189 const CbmLink& link = itTrack->first;
190 McTrackInfo& info = itTrack->second;
191 CbmMCTrack* mcTrack = dynamic_cast<CbmMCTrack*>(fMCTracks->Get(link));
192 assert(mcTrack);
193
194 nAll++;
195
196 // Check origin of MCTrack
197 // TODO: Track origin should rather be compared to MC event vertex
198 // But that is not available from MCDataManager
199 mcTrack->GetStartVertex(vertex);
200 if (TMath::Abs(vertex.Z() - fTargetPos.Z()) < 1.) {
201 info.fIsPrimary = true;
202 }
203
204 // Get momentum
205 mcTrack->GetMomentum(momentum);
206 info.fP = momentum.Mag();
207 info.fPt = momentum.Pt();
208 info.fPdg = mcTrack->GetPdgCode();
209 info.fY = mcTrack->GetRapidity() - fYCM;
210 info.fIsFast = (info.fP > 0.1);
211
212 // Continue only for reconstructible tracks
213
214 Int_t nStations = info.fHitMap.size();
215
216 int nContStations = 0; // Number of continious stations
217 {
218 int istaprev = -100;
219 int len = 0;
220 for (auto itSta = info.fHitMap.begin(); itSta != info.fHitMap.end(); itSta++) {
221 if (itSta->first == istaprev + 1) {
222 len++;
223 }
224 else {
225 len = 1;
226 }
227 if (nContStations < len) {
228 nContStations = len;
229 }
230 istaprev = itSta->first;
231 }
232 }
233
234 info.fIsLong = (nContStations >= fTrdNstations);
235
236 if (nStations < fMinStations) continue; // Too few stations
237 if (nContStations < fMinStations) continue; // Too few stations
238
239 info.fIsAccepted = true;
240 nAcc++;
241
242 if (info.fIsPrimary) {
243 nPrim++;
244 }
245 else {
246 nSec++;
247 }
248
249 if (info.fIsFast) {
250 nFast++;
251 }
252
253 Bool_t isFastLong = (info.fIsFast && info.fIsLong);
254 if (isFastLong) {
255 nFastLong++;
256 }
257
258 // Fill histograms for reconstructible tracks
259
260 fhPtAccAll->Fill(info.fPt);
261 fhNpAccAll->Fill(Double_t(nStations));
262 if (info.fIsPrimary) {
263 fhPtAccPrim->Fill(info.fPt);
264 fhPidPtY["prmY"][Pdg2Idx(info.fPdg)]->Fill(info.fY, info.fPt);
265 fhNpAccPrim->Fill(Double_t(nStations));
266 }
267 else {
268 fhPtAccSec->Fill(info.fPt);
269 fhPidPtY["secY"][Pdg2Idx(info.fPdg)]->Fill(info.fY, info.fPt);
270 fhNpAccSec->Fill(Double_t(nStations));
271 fhZAccSec->Fill(vertex.Z());
272 }
273
274 // Get matched GlobalTrack
275 Int_t globalTrackId = info.fGlobalTrackMatch;
276 Int_t trdTrackId = info.fTrdTrackMatch;
277 Double_t quali = info.fQuali;
278 // Bool_t isRec = kFALSE;
279 if (globalTrackId < 0) continue;
280 if (trdTrackId < 0) continue;
281 CbmGlobalTrack* globalTrack = (CbmGlobalTrack*) fGlobalTracks->At(globalTrackId);
282
283 CbmTrdTrack* trdTrack = (CbmTrdTrack*) fTrdTracks->At(trdTrackId);
284 assert(trdTrack);
285 assert(quali >= fQuota);
286 CbmTrackMatchNew* match = (CbmTrackMatchNew*) fTrdTrackMatches->At(trdTrackId);
287 assert(match);
288 Int_t nTrue = match->GetNofTrueHits();
289 Int_t nWrong = match->GetNofWrongHits();
290 //Int_t nFake = match->GetNofFakeHits();
291 Int_t nFake = 0;
292 Int_t nAllHits = trdTrack->GetNofHits();
293 assert(nTrue + nWrong + nFake == nAllHits);
294
295 int nStsHits = 0;
296 {
297 Int_t stsTrackId = info.fStsTrackMatch;
298 if (stsTrackId >= 0) {
299 CbmStsTrack* stsTrack = (CbmStsTrack*) fStsTracks->At(stsTrackId);
300 assert(stsTrack);
301 nStsHits = stsTrack->GetTotalNofHits();
302 }
303 }
304
305 double qp = globalTrack->GetParamFirst()->GetQp();
306 //double q = (qp >= 1.) ? 1. : -1.;
307 double p = (fabs(qp) > 1. / 1000.) ? 1. / fabs(qp) : 1000.;
308 double tx = globalTrack->GetParamFirst()->GetTx();
309 double ty = globalTrack->GetParamFirst()->GetTy();
310 double pt = sqrt((tx * tx + ty * ty) / (1. + tx * tx + ty * ty)) * p;
311
312 // Verbose output
313 LOG(debug1) << GetName() << ": MCTrack " << iMcTrack << ", stations " << nStations << ", hits " << nAllHits
314 << ", true hits " << nTrue;
315
316 // Fill histograms for reconstructed tracks
317 nRecAll++;
318 fhPtRecAll->Fill(info.fPt);
319 fhNpRecAll->Fill(Double_t(nAllHits));
320 //fhPidXY[Pdg2Idx[info.fPdg]]->Fill(info.fY, info.fPt);
321 if (info.fIsPrimary) {
322 nRecPrim++;
323 fhPtRecPrim->Fill(info.fPt);
324 fhPidPtY["prmE"][Pdg2Idx(info.fPdg)]->Fill(info.fY, info.fPt);
325 fhNpRecPrim->Fill(Double_t(nAllHits));
326 if (info.fPt > 0.001) {
327 fhPtResPrim->Fill((pt / info.fPt - 1.));
328 }
329 if (info.fP > 0.001) {
330 double dp = p / info.fP - 1.;
331 fhPResPrim->Fill(dp);
332 if (nStsHits == 0) {
333 fhPResPrimSts0->Fill(dp);
334 }
335 if (nStsHits == 1) {
336 fhPResPrimSts1->Fill(dp);
337 }
338 if (nStsHits == 2) {
339 fhPResPrimSts2->Fill(dp);
340 }
341 if (nStsHits >= 3) {
342 fhPResPrimSts3->Fill(dp);
343 }
344 }
345 }
346 else {
347 nRecSec++;
348 fhPtRecSec->Fill(info.fPt);
349 fhPidPtY["secE"][Pdg2Idx(info.fPdg)]->Fill(info.fY, info.fPt);
350 fhNpRecSec->Fill(Double_t(nAllHits));
351 fhZRecSec->Fill(vertex.Z());
352 }
353 if (info.fIsFast) nRecFast++;
354 if (isFastLong) nRecFastLong++;
355
356 } // Loop over MCTracks
357
358 // Loop over MC points
359
360 for (uint iLink = 0; iLink < events.size(); iLink++) {
361 CbmLink link = events[iLink];
362 Int_t nMcPoints = fTrdPoints->Size(link);
363 std::cout << "MC event " << iLink << " n mc points " << nMcPoints << std::endl;
364 for (Int_t ip = 0; ip < nMcPoints; ip++) {
365 link.SetIndex(ip);
366 CbmTrdPoint* pt = (CbmTrdPoint*) fTrdPoints->Get(link);
367 assert(pt);
368 Int_t station = CbmTrdTrackingInterface::Instance()->GetTrackingStationIndex(pt->GetDetectorID());
369 link.SetIndex(pt->GetTrackID());
370 McTrackInfo& info = getMcTrackInfo(link);
371 if (info.fIsAccepted) {
372 fhStationEffXY[station].Fill(pt->GetX(), pt->GetY(), (info.fNtimesReconstructed > 0) ? 100. : 0.);
373 }
374 }
375 }
376
377 // Calculate efficiencies
378 Double_t effAll = Double_t(nRecAll) / Double_t(nAcc);
379 Double_t effPrim = Double_t(nRecPrim) / Double_t(nPrim);
380 Double_t effFast = Double_t(nRecFast) / Double_t(nFast);
381 Double_t effFastLong = Double_t(nRecFastLong) / Double_t(nFastLong);
382 Double_t effSec = Double_t(nRecSec) / Double_t(nSec);
383
384 fTimer.Stop();
385
386
387 // Event summary
388 LOG(info) << "+ " << setw(20) << GetName() << ": Event " << setw(6) << right << fNEvents << ", real time " << fixed
389 << setprecision(6) << fTimer.RealTime() << " s, MC tracks: all " << nMcTracks << ", acc. " << nAcc
390 << ", rec. " << nRecAll << ", eff. " << setprecision(2) << 100. * effAll << " %";
391 if (fair::Logger::Logging(fair::Severity::debug)) {
392 LOG(debug) << "---------- CbmTrackingTrdQa : Event summary ------------";
393 LOG(debug) << "MCTracks : " << nAll << ", reconstructible: " << nAcc << ", reconstructed: " << nRecAll;
394 LOG(debug) << "Vertex : reconstructible: " << nPrim << ", reconstructed: " << nRecPrim << ", efficiency "
395 << effPrim * 100. << "%";
396 LOG(debug) << "Fast : reconstructible: " << nFast << ", reconstructed: " << nRecFast << ", efficiency "
397 << effFast * 100. << "%";
398 LOG(debug) << "Fast long : reconstructible: " << nFastLong << ", reconstructed: " << nRecFastLong << ", efficiency "
399 << effFastLong * 100. << "%";
400 LOG(debug) << "Non-vertex : reconstructible: " << nSec << ", reconstructed: " << nRecSec << ", efficiency "
401 << effSec * 100. << "%";
402 LOG(debug) << "TrdTracks " << nTracks << ", ghosts " << nGhosts << ", clones " << nClones;
403 LOG(debug) << "-----------------------------------------------------------\n";
404 }
405
406
407 // Increase counters
408 fNAll += nAll;
409 fNAccAll += nAcc;
410 fNAccPrim += nPrim;
411 fNAccFast += nFast;
412 fNAccFastLong += nFastLong;
413 fNAccSec += nSec;
414 fNRecAll += nRecAll;
415 fNRecPrim += nRecPrim;
416 fNRecFast += nRecFast;
417 fNRecFastLong += nRecFastLong;
418 fNRecSec += nRecSec;
419 fNGhosts += nGhosts;
420 fNClones += nClones;
421 fNEvents++;
422 fTime += fTimer.RealTime();
423}
424// -------------------------------------------------------------------------
425
426
427// ----- Public method SetParContainers --------------------------------
429// -------------------------------------------------------------------------
430
431
432// ----- Public method Init --------------------------------------------
434{
435
436 LOG(info) << "\n\n====================================================";
437 LOG(info) << GetName() << ": Initialising...";
438
439 fManager = FairRootManager::Instance();
440 assert(fManager);
441
442 fMcManager = dynamic_cast<CbmMCDataManager*>(fManager->GetObject("MCDataManager"));
443
444 assert(fMcManager);
445
446 fTimeSlice = static_cast<CbmTimeSlice*>(fManager->GetObject("TimeSlice."));
447
448 if (fTimeSlice == nullptr) {
449 LOG(fatal) << "CbmTrackingTrdQa: No time slice object";
450 }
451
452 if (fMcManager) {
453 fMCTracks = fMcManager->InitBranch("MCTrack");
454 fTrdPoints = fMcManager->InitBranch("TrdPoint");
455 }
456
457 assert(fMCTracks);
458 assert(fTrdPoints);
459
460 // Get the geometry
461 InitStatus geoStatus = GetGeometry();
462 if (geoStatus != kSUCCESS) {
463 LOG(error) << GetName() << "::Init: Error in reading geometry!";
464 return geoStatus;
465 }
466
467
468 // TRD
469
470 // Get TrdHit array
471 fTrdHits = (TClonesArray*) fManager->GetObject("TrdHit");
472 assert(fTrdHits);
473
474 // Get TrdHitMatch array
475 fTrdHitMatch = (TClonesArray*) fManager->GetObject("TrdHitMatch");
476 assert(fTrdHitMatch);
477
478 // Get GlobalTrack array
479 fGlobalTracks = (TClonesArray*) fManager->GetObject("GlobalTrack");
480 assert(fGlobalTracks);
481
482 // Get GlobalTrackMatch array
483 //fGlobalTrackMatches = (TClonesArray*) fManager->GetObject("GlobalTrackMatch");
484 //assert(fGlobalTrackMatches);
485
486 // Get TrdTrack array
487 fTrdTracks = (TClonesArray*) fManager->GetObject("TrdTrack");
488 assert(fTrdTracks);
489
490 // Get TrdTrackMatch array
491 fTrdTrackMatches = (TClonesArray*) fManager->GetObject("TrdTrackMatch");
492 assert(fTrdTrackMatches);
493
494 // Get StsTrack array
495 fStsTracks = (TClonesArray*) fManager->GetObject("StsTrack");
496 assert(fStsTracks);
497
498 // Get StsTrackMatch array
499 fStsTrackMatches = (TClonesArray*) fManager->GetObject("StsTrackMatch");
500 assert(fStsTrackMatches);
501
502
503 // Create histograms
504 CreateHistos();
505 Reset();
506
507 // Output
508 LOG(info) << " Number of Trd stations : " << fTrdNstations;
509 LOG(info) << " Target position ( " << fTargetPos.X() << ", " << fTargetPos.Y() << ", " << fTargetPos.Z() << ") cm";
510 LOG(info) << " Minimum number of Trd stations : " << fMinStations;
511 LOG(info) << " Matching quota : " << fQuota;
512 LOG(info) << "====================================================";
513
514 return geoStatus;
515}
516// -------------------------------------------------------------------------
517
518
519// ----- Public method ReInit ------------------------------------------
521{
522
523 LOG(info) << "\n\n====================================================";
524 LOG(info) << GetName() << ": Re-initialising...";
525
526 // Get the geometry of target and Trd
527 InitStatus geoStatus = GetGeometry();
528 if (geoStatus != kSUCCESS) {
529 LOG(error) << GetName() << "::Init: Error in reading geometry!";
530 return geoStatus;
531 }
532
533 // --- Screen log
534 LOG(info) << " Number of TRD stations : " << fTrdNstations;
535 LOG(info) << " Target position ( " << fTargetPos.X() << ", " << fTargetPos.Y() << ", " << fTargetPos.Z() << ") cm";
536 LOG(info) << " Minimum number of TRD stations : " << fMinStations;
537 LOG(info) << " Matching quota : " << fQuota;
538 LOG(info) << "====================================================";
539
540 return geoStatus;
541}
542// -------------------------------------------------------------------------
543
544
545// ----- Private method Finish -----------------------------------------
547{
548
549 // Divide histograms for efficiency calculation
557 for (int idx(0); idx < fgkNpdg; idx++) {
558 fhPidPtY["allY"][idx]->Add(fhPidPtY["prmY"][idx]);
559 fhPidPtY["allY"][idx]->Add(fhPidPtY["secY"][idx]);
560 fhPidPtY["allE"][idx]->Add(fhPidPtY["prmE"][idx]);
561 fhPidPtY["allE"][idx]->Add(fhPidPtY["secE"][idx]);
562 DivideHistos(fhPidPtY["prmE"][idx], fhPidPtY["prmY"][idx], fhPidPtY["prmE"][idx], "2D");
563 DivideHistos(fhPidPtY["secE"][idx], fhPidPtY["secY"][idx], fhPidPtY["secE"][idx], "2D");
564 DivideHistos(fhPidPtY["allE"][idx], fhPidPtY["allY"][idx], fhPidPtY["allE"][idx], "2D");
565 }
566 // Normalise histos for clones and ghosts to one event
567 if (fNEvents) {
568 fhNhClones->Scale(1. / Double_t(fNEvents));
569 fhNhGhosts->Scale(1. / Double_t(fNEvents));
570 }
571
572 // Calculate integrated efficiencies and rates
573 Double_t effAll = Double_t(fNRecAll) / Double_t(fNAccAll);
574 Double_t effPrim = Double_t(fNRecPrim) / Double_t(fNAccPrim);
575 Double_t effFast = Double_t(fNRecFast) / Double_t(fNAccFast);
576 Double_t effFastLong = Double_t(fNRecFastLong) / Double_t(fNAccFastLong);
577 Double_t effSec = Double_t(fNRecSec) / Double_t(fNAccSec);
578 Double_t rateGhosts = Double_t(fNGhosts) / Double_t(fNRecAll);
579 Double_t rateClones = Double_t(fNClones) / Double_t(fNRecAll);
580
581 // Run summary to screen
582 std::cout << std::endl;
583 LOG(info) << "=====================================";
584 LOG(info) << fName << ": Run summary ";
585 LOG(info) << "Events processed : " << fNEvents << setprecision(2);
586 LOG(info) << "Eff. all tracks : " << effAll * 100 << " % (" << fNRecAll << "/" << fNAccAll << ")";
587 LOG(info) << "Eff. vertex tracks : " << effPrim * 100 << " % (" << fNRecPrim << "/" << fNAccPrim << ")";
588 LOG(info) << "Eff. fast tracks : " << effFast * 100 << " % (" << fNRecFast << "/" << fNAccFast << ")";
589 LOG(info) << "Eff. fast long tracks : " << effFastLong * 100 << " % (" << fNRecFastLong << "/" << fNAccFastLong
590 << ")";
591 LOG(info) << "Eff. secondary tracks : " << effSec * 100 << " % (" << fNRecSec << "/" << fNAccSec << ")";
592 LOG(info) << "Ghost rate : " << rateGhosts * 100 << " % (" << fNGhosts << "/" << fNRecAll << ")";
593 LOG(info) << "Clone rate : " << rateClones * 100 << " % (" << fNClones << "/" << fNRecAll << ")";
594 LOG(info) << "mc tracks/event " << fNAll / fNEvents << " accepted " << fNRecAll / fNEvents;
595 LOG(info) << "Time per event : " << setprecision(6) << fTime / Double_t(fNEvents) << " s";
596
597
598 LOG(info) << "=====================================";
599
600 // Write histos to output
601 /*
602 gDirectory->mkdir("CbmTrackingTrdQa");
603 gDirectory->cd("CbmTrackingTrdQa");
604 TIter next(fHistoList);
605 while (TH1* histo = ((TH1*) next()))
606 histo->Write();
607 gDirectory->cd("..");
608*/
609 FairSink* sink = FairRootManager::Instance()->GetSink();
610 sink->WriteObject(&fOutFolder, nullptr);
611}
612// -------------------------------------------------------------------------
613
614
615// ----- Private method GetGeometry ------------------------------------
617{
618 // Get target geometry
620
621 // Get TRD setup
622 auto trdInterface = CbmTrdTrackingInterface::Instance();
623 assert(trdInterface);
624 fTrdNstations = trdInterface->GetNtrackingStations();
625 return kSUCCESS;
626}
627// -------------------------------------------------------------------------
628
629
630// ----- Get target node -----------------------------------------------
632{
633
634 TGeoNode* target = NULL;
635
636 gGeoManager->CdTop();
637 TGeoNode* cave = gGeoManager->GetCurrentNode();
638 for (Int_t iNode1 = 0; iNode1 < cave->GetNdaughters(); iNode1++) {
639 TString name = cave->GetDaughter(iNode1)->GetName();
640 if (name.Contains("pipe", TString::kIgnoreCase)) {
641 LOG(debug) << "Found pipe node " << name;
642 gGeoManager->CdDown(iNode1);
643 break;
644 }
645 }
646 for (Int_t iNode2 = 0; iNode2 < gGeoManager->GetCurrentNode()->GetNdaughters(); iNode2++) {
647 TString name = gGeoManager->GetCurrentNode()->GetDaughter(iNode2)->GetName();
648 if (name.Contains("pipevac1", TString::kIgnoreCase)) {
649 LOG(debug) << "Found vacuum node " << name;
650 gGeoManager->CdDown(iNode2);
651 break;
652 }
653 }
654 for (Int_t iNode3 = 0; iNode3 < gGeoManager->GetCurrentNode()->GetNdaughters(); iNode3++) {
655 TString name = gGeoManager->GetCurrentNode()->GetDaughter(iNode3)->GetName();
656 if (name.Contains("target", TString::kIgnoreCase)) {
657 LOG(debug) << "Found target node " << name;
658 gGeoManager->CdDown(iNode3);
659 target = gGeoManager->GetCurrentNode();
660 break;
661 }
662 }
663 if (!target) {
664 fTargetPos[0] = 0.;
665 fTargetPos[1] = 0.;
666 fTargetPos[2] = 0.;
667 }
668 else {
669 TGeoHMatrix* glbMatrix = gGeoManager->GetCurrentMatrix();
670 Double_t* pos = glbMatrix->GetTranslation();
671 fTargetPos[0] = pos[0];
672 fTargetPos[1] = pos[1];
673 fTargetPos[2] = pos[2];
674 }
675
676 gGeoManager->CdTop();
677}
678// -------------------------------------------------------------------------
679
680
681// ----- Private method CreateHistos -----------------------------------
683{
684
685 fOutFolder.Clear();
686
687 // Histogram list
688 fHistoList = new TList();
689
690 // Momentum distributions
691 Double_t minPt = 0.;
692 Double_t maxPt = 2.;
693 Int_t nBinsPt = 40;
694
695 fhStationEffXY.clear();
696
697 for (int i = 0; i < fTrdNstations; i++) {
698 //auto trdInterface = CbmTrdTrackingInterface::Instance();
699 double dx = 150; //trdInterface->GetXmax(i);
700 double dy = 150; //trdInterface->GetYmax(i);
701 fhStationEffXY.emplace_back(Form("fhStationEffXY%i", i), Form("Efficiency XY: Station %i;X [cm];Y [cm]", i), 300,
702 -dx, dx, 300, -dy, dy);
703 fhStationEffXY[i].SetDirectory(0);
704 fhStationEffXY[i].SetOptStat(10);
705 fhStationEffXY[i].GetYaxis()->SetTitleOffset(1.4);
706 }
707
708 for (int i = 0; i < fTrdNstations; i++) {
709 fHistoList->Add(&fhStationEffXY[i]);
710 }
711
712 fhPtAccAll = new TH1F("hPtAccAll", "all reconstructable tracks", nBinsPt, minPt, maxPt);
713 fhPtRecAll = new TH1F("hPtRecAll", "all reconstructed tracks", nBinsPt, minPt, maxPt);
714 fhPtEffAll = new TH1F("hPtEffAll", "efficiency all tracks", nBinsPt, minPt, maxPt);
715 fhPtAccPrim = new TH1F("hPtAccPrim", "reconstructable vertex tracks", nBinsPt, minPt, maxPt);
716 fhPtRecPrim = new TH1F("hPtRecPrim", "reconstructed vertex tracks", nBinsPt, minPt, maxPt);
717 fhPtEffPrim = new TH1F("hPtEffPrim", "efficiency vertex tracks", nBinsPt, minPt, maxPt);
718 fhPtAccSec = new TH1F("hPtAccSec", "reconstructable non-vertex tracks", nBinsPt, minPt, maxPt);
719 fhPtRecSec = new TH1F("hPtRecSec", "reconstructed non-vertex tracks", nBinsPt, minPt, maxPt);
720 fhPtEffSec = new TH1F("hPtEffSec", "efficiency non-vertex tracks", nBinsPt, minPt, maxPt);
730
731 const char* pltTitle[] = {"Yield", "Yield", "Yield", "Efficiency", "Efficiency", "Efficiency"};
732 const char* pltLab[] = {"yield", "yield", "yield", "#epsilon (%)", "#epsilon (%)", "#epsilon (%)"};
733 const char* vxTyp[] = {"allY", "prmY", "secY", "allE", "prmE", "secE"};
734 for (int ivx(0); ivx < 6; ivx++) {
735 for (int ipid(0); ipid < fgkNpdg; ipid++) {
736 fhPidPtY[vxTyp[ivx]][ipid] = new TH2F(
737 Form("hPtY_%s%s", vxTyp[ivx], Idx2Symb(ipid)),
738 Form("%s %s(%s); y - y_{cm}; p_{T} (GeV/c); %s", pltTitle[ivx], Idx2Name(ipid), vxTyp[ivx], pltLab[ivx]), 50,
739 -2.5, 2.5, nBinsPt, minPt, maxPt);
740 fHistoList->Add(fhPidPtY[vxTyp[ivx]][ipid]);
741 }
742 }
743 // Number-of-points distributions
744 Double_t minNp = -0.5;
745 Double_t maxNp = 15.5;
746 Int_t nBinsNp = 16;
747 fhNpAccAll = new TH1F("hNpAccAll", "all reconstructable tracks", nBinsNp, minNp, maxNp);
748 fhNpRecAll = new TH1F("hNpRecAll", "all reconstructed tracks", nBinsNp, minNp, maxNp);
749 fhNpEffAll = new TH1F("hNpEffAll", "efficiency all tracks", nBinsNp, minNp, maxNp);
750 fhNpAccPrim = new TH1F("hNpAccPrim", "reconstructable vertex tracks", nBinsNp, minNp, maxNp);
751 fhNpRecPrim = new TH1F("hNpRecPrim", "reconstructed vertex tracks", nBinsNp, minNp, maxNp);
752 fhNpEffPrim = new TH1F("hNpEffPrim", "efficiency vertex tracks", nBinsNp, minNp, maxNp);
753 fhNpAccSec = new TH1F("hNpAccSec", "reconstructable non-vertex tracks", nBinsNp, minNp, maxNp);
754 fhNpRecSec = new TH1F("hNpRecSec", "reconstructed non-vertex tracks", nBinsNp, minNp, maxNp);
755 fhNpEffSec = new TH1F("hNpEffSec", "efficiency non-vertex tracks", nBinsNp, minNp, maxNp);
765
766 // z(vertex) distributions
767 Double_t minZ = 0.;
768 Double_t maxZ = 50.;
769 Int_t nBinsZ = 50;
770 fhZAccSec = new TH1F("hZAccSec", "reconstructable non-vertex tracks", nBinsZ, minZ, maxZ);
771 fhZRecSec = new TH1F("hZRecSecl", "reconstructed non-vertex tracks", nBinsZ, minZ, maxZ);
772 fhZEffSec = new TH1F("hZEffRec", "efficiency non-vertex tracks", nBinsZ, minZ, maxZ);
773 fHistoList->Add(fhZAccSec);
774 fHistoList->Add(fhZRecSec);
775 fHistoList->Add(fhZEffSec);
776
777 // Number-of-hit distributions
778 fhNhClones = new TH1F("hNhClones", "number of hits for clones", nBinsNp, minNp, maxNp);
779 fhNhGhosts = new TH1F("hNhGhosts", "number of hits for ghosts", nBinsNp, minNp, maxNp);
782
783 fhPtResPrim = new TH1F("hPtPrim", "Resolution Pt Primaries [100%]", 100, -1., 1.);
785
786 fhPResPrim = new TH1F("hPPrim", "Resolution P Primaries [100%]", 100, -1., 1.);
788
789 fhPResPrimSts0 = new TH1F("hPPrimSts0", "Resolution P Primaries [100%], No Sts hits", 100, -1., 1.);
791
792 fhPResPrimSts1 = new TH1F("hPPrimSts1", "Resolution P Primaries [100%], 1 Sts hit", 100, -1., 1.);
794
795 fhPResPrimSts2 = new TH1F("hPPrimSts2", "Resolution P Primaries [100%], 2 Sts hits", 100, -1., 1.);
797
798 fhPResPrimSts3 = new TH1F("hPPrimSts3", "Resolution P Primaries [100%], >=3 Sts hits", 100, -1., 1.);
800
801 TIter next(fHistoList);
802 while (TH1* histo = ((TH1*) next())) {
803 fOutFolder.Add(histo);
804 }
805}
806// -------------------------------------------------------------------------
807
808
809// ----- Private method Reset ------------------------------------------
811{
812
813 TIter next(fHistoList);
814 while (TH1* histo = ((TH1*) next()))
815 histo->Reset();
816
819 fNGhosts = fNClones = fNEvents = 0;
820}
821// -------------------------------------------------------------------------
822
823
824// ----- Private method FillHitMap -------------------------------------
826{
827
828 // --- Fill hit map ( mcTrack -> ( station -> number of hits ) )
829
830 // pocess Trd hits
831
832 for (Int_t iHit = 0; iHit < fTrdHits->GetEntriesFast(); iHit++) {
833 CbmTrdHit* hit = (CbmTrdHit*) fTrdHits->At(iHit);
834 assert(hit);
835
836 if ((int) hit->GetClassType() != 1) {
837 // skip TRD-1D hit
838 continue;
839 }
840
842
843 // carefully check the hit match by looking at the strips from both sides
844
845 const CbmMatch* match = dynamic_cast<const CbmMatch*>(fTrdHitMatch->At(iHit));
846 assert(match);
847 if (match->GetNofLinks() <= 0) continue;
848
849 CbmLink link = match->GetMatchedLink();
850
851 CbmTrdPoint* pt = (CbmTrdPoint*) fTrdPoints->Get(link);
852 assert(pt);
853 assert(CbmTrdTrackingInterface::Instance()->GetTrackingStationIndex(pt->GetDetectorID()) == station);
854
855 link.SetIndex(pt->GetTrackID());
856 McTrackInfo& info = getMcTrackInfo(link);
857 info.fHitMap[station]++;
858 }
859 LOG(debug) << GetName() << ": Filled hit map from " << fTrdHits->GetEntriesFast() << " Trd hits";
860}
861// -------------------------------------------------------------------------
862
863
864// ------ Private method FillMatchMap ----------------------------------
865void CbmTrackingTrdQa::FillTrackMatchMap(Int_t& nRec, Int_t& nGhosts, Int_t& nClones)
866{
867 // Clear matching maps
868 for (auto it = fMcTrackInfoMap.begin(); it != fMcTrackInfoMap.end(); ++it) {
869 McTrackInfo& info = it->second;
870 info.fGlobalTrackMatch = -1;
871 info.fQuali = 0.;
872 info.fMatchedNHitsAll = 0;
873 info.fMatchedNHitsTrue = 0;
874 info.fNtimesReconstructed = 0;
875 }
876
877 // Loop over GlobalTracks. Check matched MCtrack and fill maps.
878 nGhosts = 0;
879 nClones = 0;
880 nRec = 0;
881
882 //assert(fGlobalTrackMatches);
883
884 for (Int_t iGlobalTrack = 0; iGlobalTrack < fGlobalTracks->GetEntriesFast(); iGlobalTrack++) {
885
886 // --- GlobalTrack
887 CbmGlobalTrack* globalTrack = (CbmGlobalTrack*) fGlobalTracks->At(iGlobalTrack);
888 assert(globalTrack);
889
890 // --- TrackMatch
891
892 //assert(iGlobalTrack >= 0 && iGlobalTrack < fGlobalTrackMatches->GetEntriesFast());
893 //CbmTrackMatchNew* globalMatch = (CbmTrackMatchNew*) fGlobalTrackMatches->At(iGlobalTrack);
894 //assert(globalMatch);
895
896 int iTrdTrack = globalTrack->GetTrdTrackIndex();
897
898 if (iTrdTrack < 0) continue;
899 CbmTrdTrack* trdTrack = (CbmTrdTrack*) fTrdTracks->At(iTrdTrack);
900 assert(trdTrack);
901 nRec++;
902
903 int iStsTrack = globalTrack->GetStsTrackIndex();
904
905 // --- TrackMatch
906
907 assert(iTrdTrack >= 0 && iTrdTrack < fTrdTrackMatches->GetEntriesFast());
908 CbmTrackMatchNew* trdMatch = (CbmTrackMatchNew*) fTrdTrackMatches->At(iTrdTrack);
909 assert(trdMatch);
910
911 Int_t nHits = trdTrack->GetNofHits();
912 Int_t nTrue = trdMatch->GetNofTrueHits();
913
914 // Check matching criterion (quota)
915 Double_t quali = Double_t(nTrue) / Double_t(nHits);
916
917 // Quality isn't good, it's a ghost
918
919 if (quali < fQuota) {
920 fhNhGhosts->Fill(nHits);
921 nGhosts++;
922 continue;
923 }
924
925 // Quality is good
926
927 // --- Matched MCTrack
928 assert(trdMatch->GetNofLinks() > 0);
929 CbmLink link = trdMatch->GetMatchedLink();
930 assert(link.GetIndex() >= 0);
931 link.SetFile(0); //??
932
933 McTrackInfo& info = getMcTrackInfo(link);
934
935 // previous match is better, this track is a clone
936 if ((quali < info.fQuali) || ((quali == info.fQuali) && (nTrue < info.fMatchedNHitsTrue))) {
937 if (info.fIsAccepted) {
938 fhNhClones->Fill(nHits);
939 nClones++;
940 }
941 continue;
942 }
943
944 // this track is better than the old one
945 if (info.fMatchedNHitsAll > 0) {
946 if (info.fIsAccepted) {
947 fhNhClones->Fill(info.fMatchedNHitsAll);
948 nClones++;
949 }
950 }
951 info.fGlobalTrackMatch = iGlobalTrack;
952 info.fTrdTrackMatch = iTrdTrack;
953 info.fStsTrackMatch = iStsTrack;
954 info.fQuali = quali;
955 info.fMatchedNHitsAll = nHits;
956 info.fMatchedNHitsTrue = nTrue;
958 } // Loop over GlobalTracks
959
960 LOG(debug) << GetName() << ": Filled match map for " << nRec << " Trd tracks. Ghosts " << nGhosts << " Clones "
961 << nClones;
962}
963// -------------------------------------------------------------------------
964
965
966// ----- Private method DivideHistos -----------------------------------
967void CbmTrackingTrdQa::DivideHistos(TH1* histo1, TH1* histo2, TH1* histo3, Option_t* opt)
968{
969
970 if (!histo1 || !histo2 || !histo3) {
971 LOG(fatal) << GetName() << "::DivideHistos: "
972 << "NULL histogram pointer";
973 }
974
975 Int_t nBins = histo1->GetNbinsX();
976 if (histo2->GetNbinsX() != nBins || histo3->GetNbinsX() != nBins) {
977 LOG(error) << GetName() << "::DivideHistos: "
978 << "Different bin numbers in histos";
979 LOG(error) << histo1->GetName() << " " << histo1->GetNbinsX();
980 LOG(error) << histo2->GetName() << " " << histo2->GetNbinsX();
981 LOG(error) << histo3->GetName() << " " << histo3->GetNbinsX();
982 return;
983 }
984 if (strcmp(opt, "2D") == 0) {
985 Int_t nBinsY = histo1->GetNbinsY();
986 if (histo2->GetNbinsY() != nBinsY || histo3->GetNbinsY() != nBinsY) {
987 LOG(error) << GetName() << "::DivideHistos: "
988 << "Different bin numbers in histos";
989 LOG(error) << histo1->GetName() << " " << histo1->GetNbinsY();
990 LOG(error) << histo2->GetName() << " " << histo2->GetNbinsY();
991 LOG(error) << histo3->GetName() << " " << histo3->GetNbinsY();
992 return;
993 }
994 nBins *= nBinsY;
995 }
996
997 Double_t c1, c2, c3, ce;
998 for (Int_t iBin = 0; iBin < nBins; iBin++) {
999 c1 = histo1->GetBinContent(iBin);
1000 c2 = histo2->GetBinContent(iBin);
1001 if (c2 != 0.) {
1002 c3 = c1 / c2;
1003 Double_t c4 = (c3 * (1. - c3) / c2);
1004 if (c4 >= 0.) {
1005 ce = TMath::Sqrt(c3 * (1. - c3) / c2);
1006 }
1007 else {
1008 ce = 0;
1009 }
1010 }
1011 else {
1012 c3 = 0.;
1013 ce = 0.;
1014 }
1015 histo3->SetBinContent(iBin, 1.e2 * c3);
1016 histo3->SetBinError(iBin, 1.e2 * ce);
1017 }
1018}
1019// -------------------------------------------------------------------------
1020
1021
ClassImp(CbmConverterManager)
Int_t nStsHits
Int_t nMCTracks
Data class for STS tracks.
Class for hits in TRD detector.
friend fvec sqrt(const fvec &a)
int32_t GetStsTrackIndex() const
const FairTrackParam * GetParamFirst() const
int32_t GetTrdTrackIndex() const
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
int32_t GetPdgCode() const
Definition CbmMCTrack.h:68
double GetRapidity() const
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
virtual int32_t GetTotalNofHits() const
Definition CbmStsTrack.h:81
Bookkeeping of time-slice content.
const CbmMatch & GetMatch() const
int32_t GetNofWrongHits() const
int32_t GetNofTrueHits() const
virtual int32_t GetNofHits() const
Definition CbmTrack.h:58
TClonesArray * fTrdHitMatch
TrdHits.
CbmMCDataArray * fMCTracks
MC tracks.
static const int fgkNpdg
static int Pdg2Idx(int pdg)
TClonesArray * fTrdHits
TrdPoints.
McTrackInfo & getMcTrackInfo(const CbmLink &link)
std::map< const char *, std::array< TH2F *, fgkNpdg > > fhPidPtY
FairRootManager * fManager
map track link -> track info
Int_t fTrdNstations
MCtrack.
TClonesArray * fStsTrackMatches
StsTrack.
TClonesArray * fTrdTracks
GlobalTrack.
std::map< CbmLink, McTrackInfo > fMcTrackInfoMap
static const char * Idx2Symb(int idx)
CbmMCDataArray * fTrdPoints
static const char * fgkIdxName[fgkNpdg]
virtual void Finish()
TClonesArray * fTrdTrackMatches
TrdTrack.
std::vector< CbmQaHist< TProfile2D > > fhStationEffXY
output folder with histos and canvases
virtual void Exec(Option_t *opt)
static int Idx2Pdg(int idx)
static const char * Idx2Name(int idx)
virtual InitStatus Init()
virtual void SetParContainers()
CbmMCDataManager * fMcManager
TClonesArray * fStsTracks
TrdTrackMatch.
TClonesArray * fGlobalTracks
TrdHitMatch.
void DivideHistos(TH1 *histo1, TH1 *histo2, TH1 *histo3, Option_t *opt="")
TVector3 fTargetPos
StsTrackMatch.
CbmTrackingTrdQa(Int_t iVerbose=1)
CbmTimeSlice * fTimeSlice
static const char * fgkIdxSymb[fgkNpdg]
virtual InitStatus ReInit()
void FillTrackMatchMap(Int_t &nRec, Int_t &nGhosts, Int_t &nClones)
data class for a reconstructed Energy-4D measurement in the TRD
Definition CbmTrdHit.h:40
bool GetClassType() const
Definition CbmTrdHit.h:80
static CbmTrdTrackingInterface * Instance()
Gets pointer to the instance of the CbmTrdTrackingInterface.
int GetTrackingStationIndex(const CbmHit *hit) const override
Gets a tracking station of a CbmHit.
Int_t fStsTrackMatch
matched TrdTrack index
Int_t fMatchedNHitsTrue
number of matched hits
Double_t fQuali
matched StsTrack index
std::map< Int_t, Int_t > fHitMap
Int_t fMatchedNHitsAll
percentage of matched hits
Int_t fTrdTrackMatch
matched GlobalTrack index
Bool_t fIsAccepted
number of matched hits
Int_t fGlobalTrackMatch
Trd station -> number of attached hits.