BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnHypNuclPairFinder.cxx
Go to the documentation of this file.
1
3
4#include "TH1F.h"
5
7
9{
10 if (hyp.Contains("H3L") || hyp.Contains("h3l")) {
13 } else if (hyp.Contains("H4L") || hyp.Contains("h4l")) {
16 } else {
19 }
20 fEventCounter = 0;
21 fKalman = nullptr;
22 fParticlePair = nullptr;
23 fVertex = nullptr;
24 fTrigger = nullptr;
25 fStsHits = nullptr;
26 fUpperGemClusters = nullptr;
27 fLowerGemClusters = nullptr;
28 fUpperFsdClusters = nullptr;
29 fLowerFsdClusters = nullptr;
30 fStsTracks = nullptr;
31 fGlobTracks = nullptr;
32 fTof700Hits = nullptr;
33 fDstHeader = nullptr;
34 isExp = exp;
35 runId = run;
36
37 nSt = 11;
38 nSect = {6, 10, 14, 18, 8, 8, 8, 8, 8, 8, 8};
39 nMomSlices = 6;
40 minMomBound = {0.0, 0.5, 1.0, 1.5, 2.0, 3.0};
41 maxMomBound = {0.5, 1.0, 1.5, 2.0, 3.0, 20.0};
42
43 a = new Double_t**[nSt];
44 b = new Double_t**[nSt];
45 for (Int_t i = 0; i < nSt; ++i) {
46 a[i] = new Double_t*[nSect[i]];
47 b[i] = new Double_t*[nSect[i]];
48 for (Int_t j = 0; j < nSect[i]; ++j) {
49 a[i][j] = new Double_t[nMomSlices];
50 b[i][j] = new Double_t[nMomSlices];
51 for (Int_t k = 0; k < nMomSlices; ++k) {
52 a[i][j][k] = 0.0;
53 b[i][j][k] = 0.0;
54 }
55 }
56 }
57
58 m2CutLowKplsTof700 = new TF1("m2CutLowKplsTof400", "-0.00970*x*x-0.0070*x+0.239", 0, 3.5);
59 m2CutUpKplsTof700 = new TF1("m2CutUpKplsTof400", "0.00462*x*x+0.0357*x+0.279", 0, 3.5);
60 m2CutLowKplsTof400 = new TF1("m2CutLowKplsTof700", "-0.02108*x*x-0.0278*x+0.255", 0, 3.5);
61 m2CutUpKplsTof400 = new TF1("m2CutUpKplsTof700", "0.00284*x*x+0.0434*x+0.256", 0, 3.5);
62
63 if (massPos > 3) { // He4
64 fit_dP_He = new TF1("fit_dP_He", "[0]+[1]*(1+(3.728/x)^2)^[2]");
65 fit_dP_He->SetParameters(0.2010, -0.2875, 0.6414);
66 } else { // He3
67 fit_dP_He = new TF1("fit_dP_He", "[0]+[1]*(1+(2.809/x)^2)^[2]");
68 fit_dP_He->SetParameters(0.0731, -0.1687, 0.8723);
69 }
70
71 alephFit_d = new TF1("alephFit_d", "[0]/(x^([3]))*([1]-x^([3])-TMath::Log([2]+1/(x^([4]))))", 0, 14.5);
72 const Float_t fpar1[5] = {-591.879, -0.537493, 0.338613, -0.00845327,
73 3.16787}; // parameters from fitting hdEdxHe4
74 alephFit_d->SetParameters(fpar1[0], fpar1[1], fpar1[2], fpar1[3], fpar1[4]);
75
76 if (massPos > 3) { // He4
77 m2CutLow = new TF1("m2CutLow", "-0.0236*x*x+0.0240*x+3.1896", 0, 30);
78 m2CutUp = new TF1("m2CutUp", "0.0169*x*x+0.1306*x+4.0525", 0, 30);
79 } else { // He3
80 m2CutLow = new TF1("m2CutLow", "-0.0034*x*x-0.0360*x+1.7426", 0, 30);
81 m2CutUp = new TF1("m2CutUp", "0.0128*x*x-0.1060*x+2.6261", 0, 30);
82 }
83}
84
86{
87 delete m2CutLowKplsTof400;
88 delete m2CutUpKplsTof400;
89 delete m2CutLowKplsTof700;
90 delete m2CutUpKplsTof700;
91 delete fit_dP_He;
92 delete alephFit_d;
93 delete m2CutLow;
94 delete m2CutUp;
95 if (a) {
96 for (Int_t i = 0; i < nSt; ++i) {
97 for (Int_t j = 0; j < nSect[i]; ++j) {
98 delete[] a[i][j];
99 }
100 delete[] a[i];
101 }
102 delete[] a;
103 a = nullptr;
104 }
105 if (b) {
106 for (Int_t i = 0; i < nSt; ++i) {
107 for (Int_t j = 0; j < nSect[i]; ++j) {
108 delete[] b[i][j];
109 }
110 delete[] b[i];
111 }
112 delete[] b;
113 b = nullptr;
114 }
115}
116
118{
119 Float_t VPX = fVertex->GetX();
120 Float_t VPY = fVertex->GetY();
121 Float_t VPZ = fVertex->GetZ();
122
123 fParInVPPos.clear();
124 fParInVPNeg.clear();
125 fM2Pos700.clear();
126 fChi2NDFPos.clear();
127 fChi2NDFNeg.clear();
128 fDedxPos.clear();
129 fNGemHitsNeg.clear();
130 fNGemHitsPos.clear();
131 fNFsdHitsNeg.clear();
132 fNFsdHitsPos.clear();
133
134 Bool_t strangeEvent = kFALSE;
135
136 for (Int_t i = 0; i < fGlobTracks->GetEntriesFast(); i++) {
137 BmnGlobalTrack* gl = (BmnGlobalTrack*)fGlobTracks->UncheckedAt(i);
138 if (IsKaPlus(gl)) {
139 strangeEvent = kTRUE;
140 break;
141 }
142 }
143
144 if (!strangeEvent)
145 return;
146
147 for (Int_t i = 0; i < fGlobTracks->GetEntriesFast(); i++) {
148 BmnGlobalTrack* gl = (BmnGlobalTrack*)fGlobTracks->UncheckedAt(i);
150
151 if (sts->GetB() < -0.1) // TMVA cut for good tracks
152 continue;
153
154 if (sts->GetNStsHits() < 4)
155 continue;
156
157 FairTrackParam par = *(sts->GetParamFirst());
158 const Float_t tZ = -0.01942; // z-coordinate of target for RUN-8
159 if (fKalman->TGeoTrackPropagate(&par, tZ, fPDG1, nullptr, nullptr) == kBMNERROR)
160 continue;
161
162 Int_t nGEM = 0;
163 Int_t nFSD = 0;
164 GetNHits(sts, nGEM, nFSD);
165
166 Float_t mom = gl->GetP();
167 if (mom > 0) { // He3/He4
168
169 Float_t dedx = GetdEdx(sts); // gl->GetdQdNLower();
170 Float_t m2 = gl->GetMass2(2);
171 // ============================================================
172 // Отбор по dE/dx.
173 //
174 // 1. dedx < 0 — GetdEdx() не смог измерить (мало хитов,
175 // импульс вне диапазона и т.п.). Отбрасываем трек
176 // явно.
177 //
178 // 2. alephFit_d определена на [0, 14.5]. Вне этого
179 // диапазона Eval() возвращает 0 или мусор, что даёт
180 // inf/nan при делении. Отбрасываем такие треки явно.
181 //
182 // 3. Eval() может вернуть <= 0 для некоторых mom —
183 // защищаемся от деления на ноль/отрицательное.
184 // ============================================================
185 if (dedx < 0.0)
186 continue;
187
188 if (mom > 14.5)
189 continue;
190
191 const Float_t expectedDedx = alephFit_d->Eval(mom);
192 if (expectedDedx <= 0.0)
193 continue;
194
195 if (dedx / expectedDedx < 2.25)
196 continue;
197
198 fDedxPos.push_back(dedx);
199 fM2Pos700.push_back(m2);
200
201 fParInVPPos.push_back(par);
202 fChi2NDFPos.push_back(sts->GetChi2() / sts->GetNDF());
203 fNGemHitsPos.push_back(nGEM);
204 fNFsdHitsPos.push_back(nFSD);
205 } else { // pi-
206 fParInVPNeg.push_back(par);
207 fChi2NDFNeg.push_back(sts->GetChi2() / sts->GetNDF());
208 fNGemHitsNeg.push_back(nGEM);
209 fNFsdHitsNeg.push_back(nFSD);
210 }
211 }
212
213 for (size_t i = 0; i < fParInVPPos.size(); ++i) {
214 for (size_t j = 0; j < fParInVPNeg.size(); ++j) {
215
216 FairTrackParam VP1 = fParInVPPos[i];
217 FairTrackParam VP2 = fParInVPNeg[j];
218 FairTrackParam V01 = fParInVPPos[i];
219 FairTrackParam V02 = fParInVPNeg[j];
220
221 const Float_t kFindV0Range = 30.0f; // см
222
223 Float_t V0Z = FindV0ByVirtualPlanes(&V01, &V02, VPZ, kFindV0Range);
224 if (V0Z > 15 || V0Z < 0)
225 continue;
226
227 V01 = fParInVPPos[i];
228 V02 = fParInVPNeg[j];
229
230 fKalman->TGeoTrackPropagate(&V01, V0Z, fPDG1, nullptr, nullptr, kTRUE);
231 fKalman->TGeoTrackPropagate(&V02, V0Z, fPDG2, nullptr, nullptr, kTRUE);
232
233 Float_t V0X1 = V01.GetX();
234 Float_t V0X2 = V02.GetX();
235 Float_t V0Y1 = V01.GetY();
236 Float_t V0Y2 = V02.GetY();
237 Float_t VPX1 = VP1.GetX();
238 Float_t VPX2 = VP2.GetX();
239 Float_t VPY1 = VP1.GetY();
240 Float_t VPY2 = VP2.GetY();
241
242 Float_t V0X = .5 * (V0X1 + V0X2);
243 Float_t V0Y = .5 * (V0Y1 + V0Y2);
244 Float_t path = Sqrt(Sq(V0X - VPX) + Sq(V0Y - VPY) + Sq(V0Z - VPZ));
245
246 BmnHypNuclPair partPair;
247
248 partPair.SetM2(fM2Pos700[i]);
249 partPair.SetChi2NDF(fChi2NDFPos[i], fChi2NDFNeg[j]);
250
251 Float_t cV01_00 = V01.GetCovariance(0, 0);
252 Float_t cV01_01 = V01.GetCovariance(0, 1);
253 Float_t cV01_11 = V01.GetCovariance(1, 1);
254
255 Float_t cV02_00 = V02.GetCovariance(0, 0);
256 Float_t cV02_01 = V02.GetCovariance(0, 1);
257 Float_t cV02_11 = V02.GetCovariance(1, 1);
258
259 Float_t cVP1_00 = VP1.GetCovariance(0, 0);
260 Float_t cVP1_01 = VP1.GetCovariance(0, 1);
261 Float_t cVP1_11 = VP1.GetCovariance(1, 1);
262
263 Float_t cVP2_00 = VP2.GetCovariance(0, 0);
264 Float_t cVP2_01 = VP2.GetCovariance(0, 1);
265 Float_t cVP2_11 = VP2.GetCovariance(1, 1);
266
267 Float_t dx12 = V0X2 - V0X1;
268 Float_t dy12 = V0Y2 - V0Y1;
269 Float_t chi2_DCA12 = ComputeChi2_2D(dx12, dy12, cV01_00, cV01_01, cV01_11, cV02_00, cV02_01, cV02_11);
270 if (chi2_DCA12 < 0.0)
271 continue;
272
273 Float_t dx1 = VPX1 - VPX;
274 Float_t dy1 = VPY1 - VPY;
275
276 Float_t cVtx_00 = fVertex->GetCovariance(0, 0);
277 Float_t cVtx_01 = 0.0f;
278 Float_t cVtx_11 = fVertex->GetCovariance(1, 1);
279
280 Float_t chi2_DCA1 = ComputeChi2_2D(dx1, dy1, cVP1_00, cVP1_01, cVP1_11, cVtx_00, cVtx_01, cVtx_11);
281 if (chi2_DCA1 < 0.0)
282 continue;
283 Float_t dx2 = VPX2 - VPX;
284 Float_t dy2 = VPY2 - VPY;
285 Float_t chi2_DCA2 = ComputeChi2_2D(dx2, dy2, cVP2_00, cVP2_01, cVP2_11, cVtx_00, cVtx_01, cVtx_11);
286 if (chi2_DCA2 < 0.0)
287 continue;
288 partPair.SetPath(path);
289
291
292 Float_t p1 = Abs(1. / V01.GetQp());
293 p1 *= 2.0; // p1 is actually p1/Q, Q is 2 for helium
294 p1 -= fit_dP_He->Eval(p1);
295 Float_t p2 = Abs(1. / V02.GetQp());
296 Float_t Tx1 = V01.GetTx();
297 Float_t Ty1 = V01.GetTy();
298 Float_t Tx2 = V02.GetTx();
299 Float_t Ty2 = V02.GetTy();
300 Float_t A1 = 1. / Sqrt(Tx1 * Tx1 + Ty1 * Ty1 + 1);
301 Float_t A2 = 1. / Sqrt(Tx2 * Tx2 + Ty2 * Ty2 + 1);
302 Float_t pz1 = p1 * A1;
303 Float_t pz2 = p2 * A2;
304 Float_t px1 = Tx1 * pz1;
305 Float_t px2 = Tx2 * pz2;
306 Float_t py1 = Ty1 * pz1;
307 Float_t py2 = Ty2 * pz2;
308
309 partPair.SetMomXYZ1(px1, py1, pz1);
310 partPair.SetMomXYZ2(px2, py2, pz2);
311
312 Float_t PzPart0 = pz1 + pz2;
313 Float_t PxPart0 = px1 + px2;
314 Float_t PyPart0 = py1 + py2;
315 Float_t TxPart0 = PxPart0 / PzPart0;
316 Float_t TyPart0 = PyPart0 / PzPart0;
317 Float_t xPart0 = TxPart0 * (VPZ - V0Z) + V0X;
318 Float_t yPart0 = TyPart0 * (VPZ - V0Z) + V0Y;
319 Float_t dx0 = xPart0 - VPX;
320 Float_t dy0 = yPart0 - VPY;
321
322 Float_t chi2_DCA0 = ComputeChi2_2D(dx0, dy0, cVtx_00, cVtx_01, cVtx_11, cVtx_00, cVtx_01, cVtx_11);
323 if (chi2_DCA0 < 0.0)
324 continue;
325 partPair.SetChi2DCA1(chi2_DCA1);
326 partPair.SetChi2DCA2(chi2_DCA2);
327 partPair.SetChi2DCA12(chi2_DCA12);
328 partPair.SetChi2DCA0(chi2_DCA0);
329
330 partPair.SetDedx(fDedxPos[i]);
331
332 const Double_t E1 =
333 TMath::Sqrt(static_cast<Double_t>(px1) * px1 + static_cast<Double_t>(py1) * py1
334 + static_cast<Double_t>(pz1) * pz1 + static_cast<Double_t>(massPos) * massPos);
335 const Double_t E2 =
336 TMath::Sqrt(static_cast<Double_t>(px2) * px2 + static_cast<Double_t>(py2) * py2
337 + static_cast<Double_t>(pz2) * pz2 + static_cast<Double_t>(massNeg) * massNeg);
338
339 const Double_t E = E1 + E2;
340 const Double_t Px = static_cast<Double_t>(px1) + px2;
341 const Double_t Py = static_cast<Double_t>(py1) + py2;
342 const Double_t Pz = static_cast<Double_t>(pz1) + pz2;
343
344 const Double_t m2 = E * E - Px * Px - Py * Py - Pz * Pz;
345 const Double_t m = (m2 > 0.0) ? TMath::Sqrt(m2) : 0.0;
346
347 partPair.SetInvMass(static_cast<Float_t>(m));
348
349 partPair.SetNTrInEvent(fVertex->GetNTracks());
350
351 new ((*fParticlePair)[fParticlePair->GetEntriesFast()]) BmnHypNuclPair(partPair);
352 }
353 }
354}
355
357{
358 cout << "\nBmnHypNuclPairFinder::Init()" << endl;
359
360 FairRootManager* ioman = FairRootManager::Instance();
361
362 fStsTracks = (TClonesArray*)ioman->GetObject("StsVector");
363 fGlobTracks = (TClonesArray*)ioman->GetObject("BmnGlobalTrack");
364 fStsHits = (TClonesArray*)ioman->GetObject("StsHit");
365 fVertex = (CbmVertex*)ioman->GetObject("MpdVertex.");
366 fTrigger = (BmnTrigInfoDst*)ioman->GetObject("BmnTrigInfo.");
367 fUpperGemClusters = (TClonesArray*)ioman->GetObject("BmnGemUpperCluster");
368 fLowerGemClusters = (TClonesArray*)ioman->GetObject("BmnGemLowerCluster");
369 fUpperFsdClusters = (TClonesArray*)ioman->GetObject("BmnSiliconUpperCluster");
370 fLowerFsdClusters = (TClonesArray*)ioman->GetObject("BmnSiliconLowerCluster");
371 fTof700Hits = (TClonesArray*)ioman->GetObject("BmnTof700Hit");
372 fDstHeader = (DstEventHeader*)ioman->GetObject("DstEventHeader.");
373
374 fParticlePair = new TClonesArray("BmnHypNuclPair");
375 ioman->Register("pairs", "HYP", fParticlePair, kTRUE);
376
377 fKalman = new BmnKalmanFilter();
378
379 TString dir = getenv("VMCWORKDIR");
380 if (dir.IsNull()) {
381 Error("Init", "VMCWORKDIR is not set — cannot locate calibration.root");
382 return kERROR;
383 }
384
385 TString calibPath = dir + "/input/calibration.root";
386 TFile* calibFile = TFile::Open(calibPath);
387 if (!calibFile || calibFile->IsZombie()) {
388 Error("Init", "Cannot open calibration file: %s", calibPath.Data());
389 return kERROR;
390 }
391
392 for (Int_t i = 0; i < nSt; ++i) {
393 for (Int_t j = 0; j < nSect[i]; ++j) {
394 for (Int_t k = 0; k < nMomSlices; ++k) {
395 TH1F* hA = (TH1F*)calibFile->Get(Form("hA_run_%d_%d_%d", i, j, k));
396 TH1F* hB = (TH1F*)calibFile->Get(Form("hB_run_%d_%d_%d", i, j, k));
397
398 if (!hA || !hB) {
399 Warning("Init",
400 "Missing calibration histograms for (i=%d, j=%d, k=%d) — "
401 "setting a=b=0",
402 i, j, k);
403 a[i][j][k] = 0.0;
404 b[i][j][k] = 0.0;
405 continue;
406 }
407
408 a[i][j][k] = hA->GetBinContent(hA->FindBin(runId));
409 b[i][j][k] = hB->GetBinContent(hB->FindBin(runId));
410 }
411 }
412 }
413
414 calibFile->Close();
415 delete calibFile;
416 calibFile = nullptr;
417
418 constexpr size_t kReserveSize = 128;
419
420 fParInVPPos.reserve(kReserveSize);
421 fParInVPNeg.reserve(kReserveSize);
422 fM2Pos700.reserve(kReserveSize);
423 fChi2NDFPos.reserve(kReserveSize);
424 fChi2NDFNeg.reserve(kReserveSize);
425 fDedxPos.reserve(kReserveSize);
426 fNGemHitsNeg.reserve(kReserveSize);
427 fNGemHitsPos.reserve(kReserveSize);
428 fNFsdHitsNeg.reserve(kReserveSize);
429 fNFsdHitsPos.reserve(kReserveSize);
430
431 return kSUCCESS;
432}
433
434// -------------------------------------------------------------------
435
437{
438 fParticlePair->Delete();
439
441
442 if (fEventCounter % 1000 == 0)
443 cout << "Event# " << fEventCounter << endl;
444
445 if (isExp) {
446 if (!(fTrigger->IsTriggerBitTrueAR(7))) // bit #7 is for CCT2
447 return;
448 if (fVertex->GetNTracks() < 2)
449 return;
450 if (fVertex->GetZ() < -0.5 || fVertex->GetZ() > +0.5)
451 return;
452
453 Float_t centerOfTargetX = 0.40;
454 Float_t centerOfTargetY = 0.15;
455 Float_t radiusOfTarget = 1.2;
456
457 if (TMath::Sqrt(TMath::Sq(fVertex->GetX() - centerOfTargetX) + TMath::Sq(fVertex->GetY() - centerOfTargetY))
458 > radiusOfTarget)
459 return;
460 }
461 Analysis();
462}
463// -------------------------------------------------------------------
464
466{
467 delete fKalman;
468 // delete fMagField;
469 cout << "\n-I- [BmnHypNuclPairFinder::Finish] " << endl;
470}
471
473 FairTrackParam* par2,
474 Float_t z_0,
475 Float_t range)
476{
477 const FairTrackParam par1_initial = *par1;
478 const FairTrackParam par2_initial = *par2;
479
480 const Int_t nPlanes = 5; // FIXME: можно адаптивно (5 → 3)
481
482 Float_t minDist2 = numeric_limits<Float_t>::max();
483 Float_t minZ = z_0;
484
485 while (range >= 0.1) {
486 const Float_t zMax = z_0 + range;
487 const Float_t zMin = z_0 - range;
488 const Float_t zStep = (zMax - zMin) / nPlanes;
489
490 *par1 = par1_initial;
491 *par2 = par2_initial;
492
493 minDist2 = numeric_limits<Float_t>::max();
494 minZ = z_0;
495
496 for (Int_t iPlane = 0; iPlane < nPlanes; ++iPlane) {
497 const Float_t z = zMax - iPlane * zStep;
498
499 FairTrackParam p1 = par1_initial;
500 FairTrackParam p2 = par2_initial;
501
502 BmnStatus stat1 = fKalman->TGeoTrackPropagate(&p1, z, fPDG1, nullptr, nullptr, kTRUE);
503 BmnStatus stat2 = fKalman->TGeoTrackPropagate(&p2, z, fPDG2, nullptr, nullptr, kTRUE);
504
505 if (stat1 == kBMNERROR || stat2 == kBMNERROR)
506 return DBL_MAX;
507
508 const Float_t dx = p1.GetX() - p2.GetX();
509 const Float_t dy = p1.GetY() - p2.GetY();
510 const Float_t d2 = dx * dx + dy * dy;
511
512 if (d2 < minDist2) {
513 minDist2 = d2;
514 minZ = z;
515 }
516 }
517
518 if (TMath::Abs(minZ - z_0) < 0.01)
519 break;
520
521 z_0 = minZ;
522 range *= 0.5;
523 }
524
525 return z_0;
526}
527
529{
530 if (!isExp)
531 return -1.0f;
532
533 // TODO: когда Q появится в BmnGlobalTrack,
534 // добавить проверку if (Q != 2) return -1.0f;
535 // Это сразу отсечёт π⁻, K⁺, p и оставит только He3/He4. Этот метод будет не нужен.
536
537 Float_t p = 1.0 / tr->GetParamFirst()->GetQp();
538 if (p < 0.0 || p > 20)
539 return -1.0f;
540
541 Int_t momIdx = -1;
542 for (Int_t iP = 0; iP < nMomSlices; ++iP) {
543 if (p > minMomBound[iP] && p < maxMomBound[iP]) {
544 momIdx = iP;
545 break;
546 }
547 }
548 if (momIdx == -1)
549 return -1.0f;
550
551 // ============================================================
552 // Собираем сигналы в статический массив.
553 //
554 // std::set (старая версия) даёт автоматическую сортировку,
555 // но платит за это аллокацией на каждый элемент и O(log n)
556 // на вставку. std::array + std::nth_element — zero аллокаций
557 // и O(n) в среднем.
558 //
559 // Логика truncated mean сохранена: после nth_element первые
560 // usedHits элементов — наименьшие, они и усредняются.
561 // Ландау-хвост (наибольшие) отбрасывается.
562 //
563 // ВАЖНО: в отличие от std::set, std::array НЕ удаляет
564 // дубликаты. Если два хита дают одинаковый dE/dx, оба
565 // учитываются. Для truncated mean это не критично —
566 // важны значения, а не число повторов.
567 // ============================================================
568 constexpr Int_t kMaxHits = 64;
569 std::array<Float_t, kMaxHits> signalsLow;
570 Int_t nSignals = 0;
571
572 Int_t nHits = tr->GetNStsHits();
573 for (Int_t hitIdx = 0; hitIdx < nHits; ++hitIdx) {
574 CbmStsHit* hit = (CbmStsHit*)fStsHits->At(tr->GetStsHitIndex(hitIdx));
575
576 Int_t sect = hit->GetSectorNr() - 1;
577 Int_t st = hit->GetStationNr() - 1;
578
579 StripCluster low;
580 if (hit->GetSystemId() == kGEM) {
581 low = *((StripCluster*)fLowerGemClusters->At(hit->fDigiF % 1000000));
582 } else if (hit->GetSystemId() == kSILICON) {
583 low = *((StripCluster*)fLowerFsdClusters->At(hit->fDigiF % 1000000));
584 } else {
585 continue;
586 }
587
588 if (nSignals >= kMaxHits)
589 break; // защита от переполнения
590
591 signalsLow[nSignals++] = low.TotalSignal * a[st][sect][momIdx] + b[st][sect][momIdx];
592 }
593
594 if (nSignals == 0)
595 return -1.0f;
596
597 Int_t usedHits = (nHits == 3) ? 2
598 : (nHits == 4) ? 2
599 : (nHits == 5) ? 3
600 : (nHits == 6) ? 4
601 : (nHits == 7) ? 4
602 : (nHits == 8) ? 5
603 : (nHits == 9) ? 6
604 : (nHits == 10) ? 6
605 : (nHits > 10) ? 7
606 : 0;
607
608 if (usedHits <= 0)
609 return -1.0f;
610
611 if (usedHits > nSignals)
612 usedHits = nSignals;
613
614 // nth_element: первые usedHits — наименьшие (не отсортированы,
615 // но это и не нужно — нам важна только сумма)
616 std::nth_element(signalsLow.begin(), signalsLow.begin() + usedHits, signalsLow.begin() + nSignals);
617
618 Float_t totSigLow = 0.0f;
619 for (Int_t i = 0; i < usedHits; ++i)
620 totSigLow += signalsLow[i];
621
622 return totSigLow / usedHits;
623}
624
626{
627 nGEM = 0;
628 nFSD = 0;
629 for (Int_t hitIdx = 0; hitIdx < tr->GetNStsHits(); ++hitIdx) {
630 CbmStsHit* hit = (CbmStsHit*)fStsHits->At(tr->GetStsHitIndex(hitIdx));
631
632 if (hit->GetSystemId() == kGEM)
633 nGEM++;
634 else if (hit->GetSystemId() == kSILICON)
635 nFSD++;
636 }
637}
638
640{
641
642 Float_t m2tof400 = gl->GetMass2(1); // M2 by tof400
643 Float_t m2tof700 = gl->GetMass2(2); // M2 by tof700
644 Float_t p = gl->GetP();
645
646 if (p > 3.5 || p < 0.0)
647 return kFALSE;
648
649 // BOTH TOFs
650 return (m2tof400 < m2CutUpKplsTof400->Eval(p) && m2tof400 > m2CutLowKplsTof400->Eval(p))
651 || (m2tof700 < m2CutUpKplsTof700->Eval(p) && m2tof700 > m2CutLowKplsTof700->Eval(p));
652
653 // TOF400
654 // return (m2tof400 < m2CutUpKplsTof400->Eval(p) && m2tof400 > m2CutLowKplsTof400->Eval(p));
655
656 // TOF700
657 // return (m2tof700 < m2CutUpKplsTof700->Eval(p) && m2tof700 > m2CutLowKplsTof700->Eval(p));
658}
659
int i
Definition P4_F32vec4.h:22
__m128 m
Definition P4_F32vec4.h:27
bool Bool_t
int Int_t
float Float_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
#define ClassImp(name)
void Error(const char *location, const char *msgfmt,...)
void Warning(const char *location, const char *msgfmt,...)
char * Form(const char *fmt,...)
@ kSILICON
@ kGEM
BmnStatus
Define status code.
Definition BmnEnums.h:93
@ kBMNERROR
Error.
Definition BmnEnums.h:95
BmnGlobalTrack.h.
Int_t GetGemTrackIndex() const
Accessors.
Float_t GetMass2(Int_t tofID) const
virtual InitStatus Init()
vector< Short_t > fNFsdHitsNeg
Bool_t IsKaPlus(BmnGlobalTrack *gl)
TClonesArray * fUpperFsdClusters
BmnKalmanFilter * fKalman
virtual void Exec(Option_t *option)
void GetNHits(CbmStsTrack *tr, Int_t &nGEM, Int_t &nFSD)
TClonesArray * fLowerGemClusters
TClonesArray * fUpperGemClusters
vector< FairTrackParam > fParInVPNeg
vector< Float_t > fM2Pos700
TClonesArray * fLowerFsdClusters
vector< Float_t > minMomBound
vector< Short_t > fNGemHitsNeg
vector< Float_t > fChi2NDFPos
vector< Short_t > fNFsdHitsPos
vector< Float_t > maxMomBound
Float_t GetdEdx(CbmStsTrack *tr)
TClonesArray * fStsHits
event counter
static Float_t ComputeChi2_2D(Float_t dx, Float_t dy, Float_t c1_00, Float_t c1_01, Float_t c1_11, Float_t c2_00, Float_t c2_01, Float_t c2_11)
vector< Float_t > fDedxPos
vector< Float_t > fChi2NDFNeg
vector< Short_t > fNGemHitsPos
DstEventHeader * fDstHeader
vector< FairTrackParam > fParInVPPos
Float_t FindV0ByVirtualPlanes(FairTrackParam *par1, FairTrackParam *par2, Float_t z_0, Float_t range=50.)
void SetChi2DCA1(Float_t v)
void SetM2(Float_t val)
void SetChi2DCA0(Float_t v)
void SetChi2DCA2(Float_t v)
void SetInvMass(Float_t val)
void SetChi2NDF(Float_t val1, Float_t val2)
void SetNTrInEvent(Int_t n)
void SetPath(Float_t val)
void SetDedx(Float_t val)
void SetChi2DCA12(Float_t v)
void SetMomXYZ2(Float_t px, Float_t py, Float_t pz)
void SetMomXYZ1(Float_t px, Float_t py, Float_t pz)
void SetNHitsPair(Short_t nFsd1, Short_t nGem1, Short_t nFsd2, Short_t nGem2)
Double_t GetP()
Definition BmnTrack.h:67
virtual Int_t GetStationNr() const
Definition CbmStsHit.h:67
Int_t GetSectorNr() const
Definition CbmStsHit.h:68
Int_t GetSystemId() const
Accessors.
Definition CbmStsHit.h:66
Int_t fDigiF
Definition CbmStsHit.h:101
Double_t GetB() const
Definition CbmStsTrack.h:68
Int_t GetNStsHits() const
Accessors.
Definition CbmStsTrack.h:60
Double_t GetChi2() const
Definition CbmStsTrack.h:66
Int_t GetStsHitIndex(Int_t iHit) const
Definition CbmStsTrack.h:62
FairTrackParam * GetParamFirst()
Definition CbmStsTrack.h:69
Int_t GetNDF() const
Definition CbmStsTrack.h:67
CbmVertex.h.
Definition CbmVertex.h:21
Double_t TotalSignal
T * Get(const char *namecycle)
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
virtual Double_t GetBinContent(Int_t bin) const
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
R__ALWAYS_INLINE Bool_t IsZombie() const
const char * Data() const
Bool_t IsNull() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
RVec< PromoteType< T > > exp(const RVec< T > &v)
constexpr Double_t E()
Double_t Sq(Double_t x)
Double_t Sqrt(Double_t x)
Double_t Abs(Double_t d)