BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnGlobalTracking.cxx
Go to the documentation of this file.
1/** BmnGlobalTracking.cxx
2 * \author Sergey Merts <Sergey.Merts@gmail.com>
3 * @since 2014
4 * @version 1.0
5 **/
6
7#include "BmnGlobalTracking.h"
8
9#include "BmnEventHeader.h"
10#include "BmnFieldMap.h"
11#include "BmnGemStripHit.h"
12#include "TFile.h"
13#include "TVectorD.h"
14
15#include <TKey.h>
16#include <algorithm>
17#include <iterator>
18#include <map>
19#include <vector>
20
21using namespace TMath;
22
23const Int_t numChambers = 59;
24const std::vector<std::string> PARTICLES = {"pi", "K", "p", "d", "t", "He3"};
25const std::vector<std::string> ZONES = {"clean", "overlap", "accepted"};
26
28 : fCscHits(nullptr)
29 , fTof1Hits(nullptr)
30 , fTof2Hits(nullptr)
31 , fStsTracks(nullptr)
32 , fGlobalTracks(nullptr)
33 , fScWall(nullptr)
34 , fNdet(nullptr)
35 , fInnerTrackBranchName("StsVector")
36 , fPeriod(8)
37 , fEventNo(0)
38 , fVertex(nullptr)
39 , fKalman(nullptr)
40 , fTime(0.0)
43 , fNInnerTracks(0)
45{}
46
48{
49 if (fGlobalTracks) {
50 fGlobalTracks->Delete();
51 delete fGlobalTracks;
52 }
53}
54
56{
57 if (fVerbose > 1)
58 cout << "BmnGlobalTracking::Init started\n";
59
61
62 FairRootManager* ioman = FairRootManager::Instance();
63 if (!ioman)
64 Fatal("Init", "FairRootManager is not instantiated");
65
66 fCscHits = (TClonesArray*)ioman->GetObject("BmnCSCHit");
67 fTof1Hits = (TClonesArray*)ioman->GetObject("BmnTof400Hit");
68 fTof2Hits = (TClonesArray*)ioman->GetObject("BmnTof700Hit");
69
70 fVertex = (CbmVertex*)ioman->GetObject("MpdVertex.");
71 fScWall = (BmnScWallEvent*)ioman->GetObject("ScWallEvent");
72 fNdet = (BmnNdetEvent*)ioman->GetObject("NdetEvent");
73
74 fStsTracks = (TClonesArray*)ioman->GetObject(fInnerTrackBranchName);
75 if (fStsTracks) {
76 printf("BmnGlobalTracking::Init(): branch %s was found!\n", fInnerTrackBranchName.Data());
77 fGlobalTracks = new TClonesArray("BmnGlobalTrack", 100); // out
78 ioman->Register("BmnGlobalTrack", "GLOBAL", fGlobalTracks, kTRUE);
79 } else {
80 printf("BmnGlobalTracking::Init(): branch with inner tracks was not found! Task will be deactivated \n");
81 SetActive(kFALSE);
82 return kERROR;
83 }
84
85 if (fPeriod == 8) {
86 TString workdir = getenv("VMCWORKDIR");
87
88 LoadAllAkimaCorrections(workdir + "/input/OutputStages_FitResults_combined_tof400_akima_v2_it16.root", kTRUE);
89 LoadAllAkimaCorrections(workdir + "/input/OutputStages_FitResults_combined_tof700_akima_it12.root", kFALSE);
90 }
91
92 if (fVerbose > 1)
93 cout << "BmnGlobalTracking::Init finished\n";
94 return kSUCCESS;
95}
96
98{
99 TStopwatch sw;
100 sw.Start();
101
102 if (!IsActive())
103 return;
104
105 fEventNo++;
106 fGlobalTracks->Delete();
107
108 if (fVerbose > 1)
109 cout << "\n======================== Global tracking exec started =====================\n" << endl;
110
111 if (!fVertex)
112 return;
113 if (fVertex->GetNTracks() < 2)
114 return;
115
116 for (Int_t i = 0; i < fStsTracks->GetEntriesFast(); ++i) {
117 CbmStsTrack* cbmTrack = (CbmStsTrack*)fStsTracks->At(i);
118
120
121 if (cbmTrack->GetNStsHits() < 4)
122 continue;
123
124 BmnGlobalTrack globTr;
125
126 globTr.SetGemTrackIndex(i);
127 globTr.SetParamFirst(*(cbmTrack->GetParamFirst()));
128 globTr.SetParamLast(*(cbmTrack->GetParamLast()));
129 globTr.SetNHits(cbmTrack->GetNStsHits());
130 globTr.SetNDF(cbmTrack->GetNDF());
131 globTr.SetChi2(cbmTrack->GetChi2());
132 FairTrackParam par(*(globTr.GetParamLast()));
133 Int_t pdg = (globTr.GetP() > 0) ? 2212 : -211;
134 Double_t len = 0.0;
135 const Float_t tZ = -0.01942; // z-coordinate of target for RUN-8
136 if (fKalman->TGeoTrackPropagate(&par, tZ, pdg, nullptr, &len) == kBMNERROR)
137 continue;
138 globTr.SetLength(len);
139
140 FairTrackParam parF(*(globTr.GetParamFirst()));
141 if (fKalman->TGeoTrackPropagate(&parF, fVertex->GetZ(), pdg, nullptr, nullptr) == kBMNERROR)
142 continue;
143 Float_t dca = Sqrt(Sq(fVertex->GetX() - parF.GetX()) + Sq(fVertex->GetY() - parF.GetY()));
144 globTr.SetParamFirst(parF);
145 globTr.SetDCAInVertex(dca);
146
147 BmnHit virtualVertexHit;
148 virtualVertexHit.SetXYZ(fVertex->GetX(), fVertex->GetY(), fVertex->GetZ());
149 virtualVertexHit.SetDxyz(Sqrt(fVertex->GetCovariance(0, 0)), Sqrt(fVertex->GetCovariance(1, 1)),
150 Sqrt(fVertex->GetCovariance(2, 2)));
151
152 Double_t chi = 0;
153 fKalman->Update(&parF, &virtualVertexHit, chi);
154 globTr.SetChi2InVertex(chi);
155
157 new ((*fGlobalTracks)[fGlobalTracks->GetEntriesFast()]) BmnGlobalTrack(globTr);
158 }
159
160 MatchingTOF(kTRUE); // tof400
161 MatchingTOF(kFALSE); // tof700
162 // MatchingScWall();
163 MatchingNdet();
164
165 sw.Stop();
166 fTime += sw.RealTime();
167
168 if (fVerbose > 1)
169 cout << "\n======================== Global tracking exec finished ====================\n" << endl;
170}
171
173{
174 Int_t tofID = (tof400) ? 1 : 2;
175 TString tofName = (tof400) ? "TOF-400" : "TOF-700";
176 if (fVerbose)
177 cout << "Matching of " << tofName << " started" << endl;
178 TClonesArray* tofHits = (tof400) ? fTof1Hits : fTof2Hits;
179 if (!tofHits)
180 return kBMNERROR;
181
182 for (Int_t i = 0; i < fGlobalTracks->GetEntriesFast(); i++)
183 ((BmnGlobalTrack*)fGlobalTracks->At(i))->SetUsing(kFALSE);
184
185 map<Float_t, pair<Int_t, Int_t>> distPairs = FindPairsTof(fGlobalTracks, tofHits, tof400);
186
187 for (auto const& distPair : distPairs) {
188 // Float_t dist = distPair.first;
189 pair<Int_t, Int_t> idxes = distPair.second;
190 BmnGlobalTrack* track = (BmnGlobalTrack*)fGlobalTracks->At(idxes.first);
191 if (track->IsUsed())
192 continue;
193 BmnHit* hit = (BmnHit*)tofHits->At(idxes.second);
194 if (hit->IsUsed())
195 continue;
196
197 track->SetUsing(kTRUE);
198 hit->SetUsing(kTRUE);
199 track->SetNHits(track->GetNHits() + 1);
200 if (tof400)
202 else
204
205 Double_t len = 0.0;
206 FairTrackParam par(*(track->GetParamLast()));
207 Int_t pdg = (track->GetP() > 0) ? 2212 : -211;
208 fKalman->TGeoTrackPropagate(&par, hit->GetZ(), pdg, nullptr, &len);
209 len += track->GetLength();
210 hit->SetLength(len);
211 Float_t mom = track->GetP();
212 Float_t beta = len / hit->GetTimeStamp() / (TMath::C() * 1e-7);
213 Float_t mass2 = mom * mom * (1.0 / beta / beta - 1.0);
214 Float_t xExtr = par.GetX();
215 Float_t yExtr = par.GetY();
216 Int_t chamber = ((hit->GetDetectorID() & 0x0000FF00) >> 8) - 1;
217 Float_t xExtr_stage2 = xExtr + GetAkimaCorrection(chamber, mom, kTRUE, "stage2", tof400);
218 Float_t yExtr_stage2 = yExtr + GetAkimaCorrection(chamber, mom, kFALSE, "stage2", tof400);
219 Float_t sigmaX_stage2 = GetAkimaSigma(chamber, mom, kTRUE, "stage2", tof400);
220 Float_t sigmaY_stage2 = GetAkimaSigma(chamber, mom, kFALSE, "stage2", tof400);
221
222 // for kCommon
223 Float_t xDist = xExtr_stage2 - hit->GetX();
224 Float_t yDist = yExtr_stage2 - hit->GetY();
225 bool isWithinSigma = (Abs(xDist) < 3 * sigmaX_stage2) && (Abs(yDist) < 3 * sigmaY_stage2);
226 if (isWithinSigma) {
227 if (tof400)
228 track->SetTof1HitIndex(idxes.second, static_cast<BmnGlobalTrack::ParticleType>(0));
229 else
230 track->SetTof2HitIndex(idxes.second, static_cast<BmnGlobalTrack::ParticleType>(0));
231 track->SetMass2(tofID, static_cast<BmnGlobalTrack::ParticleType>(0), mass2);
232 track->SetResX(tofID, static_cast<BmnGlobalTrack::ParticleType>(0), xDist);
233 track->SetResY(tofID, static_cast<BmnGlobalTrack::ParticleType>(0), yDist);
234 }
235
236 std::string zone = "accepted";
237 for (Int_t hypId = 1; hypId < BmnGlobalTrack::kNumParticleTypes; ++hypId) { // all hypothises except kCommon
238 TString particle = track->GetParticleName(static_cast<BmnGlobalTrack::ParticleType>(hypId));
239 Float_t xCorr_stage3 = GetAkimaCorrection(chamber, mom, kTRUE, "stage3", tof400, particle.Data(), zone);
240 Float_t yCorr_stage3 = GetAkimaCorrection(chamber, mom, kFALSE, "stage3", tof400, particle.Data(), zone);
241 Float_t sigmaX_stage3 = GetAkimaSigma(chamber, mom, kTRUE, "stage3", tof400, particle.Data(), zone);
242 Float_t sigmaY_stage3 = GetAkimaSigma(chamber, mom, kFALSE, "stage3", tof400, particle.Data(), zone);
243
244 xDist = xExtr_stage2 + xCorr_stage3 - hit->GetX();
245 yDist = yExtr_stage2 + yCorr_stage3 - hit->GetY();
246 isWithinSigma = (Abs(xDist) < 3 * sigmaX_stage3) && (Abs(yDist) < 3 * sigmaY_stage3);
247 if (isWithinSigma) {
248 if (tof400)
249 track->SetTof1HitIndex(idxes.second, static_cast<BmnGlobalTrack::ParticleType>(hypId));
250 else
251 track->SetTof2HitIndex(idxes.second, static_cast<BmnGlobalTrack::ParticleType>(hypId));
252 track->SetMass2(tofID, static_cast<BmnGlobalTrack::ParticleType>(hypId), mass2);
253 track->SetResX(tofID, static_cast<BmnGlobalTrack::ParticleType>(hypId), xDist);
254 track->SetResY(tofID, static_cast<BmnGlobalTrack::ParticleType>(hypId), yDist);
255 }
256 }
257 }
258 return kBMNSUCCESS;
259}
260
262{
263 if (fVerbose)
264 cout << "Matching of ScWall started " << fScWall << endl;
265 if (!fScWall)
266 return kBMNERROR;
267
268 for (Int_t trIdx = 0; trIdx < fGlobalTracks->GetEntriesFast(); ++trIdx) {
270 FairTrackParam par(*(tr->GetParamLast()));
271 Double_t minDX = DBL_MAX;
272 Double_t minDY = DBL_MAX;
273 Float_t xCut = 20.0; // cm
274 Float_t yCut = 20.0; // cm
275 Int_t minIdx = -1;
276
277 Float_t z = 741.5;
278 Int_t nCells = 174; // BmnScWallEvent::fgkMaxCells; //174
279 Int_t pdg = (tr->GetP() > 0) ? 2212 : -211;
280
281 if (fKalman->TGeoTrackPropagate(&par, z, pdg, nullptr, nullptr) == kBMNERROR)
282 continue;
283
284 for (Int_t i = 1; i <= nCells; ++i) {
285 BmnScWallCell* cell = fScWall->GetCell(i);
286 if (cell->GetSignal() < 0.001)
287 continue; // skip empty cells
288
289 Float_t dX = par.GetX() - cell->GetX();
290 Float_t dY = par.GetY() - cell->GetY();
291
292 if (Abs(dX) < xCut && Abs(dY) < yCut && Abs(dX) < Abs(minDX) && Abs(dY) < Abs(minDY)) {
293 minDX = dX;
294 minDY = dY;
295 minIdx = i;
296 }
297 }
298 // cout << minDX << " " << minDY << endl;
299
300 if (minIdx == -1)
301 continue;
302 tr->SetScWallCellId(minIdx);
303 tr->SetScWallSignal(fScWall->GetCell(minIdx)->GetSignal());
304 }
305 return kBMNSUCCESS;
306}
307
309{
310 if (fVerbose)
311 cout << "Matching of Ndet started " << fNdet << endl;
312 if (!fNdet)
313 return kBMNERROR;
314 auto* cells = fNdet->GetCells();
315 if (cells->GetEntriesFast() == 0)
316 return kBMNSUCCESS;
317
318 for (Int_t trIdx = 0; trIdx < fGlobalTracks->GetEntriesFast(); ++trIdx) {
320 FairTrackParam par(*(tr->GetParamLast()));
321
322 for (int ice = 0, nce = cells->GetEntriesFast(); ice < nce; ++ice) {
323 auto* cell = static_cast<BmnNdetCell*>(cells->At(ice));
324 if (!cell)
325 continue;
326 Int_t pdg = (tr->GetP() > 0) ? 2212 : -211;
327
328 if (fKalman->TGeoTrackPropagate(&par, cell->GetZ(), pdg, nullptr, nullptr) == kBMNERROR)
329 continue;
330
331 Float_t dX = par.GetX() - cell->GetX();
332 Float_t dY = par.GetY() - cell->GetY();
333
334 if (Abs(dX) < 5 * cell->GetDx() && Abs(dY) < 5 * cell->GetDy()) { // TODO remove 5* (after alignment)
335 tr->SetNdetHitIndex(ice);
336 // break;
337 }
338 }
339 }
340 return kBMNSUCCESS;
341}
342
343map<Float_t, pair<Int_t, Int_t>> BmnGlobalTracking::FindPairsTof(TClonesArray* tracks,
344 TClonesArray* hits,
345 Bool_t tof400)
346{
347
348 map<Float_t, pair<Int_t, Int_t>> distancesPairs;
349
350 Double_t minZ = 10000.0;
351 for (Int_t hitIdx = 0; hitIdx < hits->GetEntriesFast(); ++hitIdx) {
352 BmnHit* hit = (BmnHit*)hits->At(hitIdx);
353 if (hit->GetZ() < minZ)
354 minZ = hit->GetZ();
355 }
356
357 for (Int_t trIdx = 0; trIdx < tracks->GetEntriesFast(); ++trIdx) {
358 BmnGlobalTrack* tr = (BmnGlobalTrack*)tracks->At(trIdx);
359 FairTrackParam parMinZ(*(tr->GetParamLast()));
360 Int_t pdg = (tr->GetP() > 0) ? 2212 : -211;
361 if (fKalman->TGeoTrackPropagate(&parMinZ, minZ, pdg, nullptr, nullptr) == kBMNERROR)
362 continue;
363 for (Int_t hitIdx = 0; hitIdx < hits->GetEntriesFast(); ++hitIdx) {
364
365 BmnHit* hit = (BmnHit*)hits->At(hitIdx);
366 FairTrackParam param = parMinZ;
367 if (fKalman->TGeoTrackPropagate(&param, hit->GetZ(), pdg, nullptr, nullptr) == kBMNERROR)
368 continue;
369 Float_t mom = 1.0 / param.GetQp();
370 Int_t chamber = ((hit->GetDetectorID() & 0x0000FF00) >> 8) - 1;
371 Float_t xMomCorr = GetAkimaCorrection(chamber, mom, kTRUE, "stage1", tof400);
372 Float_t yMomCorr = GetAkimaCorrection(chamber, mom, kFALSE, "stage1", tof400);
373
374 Float_t dX = param.GetX() + xMomCorr - hit->GetX();
375 Float_t dY = param.GetY() + yMomCorr - hit->GetY();
376 Float_t dist = Sqrt(dX * dX + dY * dY);
377
378 distancesPairs.insert(pair<Float_t, pair<Int_t, Int_t>>(dist, pair<Int_t, Int_t>(trIdx, hitIdx)));
379 }
380 }
381
382 return distancesPairs;
383}
384
386{
387 FairTrackParam par = *(tr->GetParamFirst());
388 Int_t pdg = (par.GetQp() > 0) ? 2212 : -211;
389 fKalman->TGeoTrackPropagate(&par, -200, pdg, nullptr, nullptr);
390 Double_t Alpha_in = ATan(par.GetTx());
391 // Double_t Bdl = 2.856; //Abs(MagFieldIntegral(par, -200.0, 1000.0, 1.0) * 0.001);
392 Double_t Bdl = Abs(MagFieldIntegral(par, -200.0, 600.0, 1.0) * 0.001);
393 fKalman->TGeoTrackPropagate(&par, 600, pdg, nullptr, nullptr);
394 Double_t Alpha_out = ATan(par.GetTx());
395 // if (tr->GetUpstreamTrackIndex() != -1) {
396 // BmnTrack* upTrack = (BmnTrack*)fUpstreamTracks->At(tr->GetUpstreamTrackIndex());
397 // if (upTrack != nullptr)
398 // Alpha_in = ATan(upTrack->GetParamLast()->GetTx());
399 // }
400 Double_t momInt = 0.3 * Bdl / (Sin(Alpha_out) - Sin(Alpha_in));
401 // Double_t momInt = 0.3 * Bdl / (Alpha_out - Alpha_in);
402 if (!IsNaN(momInt) && Abs(momInt) > 0.01 && Abs(momInt) < 100) {
403 tr->GetParamFirst()->SetQp(1.0 / momInt);
404 }
405 // cout << Alpha_in << " " << Alpha_out << " " << Bdl << " " << momInt << endl;
406
407 return kBMNSUCCESS;
408}
409
411{
412 delete fKalman;
413 printf("Work time of BmnGlobalTracking: %4.2f sec.\n", fTime);
415}
416
418{
419 /*
420 field in kG
421 step in cm
422 */
423 Int_t pdg = (par.GetQp() > 0.) ? 2212 : -211;
424 FairField* field = FairRunAna::Instance()->GetField();
425 fKalman->TGeoTrackPropagate(&par, zMin, pdg, NULL, NULL, kTRUE);
426 Double_t z = par.GetZ();
427 Double_t integral = 0.0;
428 while (z < zMax) {
429 z += step;
430 fKalman->TGeoTrackPropagate(&par, z, pdg, NULL, NULL, kTRUE);
431 integral += field->GetBy(par.GetX(), par.GetY(), par.GetZ());
432 }
433 integral *= step;
434 return integral;
435}
436
438{
439 printf("================================================================================\n");
440 printf("======= Statistics of Global tracking\n");
441 printf("======= Number of input inner tracks: %ld\n", fNInnerTracks);
442 printf("======= Number of input inner tracks with 4+ hits extrapolated to the Vertex: %ld (%4.1f%%)\n",
444 printf("======= Number of tracks matched with TOF-400: %ld\n", fNMatchedTof400);
445 printf("======= Number of tracks matched with TOF-700: %ld\n", fNMatchedTof700);
446 printf("================================================================================\n");
447}
448
449void BmnGlobalTracking::OnlineWrite(const std::unique_ptr<TTree>& resultTree)
450{
451 if (!IsActive())
452 return;
453
454 if (fStsTracks) {
455 resultTree->Branch("BmnGlobalTrack", &fGlobalTracks);
456 }
457 resultTree->Fill();
458}
459
461{
462 std::cout << "\n=== Loading Akima corrections for " << (isTOF400 ? "TOF400" : "TOF700") << " ===" << std::endl;
463 std::cout << "=== File: " << filename << " ===" << std::endl;
464
465 AkimaContainer& cont = isTOF400 ? fAkima400 : fAkima700;
466
467 TFile* file = TFile::Open(filename);
468 if (!file || file->IsZombie()) {
469 std::cerr << "ERROR: Cannot open file: " << filename << std::endl;
470 return;
471 }
472
473 for (Int_t chamber = 0; chamber < numChambers; ++chamber) {
474 TString chamberPath = Form("chamber_%d", chamber);
475 TDirectory* chamberDir = dynamic_cast<TDirectory*>(file->Get(chamberPath));
476 if (!chamberDir)
477 continue;
478
479 TDirectory* stage1Dir = dynamic_cast<TDirectory*>(chamberDir->Get("stage1"));
480 if (stage1Dir) {
481 TDirectory* dxPosDir = dynamic_cast<TDirectory*>(stage1Dir->Get("dx_positive"));
482 if (dxPosDir) {
483 TIter next(dxPosDir->GetListOfKeys());
484 TKey* key;
485 while ((key = (TKey*)next())) {
486 TObject* obj = key->ReadObj();
487 if (obj->InheritsFrom("AkimaFunction")) {
488 cont.dx_stage1_pos[chamber] = (AkimaFunction*)obj;
489 cont.loaded_count++;
490 break;
491 }
492 }
493 }
494
495 TDirectory* dxNegDir = dynamic_cast<TDirectory*>(stage1Dir->Get("dx_negative"));
496 if (dxNegDir) {
497 TIter next(dxNegDir->GetListOfKeys());
498 TKey* key;
499 while ((key = (TKey*)next())) {
500 TObject* obj = key->ReadObj();
501 if (obj->InheritsFrom("AkimaFunction")) {
502 cont.dx_stage1_neg[chamber] = (AkimaFunction*)obj;
503 cont.loaded_count++;
504 break;
505 }
506 }
507 }
508
509 TDirectory* dyPosDir = dynamic_cast<TDirectory*>(stage1Dir->Get("dy_positive"));
510 if (dyPosDir) {
511 TIter next(dyPosDir->GetListOfKeys());
512 TKey* key;
513 while ((key = (TKey*)next())) {
514 TObject* obj = key->ReadObj();
515 if (obj->InheritsFrom("AkimaFunction")) {
516 cont.dy_stage1_pos[chamber] = (AkimaFunction*)obj;
517 cont.loaded_count++;
518 break;
519 }
520 }
521 }
522
523 TDirectory* dyNegDir = dynamic_cast<TDirectory*>(stage1Dir->Get("dy_negative"));
524 if (dyNegDir) {
525 TIter next(dyNegDir->GetListOfKeys());
526 TKey* key;
527 while ((key = (TKey*)next())) {
528 TObject* obj = key->ReadObj();
529 if (obj->InheritsFrom("AkimaFunction")) {
530 cont.dy_stage1_neg[chamber] = (AkimaFunction*)obj;
531 cont.loaded_count++;
532 break;
533 }
534 }
535 }
536 }
537
538 TDirectory* stage2Dir = dynamic_cast<TDirectory*>(chamberDir->Get("stage2"));
539 if (stage2Dir) {
540 TDirectory* dxPosDir = dynamic_cast<TDirectory*>(stage2Dir->Get("dx_positive"));
541 if (dxPosDir) {
542 TIter next(dxPosDir->GetListOfKeys());
543 TKey* key;
544 while ((key = (TKey*)next())) {
545 TObject* obj = key->ReadObj();
546 if (obj->InheritsFrom("AkimaFunction")) {
547 AkimaFunction* func = (AkimaFunction*)obj;
548 TString name = func->GetName();
549 if (name.Contains("mean")) {
550 cont.dx_stage2_mean_pos[chamber] = func;
551 cont.loaded_count++;
552 } else if (name.Contains("sigma")) {
553 cont.dx_stage2_sigma_pos[chamber] = func;
554 cont.loaded_count++;
555 }
556 }
557 }
558 }
559
560 TDirectory* dxNegDir = dynamic_cast<TDirectory*>(stage2Dir->Get("dx_negative"));
561 if (dxNegDir) {
562 TIter next(dxNegDir->GetListOfKeys());
563 TKey* key;
564 while ((key = (TKey*)next())) {
565 TObject* obj = key->ReadObj();
566 if (obj->InheritsFrom("AkimaFunction")) {
567 AkimaFunction* func = (AkimaFunction*)obj;
568 TString name = func->GetName();
569 if (name.Contains("mean")) {
570 cont.dx_stage2_mean_neg[chamber] = func;
571 cont.loaded_count++;
572 } else if (name.Contains("sigma")) {
573 cont.dx_stage2_sigma_neg[chamber] = func;
574 cont.loaded_count++;
575 }
576 }
577 }
578 }
579
580 TDirectory* dyPosDir = dynamic_cast<TDirectory*>(stage2Dir->Get("dy_positive"));
581 if (dyPosDir) {
582 TIter next(dyPosDir->GetListOfKeys());
583 TKey* key;
584 while ((key = (TKey*)next())) {
585 TObject* obj = key->ReadObj();
586 if (obj->InheritsFrom("AkimaFunction")) {
587 AkimaFunction* func = (AkimaFunction*)obj;
588 TString name = func->GetName();
589 if (name.Contains("mean")) {
590 cont.dy_stage2_mean_pos[chamber] = func;
591 cont.loaded_count++;
592 } else if (name.Contains("sigma")) {
593 cont.dy_stage2_sigma_pos[chamber] = func;
594 cont.loaded_count++;
595 }
596 }
597 }
598 }
599
600 TDirectory* dyNegDir = dynamic_cast<TDirectory*>(stage2Dir->Get("dy_negative"));
601 if (dyNegDir) {
602 TIter next(dyNegDir->GetListOfKeys());
603 TKey* key;
604 while ((key = (TKey*)next())) {
605 TObject* obj = key->ReadObj();
606 if (obj->InheritsFrom("AkimaFunction")) {
607 AkimaFunction* func = (AkimaFunction*)obj;
608 TString name = func->GetName();
609 if (name.Contains("mean")) {
610 cont.dy_stage2_mean_neg[chamber] = func;
611 cont.loaded_count++;
612 } else if (name.Contains("sigma")) {
613 cont.dy_stage2_sigma_neg[chamber] = func;
614 cont.loaded_count++;
615 }
616 }
617 }
618 }
619 }
620
621 TDirectory* stage3Dir = dynamic_cast<TDirectory*>(chamberDir->Get("stage3"));
622 if (stage3Dir) {
623 for (const auto& particle : PARTICLES) {
624 TDirectory* particleDir = dynamic_cast<TDirectory*>(stage3Dir->Get(particle.c_str()));
625 if (!particleDir)
626 continue;
627
628 for (const auto& zone : ZONES) {
629 TString dxDirName = Form("dx_%s_%s_positive", particle.c_str(), zone.c_str());
630 TDirectory* dxDir = dynamic_cast<TDirectory*>(particleDir->Get(dxDirName));
631 if (dxDir) {
632 TIter next(dxDir->GetListOfKeys());
633 TKey* key;
634 while ((key = (TKey*)next())) {
635 TObject* obj = key->ReadObj();
636 if (obj->InheritsFrom("AkimaFunction")) {
637 AkimaFunction* func = (AkimaFunction*)obj;
638 TString name = func->GetName();
639 Stage3Key k = {chamber, particle, zone};
640 if (name.Contains("mean")) {
641 cont.dx_stage3_mean[k] = func;
642 cont.loaded_count++;
643 } else if (name.Contains("sigma")) {
644 cont.dx_stage3_sigma[k] = func;
645 cont.loaded_count++;
646 }
647 }
648 }
649 }
650
651 TString dyDirName = Form("dy_%s_%s_positive", particle.c_str(), zone.c_str());
652 TDirectory* dyDir = dynamic_cast<TDirectory*>(particleDir->Get(dyDirName));
653 if (dyDir) {
654 TIter next(dyDir->GetListOfKeys());
655 TKey* key;
656 while ((key = (TKey*)next())) {
657 TObject* obj = key->ReadObj();
658 if (obj->InheritsFrom("AkimaFunction")) {
659 AkimaFunction* func = (AkimaFunction*)obj;
660 TString name = func->GetName();
661 Stage3Key k = {chamber, particle, zone};
662 if (name.Contains("mean")) {
663 cont.dy_stage3_mean[k] = func;
664 cont.loaded_count++;
665 } else if (name.Contains("sigma")) {
666 cont.dy_stage3_sigma[k] = func;
667 cont.loaded_count++;
668 }
669 }
670 }
671 }
672 }
673 }
674 }
675 }
676
677 file->Close();
678 std::cout << "Loaded " << cont.loaded_count << " AkimaFunction objects for " << (isTOF400 ? "TOF400" : "TOF700")
679 << std::endl;
680}
681
683 Float_t qp,
684 Bool_t isDx,
685 const TString& stage,
686 Bool_t isTOF400,
687 const TString& particle,
688 const TString& zone)
689{
690 if (chamber < 0 || chamber >= numChambers)
691 return 0.0;
692
693 AkimaContainer& cont = isTOF400 ? fAkima400 : fAkima700;
694 qp = AdjustQP(qp, isTOF400);
695 std::string region = GetRegionFromQP(qp);
696
697 if (stage == "stage1") {
698 if (isDx) {
699 if (region == "negative") {
700 auto it = cont.dx_stage1_neg.find(chamber);
701 if (it != cont.dx_stage1_neg.end() && it->second)
702 return -it->second->Eval(qp);
703 it = cont.dx_stage1_pos.find(chamber);
704 if (it != cont.dx_stage1_pos.end() && it->second)
705 return -it->second->Eval(-qp);
706 } else {
707 auto it = cont.dx_stage1_pos.find(chamber);
708 if (it != cont.dx_stage1_pos.end() && it->second)
709 return -it->second->Eval(qp);
710 }
711 } else {
712 if (region == "negative") {
713 auto it = cont.dy_stage1_neg.find(chamber);
714 if (it != cont.dy_stage1_neg.end() && it->second)
715 return -it->second->Eval(qp);
716 auto it_pos = cont.dy_stage1_pos.find(chamber);
717 if (it_pos != cont.dy_stage1_pos.end() && it_pos->second)
718 return -it_pos->second->Eval(-qp);
719 } else {
720 auto it = cont.dy_stage1_pos.find(chamber);
721 if (it != cont.dy_stage1_pos.end() && it->second)
722 return -it->second->Eval(qp);
723 }
724 }
725 } else if (stage == "stage2") {
726 if (isDx) {
727 if (region == "negative") {
728 auto it = cont.dx_stage2_mean_neg.find(chamber);
729 if (it != cont.dx_stage2_mean_neg.end() && it->second)
730 return -it->second->Eval(qp);
731 auto it_pos = cont.dx_stage2_mean_pos.find(chamber);
732 if (it_pos != cont.dx_stage2_mean_pos.end() && it_pos->second)
733 return -it_pos->second->Eval(-qp);
734 } else {
735 auto it = cont.dx_stage2_mean_pos.find(chamber);
736 if (it != cont.dx_stage2_mean_pos.end() && it->second)
737 return -it->second->Eval(qp);
738 }
739 } else {
740 if (region == "negative") {
741 auto it = cont.dy_stage2_mean_neg.find(chamber);
742 if (it != cont.dy_stage2_mean_neg.end() && it->second)
743 return -it->second->Eval(qp);
744 auto it_pos = cont.dy_stage2_mean_pos.find(chamber);
745 if (it_pos != cont.dy_stage2_mean_pos.end() && it_pos->second)
746 return -it_pos->second->Eval(-qp);
747 } else {
748 auto it = cont.dy_stage2_mean_pos.find(chamber);
749 if (it != cont.dy_stage2_mean_pos.end() && it->second)
750 return -it->second->Eval(qp);
751 }
752 }
753 } else if (stage == "stage3") {
754 if (qp < 0)
755 return GetAkimaCorrection(chamber, -qp, isDx, "stage2", isTOF400, "", "");
756 if (particle == "" || zone == "")
757 return GetAkimaCorrection(chamber, qp, isDx, "stage2", isTOF400);
758
759 Stage3Key key = {chamber, particle.Data(), zone.Data()};
760
761 if (isDx) {
762 auto it = cont.dx_stage3_mean.find(key);
763 if (it != cont.dx_stage3_mean.end() && it->second)
764 return -it->second->Eval(qp);
765 } else {
766 auto it = cont.dy_stage3_mean.find(key);
767 if (it != cont.dy_stage3_mean.end() && it->second)
768 return -it->second->Eval(qp);
769 }
770 return GetAkimaCorrection(chamber, qp, isDx, "stage2", isTOF400);
771 }
772
773 return 0.0;
774}
775
777 Float_t qp,
778 Bool_t isDx,
779 const TString& stage,
780 Bool_t isTOF400,
781 const TString& particle,
782 const TString& zone)
783{
784 if (chamber < 0 || chamber >= numChambers)
785 return 1.0;
786
787 AkimaContainer& cont = isTOF400 ? fAkima400 : fAkima700;
788 qp = AdjustQP(qp, isTOF400);
789 std::string region = GetRegionFromQP(qp);
790
791 if (stage == "stage2") {
792 if (isDx) {
793 if (region == "negative") {
794 auto it = cont.dx_stage2_sigma_neg.find(chamber);
795 if (it != cont.dx_stage2_sigma_neg.end() && it->second) {
796 Float_t sigma = it->second->Eval(qp);
797 return (sigma > 0) ? sigma : 1.0;
798 }
799 auto it_pos = cont.dx_stage2_sigma_pos.find(chamber);
800 if (it_pos != cont.dx_stage2_sigma_pos.end() && it_pos->second) {
801 Float_t sigma = it_pos->second->Eval(-qp);
802 return (sigma > 0) ? sigma : 1.0;
803 }
804 } else {
805 auto it = cont.dx_stage2_sigma_pos.find(chamber);
806 if (it != cont.dx_stage2_sigma_pos.end() && it->second) {
807 Float_t sigma = it->second->Eval(qp);
808 return (sigma > 0) ? sigma : 1.0;
809 }
810 }
811 } else {
812 if (region == "negative") {
813 auto it = cont.dy_stage2_sigma_neg.find(chamber);
814 if (it != cont.dy_stage2_sigma_neg.end() && it->second) {
815 Float_t sigma = it->second->Eval(qp);
816 return (sigma > 0) ? sigma : 1.0;
817 }
818 auto it_pos = cont.dy_stage2_sigma_pos.find(chamber);
819 if (it_pos != cont.dy_stage2_sigma_pos.end() && it_pos->second) {
820 Float_t sigma = it_pos->second->Eval(-qp);
821 return (sigma > 0) ? sigma : 1.0;
822 }
823 } else {
824 auto it = cont.dy_stage2_sigma_pos.find(chamber);
825 if (it != cont.dy_stage2_sigma_pos.end() && it->second) {
826 Float_t sigma = it->second->Eval(qp);
827 return (sigma > 0) ? sigma : 1.0;
828 }
829 }
830 }
831 return 1.0;
832 } else if (stage == "stage3") {
833 if (qp < 0)
834 return GetAkimaSigma(chamber, -qp, isDx, "stage2", isTOF400, "", "");
835 if (particle == "" || zone == "")
836 return GetAkimaSigma(chamber, qp, isDx, "stage2", isTOF400);
837
838 Stage3Key key = {chamber, particle.Data(), zone.Data()};
839
840 if (isDx) {
841 auto it = cont.dx_stage3_sigma.find(key);
842 if (it != cont.dx_stage3_sigma.end() && it->second) {
843 Float_t sigma = it->second->Eval(qp);
844 return (sigma > 0) ? sigma : 1.0;
845 }
846 } else {
847 auto it = cont.dy_stage3_sigma.find(key);
848 if (it != cont.dy_stage3_sigma.end() && it->second) {
849 Float_t sigma = it->second->Eval(qp);
850 return (sigma > 0) ? sigma : 1.0;
851 }
852 }
853 return GetAkimaSigma(chamber, qp, isDx, "stage2", isTOF400);
854 }
855
856 return 1.0;
857}
858
860{
861 return (qp < 0) ? "negative" : "positive";
862}
863
865{
866 if (isTOF400) {
867 if (qp < 0 && qp > -0.5)
868 return -0.5;
869 if (qp > 0 && qp < 0.5)
870 return 0.5;
871 } else {
872 if (qp < 0 && qp > -0.7)
873 return -0.7;
874 if (qp > 0 && qp < 0.7)
875 return 0.7;
876 }
877 return qp;
878}
const std::vector< std::string > PARTICLES
const std::vector< std::string > ZONES
vector< Double_t > dist(vector< Double_t > qp, Double_t mu)
Definition BmnMath.cxx:869
int i
Definition P4_F32vec4.h:22
bool Bool_t
int Int_t
float Float_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
void Fatal(const char *location, const char *msgfmt,...)
char * Form(const char *fmt,...)
BmnStatus
Define status code.
Definition BmnEnums.h:93
@ kBMNERROR
Error.
Definition BmnEnums.h:95
@ kBMNSUCCESS
Success.
Definition BmnEnums.h:94
BmnGlobalTrack.h.
void SetMass2(Int_t tofID, Float_t m2)
void SetResX(Int_t tofID, Float_t res)
TString GetParticleName(ParticleType type)
void SetNdetHitIndex(Int_t iNdet)
void SetDCAInVertex(Float_t chi)
void SetChi2InVertex(Float_t chi)
void SetGemTrackIndex(Int_t iGem)
Modifiers.
void SetTof2HitIndex(Int_t iTof2Hit)
void SetScWallSignal(Float_t sig)
void SetScWallCellId(Int_t iScWall)
void SetResY(Int_t tofID, Float_t res)
void SetTof1HitIndex(Int_t iTof1Hit)
TClonesArray * fGlobalTracks
BmnGlobalTracking()
Constructor.
Float_t AdjustQP(Float_t qp, Bool_t isTOF400=false)
map< Float_t, pair< Int_t, Int_t > > FindPairsTof(TClonesArray *tracks, TClonesArray *hits, Bool_t tof400)
virtual ~BmnGlobalTracking()
Destructor.
TClonesArray * fTof2Hits
AkimaContainer fAkima400
Float_t GetAkimaSigma(Int_t chamber, Float_t qp, Bool_t isDx, const TString &stage, Bool_t isTOF400, const TString &particle="", const TString &zone="")
virtual void Exec(Option_t *opt)
Inherited from FairTask.
std::string GetRegionFromQP(Float_t qp)
TClonesArray * fCscHits
virtual void OnlineWrite(const std::unique_ptr< TTree > &resultTree)
Write task resul to tree.
TClonesArray * fTof1Hits
Float_t GetAkimaCorrection(Int_t chamber, Float_t qp, Bool_t isDx, const TString &stage, Bool_t isTOF400, const TString &particle="", const TString &zone="")
BmnStatus MatchingTOF(Bool_t tof400)
AkimaContainer fAkima700
virtual InitStatus Init()
Inherited from FairTask.
BmnStatus UpdateMomentum(BmnGlobalTrack *tr)
TClonesArray * fStsTracks
void LoadAllAkimaCorrections(const TString &filename, Bool_t isTOF400)
BmnKalmanFilter * fKalman
vertex information
Double_t MagFieldIntegral(FairTrackParam &par, Double_t zMin, Double_t zMax, Double_t step)
virtual void Finish()
Inherited from FairTask.
BmnScWallEvent * fScWall
void SetLength(Double_t len)
Definition BmnHit.h:50
void SetUsing(Bool_t use)
Definition BmnHit.h:47
Bool_t IsUsed() const
Definition BmnHit.h:30
Class for Bmn Ndet data container in event.
Class for Bmn ScWall module data container in event.
float GetSignal() const
Deposited Signal.
Class for Bmn ScWall data container in event.
void SetChi2(Double_t chi2)
Definition BmnTrack.h:76
Float_t GetLength() const
Definition BmnTrack.h:61
void SetParamLast(FairTrackParam &par)
Definition BmnTrack.h:72
FairTrackParam * GetParamFirst()
Definition BmnTrack.h:63
Int_t GetNHits() const
Accessors.
Definition BmnTrack.h:49
Bool_t IsUsed()
Definition BmnTrack.h:86
Double_t GetP()
Definition BmnTrack.h:67
void SetNHits(Int_t n)
Definition BmnTrack.h:80
void SetUsing(Bool_t flag)
Definition BmnTrack.h:88
void SetParamFirst(FairTrackParam &par)
Modifiers.
Definition BmnTrack.h:70
FairTrackParam * GetParamLast()
Definition BmnTrack.h:65
void SetLength(Double_t length)
Definition BmnTrack.h:84
void SetNDF(Int_t ndf)
Definition BmnTrack.h:78
FairTrackParam * GetParamLast()
Definition CbmStsTrack.h:70
Int_t GetNStsHits() const
Accessors.
Definition CbmStsTrack.h:60
Double_t GetChi2() const
Definition CbmStsTrack.h:66
FairTrackParam * GetParamFirst()
Definition CbmStsTrack.h:69
Int_t GetNDF() const
Definition CbmStsTrack.h:67
CbmVertex.h.
Definition CbmVertex.h:21
T * Get(const char *namecycle)
virtual TObject * Get(const char *namecycle)
virtual TList * GetListOfKeys() const
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
void Close(Option_t *option="") override
const char * GetName() const override
Int_t GetEntriesFast() const
TObject * At(Int_t idx) const override
R__ALWAYS_INLINE Bool_t IsZombie() const
virtual Bool_t InheritsFrom(const char *classname) const
Double_t RealTime()
void Start(Bool_t reset=kTRUE)
void Stop()
const char * Data() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
const UShort_t numChambers
double beta(double x, double y)
Bool_t IsNaN(Double_t x)
constexpr Double_t C()
Double_t ATan(Double_t)
Double_t Sq(Double_t x)
Double_t Sqrt(Double_t x)
Double_t Abs(Double_t d)
Double_t Sin(Double_t)
std::map< Stage3Key, AkimaFunction * > dy_stage3_mean
std::map< Int_t, AkimaFunction * > dx_stage1_neg
std::map< Int_t, AkimaFunction * > dy_stage2_sigma_pos
std::map< Int_t, AkimaFunction * > dy_stage2_mean_neg
std::map< Int_t, AkimaFunction * > dy_stage2_mean_pos
std::map< Stage3Key, AkimaFunction * > dx_stage3_mean
std::map< Int_t, AkimaFunction * > dy_stage2_sigma_neg
std::map< Stage3Key, AkimaFunction * > dy_stage3_sigma
std::map< Int_t, AkimaFunction * > dy_stage1_pos
std::map< Int_t, AkimaFunction * > dx_stage2_sigma_pos
std::map< Int_t, AkimaFunction * > dy_stage1_neg
std::map< Int_t, AkimaFunction * > dx_stage2_mean_pos
std::map< Int_t, AkimaFunction * > dx_stage2_sigma_neg
std::map< Int_t, AkimaFunction * > dx_stage2_mean_neg
std::map< Stage3Key, AkimaFunction * > dx_stage3_sigma
std::map< Int_t, AkimaFunction * > dx_stage1_pos