BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
BmnTofHitProducer.cxx
Go to the documentation of this file.
1#include "BmnTofHitProducer.h"
2
3#include "BmnTOFPoint.h"
4#include "BmnTofHit.h"
5// #include "BmnTofGeoUtils.h"
6#include "CbmMCTrack.h"
7#include "FairLogger.h"
8#include "FairRootManager.h"
9#include "TFile.h"
10
11#include <TEfficiency.h>
12#include <TGeoBBox.h>
13#include <TGeoManager.h>
14#include <TGeoMatrix.h>
15#include <TH1D.h>
16#include <TH2D.h>
17#include <TRandom2.h>
18#include <TStopwatch.h>
19#include <TVector3.h>
20#include <assert.h>
21#include <map>
22
23#define MAKE_CLUSTERS 1
24#define OCCUPANCY 1
25#define OCCUPANCY_DEBUG 0
26
27using namespace std;
28
29static Double_t workTime = 0.0;
30
32 const char* geomFile,
33 Bool_t useMCdata,
34 Int_t verbose,
35 Bool_t test)
36 : BmnTofHitProducerIdeal(name, useMCdata, verbose, test)
37 , fTimeSigma(0.100)
38 , fErrX(1.0)
39 , fErrY(1.0)
40 , pRandom(nullptr)
41 , fDoINL(true)
42 , fDoSlewing(true)
43 , h1TestDistance(nullptr)
44 , h2TestNeighborPair(nullptr)
45 , h2TestStrips(nullptr)
46 , fSignalVelosity(1.0 / 16.0)
47{
48 fgeomFile = geomFile;
49 fMCTimeFile = NULL;
51 fMainStripSelection = 0; // 0 - minimal time, != 0 - maximal amplitude
52 fSelectXYCalibration = 2; // 0 - Petukhov, 1 - Panin, 2 - new Petukhov
53 fTimeMin = -2.f; // Minimal digit time, ns
54 fTimeMax = +15.f; // Maximal digit time, ns
55 fDiffTimeMaxSmall = 1.3f; // Maximal abs time difference, small chambers
56 fDiffTimeMaxBig = 4.0f; // Maximal abs time difference, big chambers
57
58 if (fDoTest) {
59 fTestFlnm = "test.BmnTofHitProducer.root";
61 new TEfficiency("TOF700_effSingleHit", "Efficiency single hit;R, cm;Side", 10000, -0.1, 2.);
64 new TEfficiency("TOF700_effDoubleHit", "Efficiency double hit;R, cm;Side", 10000, -0.1, 2.);
66 h1TestDistance = new TH1D("TOF700_TestDistance", "Distance between strips;M, cm;Side", 1000, 0., 100.);
67 fList.Add(h1TestDistance);
68 // h2TestStrips = new TH2D("TOF700_TestStrips", ";Z,
69 // cm;#phi, rads", 2000, -300., 300., 500, -3.5, 3.5);
70 // fList.Add(h1TestStrips);
71
72 h2TestNeighborPair = new TH2D("TOF700_TestNeighborPair", "Neighbor strip pairs test;stripID1;stripID2", 100,
73 -0.5, 49.5, 100, -0.5, 49.5);
74 fList.Add(h2TestNeighborPair);
75 h2TestXYSmeared = new TH2D("TOF700_TestXYSmeared", "Smeared XY (single hit) test;#DeltaX, cm;#DeltaY, cm", 1000,
76 -1., 1., 1000, -2., 2.);
77 fList.Add(h2TestXYSmeared);
78 h2TestXYSmeared2 = new TH2D("TOF700_TestXYSmeared2", "Smeared XY (single hit) test;X, cm;Y, cm", 1000, -180.,
79 180., 1000, -180., 180.);
80 fList.Add(h2TestXYSmeared2);
82 new TH2D("TOF700_TestXYSmearedDouble", "Smeared XY (double hit) test;#DeltaX, cm;#DeltaY, cm", 1000, -2.,
83 2., 1000, -2., 2.);
84 fList.Add(h2TestXYSmearedDouble);
85 h2TestXYSmearedDouble2 = new TH2D("TOF700_TestXYSmearedDouble2", "Smeared XY (double hit) test;X, cm;Y, cm",
86 1000, -180., 180., 1000, -180., 180.);
87 fList.Add(h2TestXYSmearedDouble2);
88
89 h2TestEtaPhi = new TH2D("TOF700_TestEtaPhi", ";#eta;#phi, degree", 1000, -5., +5., 1000, -181., 181.);
90 fList.Add(h2TestEtaPhi);
91 h2TestRZ = new TH2D("TOF700_TestRZ", ";X, cm;Y, cm", 1000, -300., 300., 1000, -200., 200.);
92 fList.Add(h2TestRZ);
93 h2TdetIdStripId = new TH2D("TOF700_TdetIdStripId", ";stripId;detId", 100, -0.5, 99.5, 26, -0.5, 25.5);
94 fList.Add(h2TdetIdStripId);
95 h1TestMass = new TH1D("TOF700_TestMass", "Mass", 500, 0., 100.);
96 fList.Add(h1TestMass);
97 h1TestMassLong = new TH1D("TOF700_TestMassLong", "Mass - long tracks", 500, 0., 100.);
98 fList.Add(h1TestMassLong);
99 h1TestOccupancyTimeShift = new TH1D("TOF700_TestOccupancyTimeShift", "Occupancy Time Shift", 100, -1., 1.);
100 fList.Add(h1TestOccupancyTimeShift);
102 new TH1D("TOF700_TestOccupancyPositionShift", "Occupancy Position Shift", 200, -10., 10.);
104 }
105}
106
108{
109 delete pRandom;
110 delete pGeoUtils;
111}
112
114{
115 LOG(debug) << "Begin [BmnTof700HitProducer::Init].";
116
117 pRandom = new TRandom2;
118 pGeoUtils = new BmnTofGeoUtils(fUseMCData);
119 pGeoUtils->SetVerbosity(fVerbose);
120
121 if (fOnlyPrimary && fVerbose > 1)
122 LOG(info) << " Only primary particles are processed!!! ";
123
124 if (fUseMCData) {
125 aMcPoints = (TClonesArray*)FairRootManager::Instance()->GetObject("TOF700Point");
126 if (!aMcPoints) {
127 cout << "BmnTof700HitProducer::Init(): branch TOFPoint not found! "
128 "Task will be deactivated"
129 << endl;
130 SetActive(kFALSE);
131 return kERROR;
132 }
133 aMcTracks = (TClonesArray*)FairRootManager::Instance()->GetObject("MCTrack");
134 if (!aMcTracks) {
135 cout << "BmnTof700HitProducer::Init(): branch MCTrack not found! "
136 "Task will be deactivated"
137 << endl;
138 SetActive(kFALSE);
139 return kERROR;
140 }
141 } else {
142 if (strstr(fgeomFile, "_run8"))
143 fTOF2 = new BmnTof2Raw2DigitNew("TOF700_map_period_8.txt", "bmn_run6666_raw.root", 0, 0, fgeomFile);
144 else
145 fTOF2 = new BmnTof2Raw2DigitNew("TOF700_map_period_7.txt", "bmn_run3332_raw.root", 0, 0, fgeomFile);
146
147 aExpDigits = (TClonesArray*)FairRootManager::Instance()->GetObject("TOF700");
148 if (!aExpDigits) {
149 cout << "BmnTof700HitProducer::Init(): branch TOF700 not found! "
150 "Task will be deactivated"
151 << endl;
152 SetActive(kFALSE);
153 return kERROR;
154 }
155 if (fMCTimeFile == NULL) {
156 cout << "BmnTof700HitProducer::Init(): MC times file not defined! "
157 "Use default!"
158 << endl;
159 for (int c = 0; c < TOF2_MAX_CHAMBERS; c++)
160 fMCTime[c] = 21.f;
161 } else {
163 }
164 // Proton hit based corrections
165 for (int c = 0; c < TOF2_MAX_CHAMBERS; c++) {
166 tofcalc[c] = 0.f;
167 for (int s = 0; s < 32; s++) {
168 tofcals[c][s] = 0.f;
169 }
170 }
171 if (fProtonTimeCorrectionFile == NULL) {
172 cout << "BmnTof700HitProducer::Init(): Proton-based time "
173 "corrections file not defined! Don't use corrections!"
174 << endl;
175 } else {
176 TProfile2D* itcalibr = 0;
177 TProfile* itcalibrc = 0;
178 float idchambers[59] = {27.1, 28.1, 3.1, 1.1, 29.1, 4.1, 33.1, 30.1, 5.1, 19.3, 31.1, 6.1,
179 2.1, 32.1, 15.2, 16.2, 17.2, 18.2, 19.2, 20.2, 7.1, 115.2, 113.1, 117.1,
180 35.1, 9.1, 37.1, 11.1, 39.1, 13.1, 34.1, 8.1, 36.1, 10.1, 38.1, 12.1,
181 21.2, 23.2, 25.2, 22.2, 24.2, 26.2, 107.2, 108.2, 109.2, 110.2, 111.2, 112.2,
182 114.1, 116.2, 118.1, 14.1, 40.1, 119.2, 120.2, 121.2, 122.2, 123.2, 124.2};
183 char fname[256];
184 TString dir = getenv("VMCWORKDIR");
185 sprintf(fname, "%s/input/%s", dir.Data(), fProtonTimeCorrectionFile);
186 TFile* fc = new TFile(fname, "READ", "Proton mass based calibration of BmnTOF700");
187 if (fc->IsZombie()) {
188 cout << "BmnTof700HitProducer::Init(): Error open Proton-based "
189 "time corrections file "
190 << fname << endl;
191 return kERROR;
192 }
193 if (CVERS == 0) {
194 itcalibr = (TProfile2D*)fc->Get("tcalibr");
195 itcalibrc = (TProfile*)fc->Get("tcalibrc");
196 } else {
197 itcalibr = (TProfile2D*)fc->Get("tcalibr;1");
198 itcalibrc = (TProfile*)fc->Get("tcalibrc;1");
199 }
200 for (int c = 0; c < TOF2_MAX_CHAMBERS; c++) {
201 tofcalc[c] = itcalibrc->GetBinContent(c + 1);
202 }
204 printf("\n ******************* Time offsets for whole chamber "
205 "**********************\n");
206 for (int c = 0; c < TOF2_MAX_CHAMBERS; c++) {
207 printf("%d %f\n", c, tofcalc[c]);
208 }
209 }
210 if (STRIP_CORRECTIONS) {
212 printf("\n ******************* Time offsets for each strip "
213 "**************************\n");
214 for (int c = 0; c < TOF2_MAX_CHAMBERS; c++) {
216 printf("\n Chamber %d %.1f\n", c, idchambers[c]);
217 int smax = 32;
218 if (idchambers[c] >= 100.f)
219 smax = 16;
220 for (int s = 0; s < smax; s++) {
221 tofcals[c][s] = itcalibr->GetBinContent(c + 1, s + 1);
223 printf(" strip %d %f\n", s, tofcals[c][s]);
224 }
226 printf("\n "
227 "**************************************************"
228 "***********************\n");
229 }
230 }
231 fc->Close();
232 }
233 }
234
235 // Create and register output array
236 aTofHits = new TClonesArray("BmnTofHit");
237 FairRootManager::Instance()->Register("BmnTof700Hit", "TOF", aTofHits, kTRUE);
238
239 // readGeom(geomFile);
240 pGeoUtils->ParseTGeoManager(fUseMCData, h2TestStrips, true);
241 // pGeoUtils->ParseStripsGeometry(fgeomFile);
242 pGeoUtils->FindNeighborStrips(h1TestDistance, h2TestNeighborPair, fDoTest);
243
244 LOG(debug) << "Initialization [BmnTof700HitProducer::Init] finished succesfully.";
245
246 return kSUCCESS;
247}
248//--------------------------------------------------------------------------------------------------------------------------------------
249Bool_t BmnTofHitProducer::HitExist(Double_t val) // val - distance to the pad edge [cm]
250{
251 const static Double_t slope = (0.98 - 0.95) / 0.2;
252 Double_t efficiency = (val > 0.2) ? 0.98 : (0.95 + slope * val);
253 //-------------------------------------
254 // 99% ---------
255 // /
256 // /
257 // /
258 // 95% /
259 // <-----------|--|
260 // 0.2 0.
261 //-------------------------------------
262 if (pRandom->Rndm() < efficiency)
263 return true;
264 return false;
265}
266//------------------------------------------------------------------------------------------------------------------------
267Bool_t BmnTofHitProducer::DoubleHitExist(Double_t val) // val - distance to the pad edge [cm]
268{
269 const static Double_t slope = (0.3 - 0.0) / 0.5;
270 Double_t efficiency = (val > 0.5) ? 0. : (0.3 - slope * val);
271
272 //-------------------------------------
273 // 30% /
274 // /
275 // /
276 // /
277 // 0% /
278 // <-----------|----|
279 // 0.5 0.
280 //-------------------------------------
281
282 if (efficiency == 0.)
283 return false;
284
285 if (pRandom->Rndm() < efficiency)
286 return HitExist(val);
287 return false;
288}
289//--------------------------------------------------------------------------------------------------------------------------------------
291{
292 TStopwatch sw;
293 sw.Start();
294
295 if (!IsActive())
296 return;
297
298 float idchambers[59] = {27.1, 28.1, 3.1, 1.1, 29.1, 4.1, 33.1, 30.1, 5.1, 19.3, 31.1, 6.1,
299 2.1, 32.1, 15.2, 16.2, 17.2, 18.2, 19.2, 20.2, 7.1, 115.2, 113.1, 117.1,
300 35.1, 9.1, 37.1, 11.1, 39.1, 13.1, 34.1, 8.1, 36.1, 10.1, 38.1, 12.1,
301 21.2, 23.2, 25.2, 22.2, 24.2, 26.2, 107.2, 108.2, 109.2, 110.2, 111.2, 112.2,
302 114.1, 116.2, 118.1, 14.1, 40.1, 119.2, 120.2, 121.2, 122.2, 123.2, 124.2};
303
304 if (fVerbose > 1)
305 cout << endl
306 << "======================== TOF700 exec started "
307 "===================="
308 << endl;
309 static const TVector3 XYZ_err(fErrX, fErrY, 0.);
310
311 aTofHits->Clear();
312
313 Int_t UID, trackID;
314 TVector3 pos, XYZ_smeared, mom;
315 int nSingleHits = 0, nDoubleHits = 0;
316
317 if (fUseMCData) {
318 for (Int_t pointIndex = 0, nTofPoint = aMcPoints->GetEntriesFast(); pointIndex < nTofPoint;
319 pointIndex++) // cycle by TOF points
320 {
321 BmnTOFPoint* pPoint = (BmnTOFPoint*)aMcPoints->UncheckedAt(pointIndex);
322
323 if (fVerbose > 2)
324 pPoint->Print("");
325
326 trackID = pPoint->GetTrackID();
327 UID = pPoint->GetDetectorID();
328 if (UID == 1)
329 continue; // TMP!!!
330 Double_t time = 0.;
331 if (OCCUPANCY)
332 time = pPoint->GetTime(); // time rsolution in ps
333 else
334 time = pRandom->Gaus(pPoint->GetTime(),
335 fTimeSigma); // time rsolution in ps
336 Double_t length = pRandom->Gaus(pPoint->GetLength(), 1.); // 1 cm
337 pPoint->Position(pos);
338 pPoint->Momentum(mom);
339 Double_t p = mom.Mag();
340 p = p * (1. + pRandom->Gaus(0.04 * p)); // momentum resolution 4%
341 Double_t cvel = 29.97925;
342 Double_t ct = cvel * time;
343 Double_t ctl = ct / length;
344 Double_t sqr = TMath::Sqrt(ctl * ctl - 1.);
345 Double_t mass = p * sqr;
346 Double_t elcut = 0.; // 0.02e-3;
347 if (fDoTest)
348 if (pPoint->GetEnergyLoss() > elcut)
349 h1TestMass->Fill(mass);
350 if (fDoTest)
351 if (pPoint->GetEnergyLoss() > elcut && length > 600.)
352 h1TestMassLong->Fill(mass);
353 // const LStrip *pStrip = pGeoUtils->FindStrip(UID,
354 // pos);
355 const LStrip* pStrip = pGeoUtils->FindStrip(UID);
356 if (pStrip == NULL)
357 continue;
358
359 // if (UID == ((19<<8)|32)) printf("Hit x %f y %f z
360 //%f, strip x %f y %f z %f\n", pos.X(), pos.Y(), pos.Z(),
361 // pStrip->center.X(), pStrip->center.Y(), pStrip->center.Z());
362
363 if (OCCUPANCY)
364 XYZ_smeared.SetXYZ(pos.X(), pStrip->center.Y(), pStrip->center.Z());
365 else
366 XYZ_smeared.SetXYZ(pRandom->Gaus(pos.X(), fErrX), pStrip->center.Y(), pStrip->center.Z());
367
368 LStrip::Side_t side;
369 Double_t distance = pStrip->MinDistanceToEdge(&pos, side); // [cm]
370
371 bool passed;
372 if ((passed = HitExist(distance)) == true) // check efficiency
373 {
374 AddHit(UID, XYZ_smeared, XYZ_err, pointIndex, trackID, time);
375 nSingleHits++;
376
377 if (fDoTest) {
378 Int_t strip = BmnTOFPoint::GetStrip(UID);
379 Int_t chamber = BmnTOFPoint::GetChamber(UID);
380 h2TestXYSmeared->Fill(pos.X() - XYZ_smeared.X(), pos.Y() - XYZ_smeared.Y());
381 h2TestXYSmeared2->Fill(XYZ_smeared.X(), XYZ_smeared.Y());
382 h2TestEtaPhi->Fill(pos.Eta(), pos.Phi() * TMath::RadToDeg());
383 h2TestRZ->Fill(pos.X(), pos.Y());
384 h2TdetIdStripId->Fill(strip, chamber);
385 }
386 }
387
388 if (fDoTest)
389 effTestEfficiencySingleHit->Fill(passed, distance);
390
391 // if((passed = DoubleHitExist(distance))) // check
392 // cross hit
393 if (false) // check efficiency
394 {
395 Int_t CrossUID = (side == LStrip::kUpper) ? pStrip->neighboring[LStrip::kUpper]
396 : pStrip->neighboring[LStrip::kLower];
397
398 if (LStrip::kInvalid == CrossUID)
399 continue; // last strip on module
400
401 pStrip = pGeoUtils->FindStrip(CrossUID);
402 XYZ_smeared.SetXYZ(pRandom->Gaus(pos.X(), fErrX), pStrip->center.Y(), pStrip->center.Z());
403
404 AddHit(CrossUID, XYZ_smeared, XYZ_err, pointIndex, trackID, time);
405 nDoubleHits++;
406
407 if (fDoTest) {
408 h2TestXYSmearedDouble->Fill((pos - XYZ_smeared).Mag(), pos.Z() - XYZ_smeared.Z());
409 h2TestXYSmearedDouble2->Fill(XYZ_smeared.X(), XYZ_smeared.Y());
410 }
411 }
412
413 if (fDoTest)
414 effTestEfficiencyDoubleHit->Fill(passed, distance);
415
416 } // cycle by the TOF points
417 } else {
418 TVector3 crosspoint;
419 Int_t tofWidths[TOF2_MAX_CHAMBERS][32] = {{0}};
420 Float_t tof[TOF2_MAX_CHAMBERS][32] = {{0.}};
421 Float_t lrdiff[TOF2_MAX_CHAMBERS][32] = {{0.}};
422 if (MAKE_CLUSTERS) {
423 for (Int_t digitIndex = 0,
424 nTof2Digits = aExpDigits->GetEntriesFast();
425 digitIndex < nTof2Digits; digitIndex++) // cycle by TOF digits
426 {
427 BmnTof2Digit* pDigit = (BmnTof2Digit*)aExpDigits->UncheckedAt(digitIndex);
428 UID = ((pDigit->GetPlane() + 1) << 8) | (pDigit->GetStrip() + 1);
429 Int_t strip = pDigit->GetStrip();
430 Int_t chamber = pDigit->GetPlane();
431 tofWidths[chamber][strip] = pDigit->GetAmplitude();
432 tof[chamber][strip] = pDigit->GetTime();
433 lrdiff[chamber][strip] = pDigit->GetDiff();
434 }
435 int ncl0 = 0, ncl[TOF2_MAX_CHAMBERS] = {0};
436 // int clchamb[TOF2_MAX_CHAMBERS] = {0};
437 // int clstrip[TOF2_MAX_CHAMBERS] = {0};
438 for (int i = 0; i < TOF2_MAX_CHAMBERS; i++) {
439 if (fMCTimeFile && fMCTime[i] == 0.f)
440 continue;
441 Double_t DiffTimeMax = fDiffTimeMaxSmall;
442 if (idchambers[i] >= 100.f)
443 DiffTimeMax = fDiffTimeMaxBig;
444 ncl[i] = 0;
445 int clstart = -1, /*clwidth = -1, */ cstr = -1;
446 float samps = 0., timemin = 1000000000., amplmax = 0.;
447 int nstr = 32;
448 if (idchambers[i] >= 100.f)
449 nstr = 16;
450 for (int j = 0; j < nstr; j++) {
451 if (tofWidths[i][j] > 0.) {
452 if (clstart < 0) {
453 clstart = j;
454 timemin = tof[i][j];
455 amplmax = tofWidths[i][j];
456 cstr = j;
457 } else {
458 if (fMainStripSelection == 0 && tof[i][j] < timemin) {
459 timemin = tof[i][j];
460 cstr = j;
461 }
462 if (fMainStripSelection != 0 && tofWidths[i][j] > amplmax) {
463 amplmax = tofWidths[i][j];
464 cstr = j;
465 }
466 }
467 samps += tofWidths[i][j];
468 if (j == (nstr - 1)) {
469 if (tof[i][cstr] > fTimeMin && tof[i][cstr] < fTimeMax
470 && TMath::Abs(lrdiff[i][cstr]) < DiffTimeMax)
471 {
472 // clchamb[ncl0] = i;
473 // clstrip[ncl0] = cstr;
474 // clwidth = (j + 1 - clstart);
475 ncl0++;
476 ncl[i]++;
477 UID = ((i + 1) << 8) | (cstr + 1);
478 Float_t xcl, ycl, zcl;
479 if (fSelectXYCalibration == 0)
480 fTOF2->get_hit_xyz(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
481 else if (fSelectXYCalibration == 1)
482 fTOF2->get_hit_xyzp(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
483 else if (fSelectXYCalibration == 2)
484 fTOF2->get_hit_xyzng(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
485 else if (fSelectXYCalibration == 3)
486 fTOF2->get_hit_xyznl(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
487 else
488 fTOF2->get_hit_xyzng(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
489 if (zcl == 0.) {
490 fTOF2->get_hit_xyz(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
491 }
492 if (zcl != 0.) {
493 crosspoint.SetXYZ(xcl, ycl, zcl);
495 AddHit(UID, crosspoint, XYZ_err, -1, -1,
496 tof[i][cstr] + fMCTime[i] + tofcals[i][cstr]);
497 else
498 AddHit(UID, crosspoint, XYZ_err, -1, -1,
499 tof[i][cstr] + fMCTime[i] + tofcalc[i]);
500 nSingleHits++;
501
502 if (fDoTest) {
503 h2TestXYSmeared2->Fill(crosspoint.X(), crosspoint.Y());
504 Float_t xc, yc, zc;
505 fTOF2->get_strip_xyz(i, cstr, &xc, &yc, &zc);
506 h2TestRZ->Fill(xc, yc);
507 }
508 }
509 }
510 samps = 0.;
511 timemin = 1000000000.;
512 amplmax = 0.;
513 }
514 } else if (clstart >= 0) {
515 if (tof[i][cstr] > fTimeMin && tof[i][cstr] < fTimeMax
516 && TMath::Abs(lrdiff[i][cstr]) < DiffTimeMax)
517 {
518 // clchamb[ncl0] = i;
519 // clstrip[ncl0] = cstr;
520 // clwidth = (j - clstart);
521 ncl0++;
522 ncl[i]++;
523 UID = ((i + 1) << 8) | (cstr + 1);
524 Float_t xcl = 0., ycl = 0., zcl = 0.;
525 if (fSelectXYCalibration == 0)
526 fTOF2->get_hit_xyz(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
527 else if (fSelectXYCalibration == 1)
528 fTOF2->get_hit_xyzp(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
529 else if (fSelectXYCalibration == 2)
530 fTOF2->get_hit_xyzng(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
531 else if (fSelectXYCalibration == 3)
532 fTOF2->get_hit_xyznl(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
533 else
534 fTOF2->get_hit_xyzng(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
535 if (zcl == 0.) {
536 fTOF2->get_hit_xyz(i, cstr, lrdiff[i][cstr], &xcl, &ycl, &zcl);
537 }
538 if (zcl != 0.) {
539 crosspoint.SetXYZ(xcl, ycl, zcl);
541 AddHit(UID, crosspoint, XYZ_err, -1, -1,
542 tof[i][cstr] + fMCTime[i] + tofcals[i][cstr]);
543 else
544 AddHit(UID, crosspoint, XYZ_err, -1, -1, tof[i][cstr] + fMCTime[i] + tofcalc[i]);
545 nSingleHits++;
546
547 if (fDoTest) {
548 h2TestXYSmeared2->Fill(crosspoint.X(), crosspoint.Y());
549 Float_t xc, yc, zc;
550 fTOF2->get_strip_xyz(i, cstr, &xc, &yc, &zc);
551 h2TestRZ->Fill(xc, yc);
552 }
553 }
554 }
555 samps = 0.;
556 timemin = 1000000000.;
557 amplmax = 0.;
558 clstart = -1;
559 }
560 }
561 }
562 } else {
563 for (Int_t digitIndex = 0,
564 nTof2Digits = aExpDigits->GetEntriesFast();
565 digitIndex < nTof2Digits; digitIndex++) // cycle by TOF digits
566 {
567 BmnTof2Digit* pDigit = (BmnTof2Digit*)aExpDigits->UncheckedAt(digitIndex);
568 UID = ((pDigit->GetPlane() + 1) << 8) | (pDigit->GetStrip() + 1);
569 Int_t strip = pDigit->GetStrip();
570 Int_t chamber = pDigit->GetPlane();
571 if (fMCTimeFile && fMCTime[chamber] == 0.f)
572 continue;
573 // if (chamber > 40 && strip > 15)
574 // continue; printf("C %d s %d\n",pDigit->GetPlane(),
575 // pDigit->GetStrip());
576 // pos.SetXYZ(xcens[chamber][strip],ycens[chamber][strip],zchamb[chamber]);
577 Float_t dtime = pDigit->GetTime();
578 Float_t dlrdiff = pDigit->GetDiff();
579 if (dtime < fTimeMin || dtime > fTimeMax)
580 continue;
581 Double_t DiffTimeMax = fDiffTimeMaxSmall;
582 if (idchambers[chamber] >= 100.f)
583 DiffTimeMax = fDiffTimeMaxBig;
584 if (TMath::Abs(dlrdiff) > DiffTimeMax)
585 continue;
586 const LStrip* pStrip = pGeoUtils->FindStrip(UID);
587 Float_t xcl = 0., ycl = 0., zcl = 0.;
588 if (fSelectXYCalibration == 0)
589 fTOF2->get_hit_xyz(chamber, strip, dlrdiff, &xcl, &ycl, &zcl);
590 else if (fSelectXYCalibration == 1)
591 fTOF2->get_hit_xyzp(chamber, strip, dlrdiff, &xcl, &ycl, &zcl);
592 else if (fSelectXYCalibration == 2)
593 fTOF2->get_hit_xyzng(chamber, strip, dlrdiff, &xcl, &ycl, &zcl);
594 else if (fSelectXYCalibration == 3)
595 fTOF2->get_hit_xyznl(chamber, strip, dlrdiff, &xcl, &ycl, &zcl);
596 else
597 fTOF2->get_hit_xyzng(chamber, strip, dlrdiff, &xcl, &ycl, &zcl);
598 if (zcl == 0.) {
599 fTOF2->get_hit_xyz(chamber, strip, dlrdiff, &xcl, &ycl, &zcl);
600 }
601 if (zcl != 0.) {
602 crosspoint.SetXYZ(xcl, ycl, zcl);
604 AddHit(UID, crosspoint, XYZ_err, -1, -1, dtime + fMCTime[chamber] + tofcals[chamber][strip]);
605 else
606 AddHit(UID, crosspoint, XYZ_err, -1, -1, dtime + fMCTime[chamber] + tofcalc[chamber]);
607 nSingleHits++;
608
609 if (fDoTest) {
610 h2TestXYSmeared2->Fill(crosspoint.X(), crosspoint.Y());
611 TVector3 stripCenter(pStrip->center);
612 h2TestRZ->Fill(stripCenter.X(), stripCenter.Y());
613 }
614 }
615 }
616 }
617 }
618 if (OCCUPANCY) {
619 if (fUseMCData)
620 MergeHitsOnStripNew(); // simulation realistic response - several
621 // tracks hits in the strip
622 else if (fUseMCData)
623 MergeHitsOnStrip(); // save only the fastest hit in the strip
624 }
625
626 int nFinally = CompressHits(); // remove blank slotes
627
628 sw.Stop();
629 workTime += sw.RealTime();
630
631 if (fVerbose > 1)
632 cout << "BmnTof700HitProducer: single hits= " << nSingleHits << ", double hits= " << nDoubleHits
633 << ", final hits= " << nFinally << endl;
634 if (fVerbose == 1)
635 cout << "BmnTof700HitProducer: " << nFinally << " hits" << endl;
636 if (fVerbose > 1)
637 cout << "======================== TOF700 exec finished "
638 "==================="
639 << endl;
640}
641//--------------------------------------------------------------------------------------------------------------------------------------
643{
644 if (fDoTest) {
645 LOG(info) << "[BmnTof700HitProducer::Finish] Update " << fTestFlnm.Data() << " file.";
646 TFile* ptr = gFile;
647 TFile file(fTestFlnm.Data(), "RECREATE");
648 fList.Write();
649 file.Close();
650 gFile = ptr;
651 }
652
653 printf("Work time of BmnTofHitProducer: %4.2f sec.\n", workTime);
654}
655//------------------------------------------------------------------------------------------------------------------------
657{
658 typedef map<Int_t, BmnTofHit*> hitsMapType;
659 hitsMapType fHits; // pair<detectorUID, BmnTofHit*> fastest hits map
660 hitsMapType::iterator it;
661 Int_t mergedNmb = 0;
662 Double_t tarrive[70000][2] = {{0.}};
663 Double_t tarrive0[70000][2] = {{0.}};
664 Double_t tarrivemin[70000] = {0.};
665 Double_t tarr[2] = {0.};
666 // Double_t tarr1[2] = {0.};
667
668 typedef multiset<Int_t> msUIDsType; // detectorUID for Hits
669 msUIDsType UIDs;
670
671 if (OCCUPANCY_DEBUG)
672 printf(" *********** New event ****************\n");
673
674 BmnTofHit *fastHit, *slowHit;
675 for (Int_t hitIndex = 0, nHits = aTofHits->GetEntriesFast(); hitIndex < nHits; hitIndex++) // cycle by hits
676 {
677 BmnTofHit* pHit = (BmnTofHit*)aTofHits->UncheckedAt(hitIndex);
678 assert(nullptr != pHit);
679
680 Int_t UID = pHit->GetDetectorID();
681 if (UID >= 70000)
682 continue;
683
684 if (fDoTest)
685 UIDs.insert(UID);
686
687 const LStrip* pStrip = pGeoUtils->FindStrip(UID);
688 if (pStrip == NULL)
689 continue;
690 TVector3 pos;
691 pHit->Position(pos);
692 // Int_t side;
693 Double_t distance1 = pStrip->DistanceFromPointToLineSegment(&pos, pStrip->A, pStrip->D); // right side, [cm]
694 Double_t distance2 = pStrip->DistanceFromPointToLineSegment(&pos, pStrip->B, pStrip->C); // left side, [cm]
695 tarr[0] = pHit->GetTimeStamp() + distance1 * fSignalVelosity; // right side, [ns]
696 tarr[1] = pHit->GetTimeStamp() + distance2 * fSignalVelosity; // left side, [ns]
697 Double_t tarrmin = tarr[0];
698 if (tarr[1] < tarrmin)
699 tarrmin = tarr[1];
700 it = fHits.find(UID);
701
702 if (it != fHits.end()) // hit for this detectorUID already exist
703 {
704 mergedNmb++;
705 if (OCCUPANCY_DEBUG)
706 printf("Chamber %2d strip %2d before %f %f\n", UID >> 8, UID & 0xFF, tarrive[UID][0], tarrive[UID][1]);
707 // printf(" distance %f %f\n",distance1, distance2);
708 if (tarrmin < tarrivemin[UID]) {
709 tarrivemin[UID] = tarrmin;
710 fastHit = pHit;
711 slowHit = it->second;
712 tarrive0[UID][0] = tarr[0];
713 tarrive0[UID][1] = tarr[1];
714 } else {
715 fastHit = it->second;
716 slowHit = pHit;
717 }
718 if (tarr[0] < tarrive[UID][0]) // faster hit found on side 0
719 {
720 tarrive[UID][0] = tarr[0];
721 fastHit->SetFlag(kFALSE);
722 }
723 if (tarr[1] < tarrive[UID][1]) // faster hit found on side 1
724 {
725 tarrive[UID][1] = tarr[1];
726 fastHit->SetFlag(kFALSE);
727 }
728 if (OCCUPANCY_DEBUG)
729 printf(" after %f %f\n", tarrive[UID][0], tarrive[UID][1]);
730
731 if (fDoTest)
732 h2TestMergedTimes->Fill(fastHit->GetTimeStamp(), slowHit->GetTimeStamp());
733
734 fastHit->AddLinks(slowHit->GetLinks()); // copy links
735 aTofHits->Remove(slowHit); // remove old hit --> make blank slote !!
736 it->second = fastHit; // change pair value to current UID
737 } else // insert new detectorUID pair
738 {
739 fHits.insert(make_pair(UID, pHit));
740 tarrive[UID][0] = tarr[0];
741 tarrive[UID][1] = tarr[1];
742 tarrive0[UID][0] = tarr[0];
743 tarrive0[UID][1] = tarr[1];
744 if (tarr[0] < tarr[1])
745 tarrivemin[UID] = tarr[0];
746 else
747 tarrivemin[UID] = tarr[1];
748 if (OCCUPANCY_DEBUG)
749 printf("Chamber %2d strip %2d start %f %f\n", UID >> 8, UID & 0xFF, tarrive[UID][0], tarrive[UID][1]);
750 }
751
752 } // cycle by hits
753
754 if (OCCUPANCY_DEBUG)
755 printf(" -------------------- Results ------------------\n");
756
757 for (Int_t hitIndex = 0, nHits = aTofHits->GetEntriesFast(); hitIndex < nHits; hitIndex++) // cycle by hits
758 {
759 BmnTofHit* pHit = (BmnTofHit*)aTofHits->UncheckedAt(hitIndex);
760 // BmnTofHit *pHit = (BmnTofHit*) aTofHits->At(hitIndex);
761 // assert(nullptr != pHit);
762 if (pHit == nullptr)
763 continue;
764
765 Int_t UID = pHit->GetDetectorID();
766 if (UID >= 70000)
767 continue;
768
769 // if (pHit->GetFlag()) continue;
770
771 const LStrip* pStrip = pGeoUtils->FindStrip(UID);
772 if (pStrip == NULL)
773 continue;
774
775 Double_t ta1 = tarrive[UID][0];
776 Double_t ta2 = tarrive[UID][1];
777 Double_t ta = 0.5 * (ta1 + ta2);
778 Double_t lstrip = (pStrip->B - pStrip->A).X();
779 ta -= (0.5 * lstrip * fSignalVelosity);
780 Double_t dxh = 0.5 * (ta1 - ta2) / fSignalVelosity;
781 Double_t xh = pStrip->center.X() + dxh;
782 TVector3 pos;
783 pHit->Position(pos);
784 Double_t told = pHit->GetTimeStamp();
785 if (fDoTest && !(pHit->GetFlag()))
786 h1TestOccupancyTimeShift->Fill(ta - told);
787 if (fDoTest && !(pHit->GetFlag()))
788 h1TestOccupancyPositionShift->Fill(xh - pos.X());
789 if (OCCUPANCY_DEBUG) {
790 printf("Chamber %2d strip %2d result %f %f lstrip %f shift %f\n", UID >> 8, UID & 0xFF, tarrive[UID][0],
791 tarrive[UID][1], lstrip, 0.5 * lstrip * fSignalVelosity);
792 printf(" time: old %f new %f\n", told, ta);
793 printf(" tim0: old %f old %f diff %f\n", tarrive0[UID][0], tarrive0[UID][1],
794 tarrive0[UID][0] - tarrive0[UID][1]);
795 printf(" tim0: new %f new %f diff %f\n", tarrive[UID][0], tarrive[UID][1],
796 tarrive[UID][0] - tarrive[UID][1]);
797 printf(" posx: old %f new %f\n", pos.X(), xh);
798 printf(" posy: old %f new %f\n", pos.Y(), pos.Y());
799 printf(" posz: old %f new %f\n", pos.Z(), pos.Z());
800 }
801 ta = pRandom->Gaus(ta, fTimeSigma); // time resolution in ns
802 pos.SetX(pRandom->Gaus(xh, fErrX));
803 pHit->SetPosition(pos);
804 pHit->SetTimeStamp(ta);
805 } // cycle by hits
806
807 // cycle by detector UIDs list
808 if (fDoTest)
809 for (msUIDsType::const_iterator it1 = UIDs.begin(), itEnd = UIDs.end(); it1 != itEnd;
810 it1 = UIDs.upper_bound(*it1))
811 h1TestOccup->Fill(UIDs.count(*it1));
812
813 return mergedNmb;
814}
815//--------------------------------------------------------------------------------------------------------------------------------------
816// input- strip edge position & signal times; output- strip crosspoint; return
817// false, if crosspoint outside strip
819 double time1,
820 const TVector3& p2,
821 double time2,
822 TVector3& crossPoint)
823{
824 double stripLength = (p2 - p1).Mag();
825 double maxDelta = (stripLength + 0.5) * fSignalVelosity; // + 5 mm on the strip edge
826 if (abs(time1 - time2) > maxDelta)
827 return false; // estimated position out the strip edge.
828 double dL = abs(time1 - time2) / fSignalVelosity;
829 double a2 = (stripLength - dL) / 2.;
830 if (time1 > time2)
831 crossPoint = p2 + (p1 - p2) * (a2 / stripLength);
832 else
833 crossPoint = p1 + (p2 - p1) * (a2 / stripLength);
834 return true;
835}
836
837bool BmnTofHitProducer::GetCrossPoint(const LStrip* pStrip, double dT, TVector3& crossPoint)
838{
839 TVector3 s1, s2, centr;
840 s1 = (pStrip->A + pStrip->D) * 0.5; // [cm] strip side1 end's position
841 s2 = (pStrip->B + pStrip->C) * 0.5; // [cm] strip side2 end's position
842 centr = pStrip->center;
843 double stripLength = (s2 - s1).Mag();
844 double maxDelta = (stripLength + 1.0) * fSignalVelosity; // + 10 mm on the strip edge
845 if (abs(dT) > maxDelta)
846 return false; // estimated position out the strip edge.
847 double dL = dT / fSignalVelosity;
848 s1(0) = dL;
849 s1(1) = 0;
850 s1(2) = 0; // TMP ALIGMENT CORRECTIONS
851 crossPoint = centr + s1;
852 /*if (time1 > time2)
853 {
854 cout << "stripLength = " << stripLength << " dL = " << dL << endl;
855 cout << "centr.x = " << centr(0) << "; centr.y = " << centr(1) << ";
856 centr.z = " << centr(2) << endl; cout << "crossPoint.x = " <<
857 crossPoint(0) << "; crossPoint.y = " << crossPoint(1) << "; crossPoint.z
858 = " << crossPoint(2) << endl; getchar();
859 }//*/
860 return true;
861}
862//--------------------------------------------------------------------------------------------------------------------------------------
864{
865 pRandom->SetSeed(seed);
866}
867//--------------------------------------------------------------------------------------------------------------------------------------
868
870{
871 Int_t CorrRPC_It1, CorrT0_It1;
872 Double_t CorrPlane7Coeff_It1[5][4] = {{12.24, -3.919, 0.2624, -0.005153},
873 {-122.9, 14.84, -0.6158, 0.008724},
874 {-12.34, 0.482, 0., 0.},
875 {-12.28, 0.479, 0., 0.},
876 {-13.14, 0.5034, 0., 0.}};
877 Double_t CorrT0Coeff_It1[3][4] = {
878 {-5.486, 1.087, -0.07936, 0.00208}, {10.77, -2.635, 0.1984, -0.004631}, {0., 0., 0., 0.}};
879 Double_t timeRPC = (d1->GetTime() + d2->GetTime()) * 0.5;
880 Double_t ampRPC = d1->GetAmplitude() + d2->GetAmplitude();
881 Double_t timeT0 = t0->GetTime();
882 Double_t ampT0 = t0->GetAmp();
883 Double_t dt = timeRPC - timeT0;
884 if (ampRPC < 20.46)
885 CorrRPC_It1 = 0;
886 else if (ampRPC >= 20.46 && ampRPC < 27.25)
887 CorrRPC_It1 = 1;
888 else if (ampRPC >= 27.25 && ampRPC < 34.81)
889 CorrRPC_It1 = 2;
890 else if (ampRPC >= 34.81 && ampRPC < 37.11)
891 CorrRPC_It1 = 3;
892 else if (ampRPC >= 37.11)
893 CorrRPC_It1 = 4;
894 dt = dt
895 - (CorrPlane7Coeff_It1[CorrRPC_It1][0] + CorrPlane7Coeff_It1[CorrRPC_It1][1] * ampRPC
896 + CorrPlane7Coeff_It1[CorrRPC_It1][2] * ampRPC * ampRPC
897 + CorrPlane7Coeff_It1[CorrRPC_It1][3] * ampRPC * ampRPC * ampRPC);
898 if (ampT0 >= 6.15 && ampT0 < 12.3)
899 CorrT0_It1 = 0;
900 else if (ampT0 >= 12.3 && ampT0 < 17.14)
901 CorrT0_It1 = 1;
902 else
903 CorrT0_It1 = 2;
904 dt = dt
905 - (CorrT0Coeff_It1[CorrT0_It1][0] + CorrT0Coeff_It1[CorrT0_It1][1] * ampT0
906 + CorrT0Coeff_It1[CorrT0_It1][2] * ampT0 * ampT0 + CorrT0Coeff_It1[CorrT0_It1][3] * ampT0 * ampT0 * ampT0);
907 return dt + 14.; // 14 ns
908}
909
910//------------------------------------------------------------------------------------------------------------------------
911int BmnTofHitProducer::readMCTimeFile(const char* MCTimeFile)
912{
913 // cout << "readMCTimeFile: " << MCTimeFile << endl;
914 float idchambers[59] = {27.1, 28.1, 3.1, 1.1, 29.1, 4.1, 33.1, 30.1, 5.1, 19.3, 31.1, 6.1,
915 2.1, 32.1, 15.2, 16.2, 17.2, 18.2, 19.2, 20.2, 7.1, 115.2, 113.1, 117.1,
916 35.1, 9.1, 37.1, 11.1, 39.1, 13.1, 34.1, 8.1, 36.1, 10.1, 38.1, 12.1,
917 21.2, 23.2, 25.2, 22.2, 24.2, 26.2, 107.2, 108.2, 109.2, 110.2, 111.2, 112.2,
918 114.1, 116.2, 118.1, 14.1, 40.1, 119.2, 120.2, 121.2, 122.2, 123.2, 124.2};
919 bool notused[59] = {true};
920 int order[59] = {-1};
921 int c = 0, cmin = -1, c0 = 0;
922 float idmin = 200.f;
923 for (c0 = 0; c0 < 59; c0++) {
924 notused[c0] = true;
925 order[c0] = -1;
926 }
927 for (c0 = 0; c0 < 59; c0++) {
928 cmin = -1;
929 idmin = 200.f;
930 for (c = 0; c < 59; c++) {
931 if (notused[c] && (idchambers[c] < idmin)) {
932 idmin = idchambers[c];
933 cmin = c;
934 }
935 }
936 // printf("c0 %d cmin %d notused
937 //%d\n",c0,cmin,(int)notused[cmin]);
938 if (cmin >= 0) {
939 notused[cmin] = false;
940 order[c0] = cmin;
941 }
942 }
943 char fname[128];
944 FILE* ft = 0;
945 float time = 0.f, timesigma = 0.f;
946 if (MCTimeFile == NULL) {
947 printf("TOF700 MC time-of-flight file name not defined!\n");
948 return 0;
949 }
950 if (strlen(MCTimeFile) == 0) {
951 printf("TOF700 MC time-of-flight file name not defined!\n");
952 return 0;
953 }
954 TString dir = getenv("VMCWORKDIR");
955 sprintf(fname, "%s/geometry/%s", dir.Data(), MCTimeFile);
956 ft = fopen(fname, "r");
957 if (ft == NULL) {
958 printf("TOF700 MC time-of-flight file %s open error!\n", fname);
959 return 0;
960 }
961 for (int i = 0; i < TOF2_MAX_CHAMBERS; i++)
962 fMCTime[i] = 21.f;
963 for (int i = 0; i < TOF2_MAX_CHAMBERS; i++)
964 fMCTimeSigma[i] = 0.f;
965 int cexp = 0, ic = -1;
966 while (fscanf(ft, "%d %f %f\n", &ic, &time, &timesigma) == 3) {
967 if (ic > 0 && ic <= 59) {
968 cexp = order[ic - 1];
969 fMCTime[cexp] = time;
970 fMCTimeSigma[cexp] = timesigma;
971 if (fVerbose == 1)
972 printf("Chamber %.1f (MC %d, EXP %d) average time-of-flight %f "
973 "with sigma %f\n",
974 idchambers[cexp], ic, cexp, time, timesigma);
975 }
976 }
977 fclose(ft);
978 return 1;
979}
980
981void BmnTofHitProducer::OnlineWrite(const std::unique_ptr<TTree>& resultTree)
982{
983 if (!IsActive())
984 return;
985
986 resultTree->Branch("BmnTof700Hit", &aTofHits);
987 resultTree->Fill();
988}
#define OCCUPANCY
#define OCCUPANCY_DEBUG
#define MAKE_CLUSTERS
#define CVERS
#define TOF2_MAX_CHAMBERS
#define LIST_STRIP_CORRECTIONS
#define STRIP_CORRECTIONS
#define LIST_CHAMBER_CORRECTIONS
static Double_t workTime
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
#define gFile
Bool_t GetFlag() const
Definition BmnHit.h:31
void SetFlag(Bool_t fl)
Definition BmnHit.h:48
Short_t GetPlane() const
Short_t GetStrip() const
Float_t GetTime() const
Float_t GetAmplitude() const
Double_t CalculateToF(BmnTof2Digit *d1, BmnTof2Digit *d2, BmnTrigDigit *t0)
Double_t tofcalc[TOF2_MAX_CHAMBERS]
TH1D * h1TestOccupancyPositionShift
Double_t fMCTime[TOF2_MAX_CHAMBERS]
BmnTofGeoUtils * pGeoUtils
const char * fMCTimeFile
Double_t tofcals[TOF2_MAX_CHAMBERS][32]
BmnTof2Raw2DigitNew * fTOF2
BmnTofHitProducer(const char *name="TOF HitProducer", const char *geomFile="", Bool_t useMCdata=true, Int_t verbose=1, Bool_t DoTest=false)
virtual void OnlineWrite(const std::unique_ptr< TTree > &resultTree)
int readMCTimeFile(const char *)
const char * fProtonTimeCorrectionFile
const double fSignalVelosity
void SetSeed(UInt_t seed=0)
Bool_t HitExist(Double_t val)
virtual void Exec(Option_t *opt)
bool GetCrossPoint(const TVector3 &p1, double time1, const TVector3 &p2, double time2, TVector3 &crossPoint)
Int_t MergeHitsOnStripNew(void)
Double_t fMCTimeSigma[TOF2_MAX_CHAMBERS]
Bool_t DoubleHitExist(Double_t val)
virtual InitStatus Init()
TEfficiency * effTestEfficiencySingleHit
TEfficiency * effTestEfficiencyDoubleHit
Double_t GetAmp() const
Double_t GetTime() const
T * Get(const char *namecycle)
void Close(Option_t *option="") override
R__ALWAYS_INLINE Bool_t IsZombie() const
Double_t RealTime()
void Start(Bool_t reset=kTRUE)
void Stop()
const char * Data() const
Double_t Z() const
void SetXYZ(Double_t x, Double_t y, Double_t z)
Double_t Eta() const
Double_t Phi() const
Double_t Y() const
Double_t X() const
Double_t Mag() const
void SetX(Double_t)
RVec< PromoteType< T > > abs(const RVec< T > &v)
Double_t Sqrt(Double_t x)
Double_t Abs(Double_t d)
constexpr Double_t RadToDeg()
Definition json.hpp:4446