Project
Loading...
Searching...
No Matches
Utils.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12//
13// Strip.cxx: structure to store the TOF digits in strips - useful
14// for clusterization purposes
15// ALICEO2
16//
17#include <TMath.h>
18#include <TH1D.h>
19
20#include "TOFBase/Utils.h"
21
22#define MAX_NUM_EVENT_AUTODETECT 10000
23
24using namespace o2::tof;
25
27
28std::vector<int> Utils::mFillScheme;
29int Utils::mBCmult[o2::constants::lhc::LHCMaxBunches];
30int Utils::mNautodet = 0;
31int Utils::mMaxBC = 0;
32bool Utils::mIsInit = false;
33float Utils::mEventTimeSpread = 200;
34float Utils::mEtaMin = -0.8;
35float Utils::mEtaMax = 0.8;
36float Utils::mLHCPhase = 0;
37int Utils::mNCalibTracks = 0;
38o2::dataformats::CalibInfoTOF Utils::mCalibTracks[NTRACKS_REQUESTED];
39int Utils::mNsample = 0;
40int Utils::mIsample = 0;
41float Utils::mPhases[100];
42uint64_t Utils::mMaskBC[16] = {};
43uint64_t Utils::mMaskBCUsed[16] = {};
44int Utils::mMaskBCchan[o2::tof::Geo::NCHANNELS][16] = {};
45int Utils::mMaskBCchanUsed[o2::tof::Geo::NCHANNELS][16] = {};
46TChain* Utils::mTreeFit = nullptr;
47std::vector<o2::dataformats::CalibInfoTOF> Utils::mVectC;
48std::vector<o2::dataformats::CalibInfoTOF>* Utils::mPvectC = &mVectC;
49int Utils::mNfits = 0;
50uint32_t Utils::mNOrbitInTF = 128;
51
52void Utils::addInteractionBC(int bc, bool fromCollisonCotext)
53{
54 if (fromCollisonCotext) { // align to TOF
56 mFillScheme.push_back(bc + Geo::LATENCY_ADJ_LHC_IN_BC + Geo::BC_IN_ORBIT);
58 mFillScheme.push_back(bc + Geo::LATENCY_ADJ_LHC_IN_BC - Geo::BC_IN_ORBIT);
59 } else {
60 mFillScheme.push_back(bc + Geo::LATENCY_ADJ_LHC_IN_BC);
61 }
62 } else {
63 mFillScheme.push_back(bc);
64 }
65}
66
68{
69 memset(mBCmult, 0, o2::constants::lhc::LHCMaxBunches * sizeof(mBCmult[0]));
70}
71
72void Utils::addCalibTrack(float ctime)
73{
74 mCalibTracks[mNCalibTracks].setDeltaTimePi(ctime);
75
76 mNCalibTracks++;
77
78 if (mNCalibTracks >= NTRACKS_REQUESTED) {
80 mNCalibTracks = 0;
81 }
82}
83
85{
86 static std::vector<o2::dataformats::CalibInfoTOF> tracks;
87 tracks.clear();
88 for (int i = 0; i < NTRACKS_REQUESTED; i++) {
89 tracks.push_back(mCalibTracks[i]);
90 }
91
92 auto evtime = evTimeMaker<std::vector<o2::dataformats::CalibInfoTOF>, o2::dataformats::CalibInfoTOF, filterCalib<o2::dataformats::CalibInfoTOF>>(tracks, 6.0f, true);
93
94 if (evtime.mEventTimeError < 100) { // udpate LHCphase
95 mPhases[mIsample] = evtime.mEventTime;
96 mIsample = (mIsample + 1) % 100;
97 if (mNsample < 100) {
98 mNsample++;
99 }
100 }
101
102 mLHCPhase = 0;
103 for (int i = 0; i < mNsample; i++) {
104 mLHCPhase += mPhases[i];
105 }
106 mLHCPhase /= mNsample;
107}
108
110{
111 printf("FILL SCHEME\n");
112 for (int i = 0; i < getNinteractionBC(); i++) {
113 printf("BC(%d) LHCref=%d TOFref=%d\n", i, mFillScheme[i] - Geo::LATENCY_ADJ_LHC_IN_BC, mFillScheme[i]);
114 }
115}
116
118{
119 return mFillScheme.size();
120}
121
122double Utils::subtractInteractionBC(double time, int& mask, bool subLatency)
123{
126
127 if (subLatency) {
131 } else {
132 bc += deltalat;
133 time += deltalat * o2::tof::Geo::BC_TIME_INPS;
134 }
135 }
136
138
139 int dbc = o2::constants::lhc::LHCMaxBunches, bcc = bc;
140 int dbcSigned = 1000;
141 for (int k = 0; k < getNinteractionBC(); k++) { // get bc from fill scheme closest
142 int deltaCBC = bcOrbit - getInteractionBC(k);
143 if (deltaCBC >= -8 && deltaCBC < 8) {
144 mask += (1 << (deltaCBC + 8)); // fill bc candidates
145 }
146 if (std::abs(deltaCBC) < dbc) {
147 bcc = bc - deltaCBC;
148 dbcSigned = deltaCBC;
149 dbc = std::abs(dbcSigned);
150 }
151 if (std::abs(deltaCBC + o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the right border (last BC of the orbit)
152 bcc = bc - deltaCBC - o2::constants::lhc::LHCMaxBunches;
153 dbcSigned = deltaCBC + o2::constants::lhc::LHCMaxBunches;
154 dbc = std::abs(dbcSigned);
155 }
156 if (std::abs(deltaCBC - o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the left border (BC=0)
157 bcc = bc - deltaCBC + o2::constants::lhc::LHCMaxBunches;
158 dbcSigned = deltaCBC - o2::constants::lhc::LHCMaxBunches;
159 dbc = std::abs(dbcSigned);
160 }
161 }
162 if (dbcSigned >= -8 && dbcSigned < 8) {
163 mask += (1 << (dbcSigned + 24)); // fill bc used
164 }
165
167
168 return time;
169}
170
171float Utils::subtractInteractionBC(float time, int& mask, bool subLatency)
172{
175
176 if (subLatency) {
180 } else {
181 bc += deltalat;
182 time += deltalat * o2::tof::Geo::BC_TIME_INPS;
183 }
184 }
185
187
188 int dbc = o2::constants::lhc::LHCMaxBunches, bcc = bc;
189 int dbcSigned = 1000;
190 for (int k = 0; k < getNinteractionBC(); k++) { // get bc from fill scheme closest
191 int deltaCBC = bcOrbit - getInteractionBC(k);
192 if (deltaCBC >= -8 && deltaCBC < 8) {
193 mask += (1 << (deltaCBC + 8)); // fill bc candidates
194 }
195 if (std::abs(deltaCBC) < dbc) {
196 bcc = bc - deltaCBC;
197 dbcSigned = deltaCBC;
198 dbc = std::abs(dbcSigned);
199 }
200 if (std::abs(deltaCBC + o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the right border (last BC of the orbit)
201 bcc = bc - deltaCBC - o2::constants::lhc::LHCMaxBunches;
202 dbcSigned = deltaCBC + o2::constants::lhc::LHCMaxBunches;
203 dbc = std::abs(dbcSigned);
204 }
205 if (std::abs(deltaCBC - o2::constants::lhc::LHCMaxBunches) < dbc) { // in case k is close to the left border (BC=0)
206 bcc = bc - deltaCBC + o2::constants::lhc::LHCMaxBunches;
207 dbcSigned = deltaCBC - o2::constants::lhc::LHCMaxBunches;
208 dbc = std::abs(dbcSigned);
209 }
210 }
211 if (dbcSigned >= -8 && dbcSigned < 8) {
212 mask += (1 << (dbcSigned + 24)); // fill bc used
213 }
214
216
217 return time;
218}
219
220void Utils::addBC(float toftime, bool subLatency)
221{
222 if (!mIsInit) {
223 init();
224 mIsInit = true;
225 }
226
227 if (mNautodet > MAX_NUM_EVENT_AUTODETECT) {
228 if (!hasFillScheme()) { // detect fill scheme
229 int thres = mMaxBC / 2;
230 for (int i = 0; i < o2::constants::lhc::LHCMaxBunches; i++) {
231 if (mBCmult[i] > thres) { // good bunch
233 }
234 }
235 }
236 return;
237 }
238
239 // just fill
242
243 if (subLatency) {
247 } else {
248 bc += deltalat;
249 toftime += deltalat * o2::tof::Geo::BC_TIME_INPS;
250 }
251 }
252
253 mBCmult[bc]++;
254
255 if (mBCmult[bc] > mMaxBC) {
256 mMaxBC = mBCmult[bc];
257 }
258 mNautodet++;
259}
260
262{
263 if (getNinteractionBC()) {
264 return true;
265 }
266
267 return false;
268}
269
270int Utils::addMaskBC(int mask, int channel)
271{
272 int mask2 = (mask >> 16);
273 int cmask = 1;
274 int used = 0;
275 int weight = 1;
276 int candidates = 0;
277 for (int ibit = 0; ibit < 16; ibit++) { // counts candidates
278 if (mask & cmask) {
279 candidates++;
280 }
281 cmask *= 2;
282 }
283
284 if (candidates) {
285 weight = 16 / candidates;
286 }
287
288 cmask = 1;
289 for (int ibit = 0; ibit < 16; ibit++) {
290 if (mask & cmask) {
291 mMaskBCchan[channel][ibit] += weight;
292 mMaskBC[ibit] += weight;
293 }
294 if (mask2 & cmask) {
295 mMaskBCchanUsed[channel][ibit] += weight;
296 mMaskBCUsed[ibit] += weight;
297 used = ibit - 8;
298 }
299 cmask *= 2;
300 }
301 return used;
302}
303
305{
306 int cmask = 0;
307 uint64_t val = 10; // at least 10 entry required
308 for (int ibit = 0; ibit < 16; ibit++) {
309 if (mMaskBC[ibit] > val) {
310 val = mMaskBC[ibit];
311 cmask = ibit - 8;
312 }
313 }
314 return cmask;
315}
316
318{
319 int cmask = 0;
320 int val = 10; // at least 10 entry required
321 for (int ibit = 0; ibit < 16; ibit++) {
322 if (mMaskBCchan[channel][ibit] > val) {
323 val = mMaskBCchan[channel][ibit];
324 cmask = ibit - 8;
325 }
326 }
327 return cmask;
328}
329
331{
332 if (!oldTS || !newTS) { // objects were not defined -> to nothing
333 return 1;
334 }
335 newTS->bind();
336
337 static auto fitFunc = new TF1("fTOFfit", "gaus", -5000, 5000);
338
339 fitFunc->SetParameter(0, 100);
340 fitFunc->SetParameter(1, 0);
341 fitFunc->SetParameter(2, 200);
342
343 if (mTreeFit) { // remove previous tree
344 delete mTreeFit;
345 }
346
347 mTreeFit = new TChain("treeCollectedCalibInfo", "treeCollectedCalibInfo");
348
349 auto retval = system("ls *collTOF*.root >listaCal"); // create list of calibInfo accumulated
350 (void)retval;
351 FILE* f = fopen("listaCal", "r");
352
353 if (!f) { // no inputs -> return
354 return 2;
355 }
356
357 char namefile[50];
358 while (fscanf(f, "%s", namefile) == 1) {
359 mTreeFit->AddFile(namefile);
360 }
361
362 if (!mTreeFit->GetEntries()) { // return if no entry available
363 return 3;
364 }
365
366 mTreeFit->SetBranchAddress("TOFCollectedCalibInfo", &mPvectC);
367
368 for (int isec = 0; isec < 18; isec++) {
369 fitTimeSlewing(isec, oldTS, newTS);
370 }
371
372 return 0;
373}
374
376{
377 const int nchPerSect = Geo::NCHANNELS / Geo::NSECTORS;
378 for (int i = sector * nchPerSect; i < (sector + 1) * nchPerSect; i += NCHPERBUNCH) {
379 fitChannelsTS(i, oldTS, newTS);
380 }
381}
382
384{
385 // fiting NCHPERBUNCH at the same time to optimze reading from tree
386 TH2F* h[NCHPERBUNCH];
387 float time, tot;
388 int mask;
389 int bcSel[NCHPERBUNCH];
390
391 for (int ii = 0; ii < NCHPERBUNCH; ii++) {
392 h[ii] = new TH2F(Form("h%d", chStart + ii), "", 1000, 0, 100, 100, -5000, 5000);
393 bcSel[ii] = -9999;
394 }
395
396 for (int i = chStart; i + NCHPERBUNCH < mTreeFit->GetEntries(); i += 157248) {
397 for (int ii = 0; ii < NCHPERBUNCH; ii++) {
398 int ch = chStart + ii;
399 mTreeFit->GetEvent(i + ii);
400 int k = 0;
401 bool skip = false;
402 for (auto& obj : mVectC) {
403 if (obj.getTOFChIndex() != ch || skip) {
404 continue;
405 }
406 time = obj.getDeltaTimePi();
407 tot = obj.getTot();
408 mask = obj.getMask();
410 if (time < -5000 || time > 20000) {
411 continue;
412 }
413 float tscorr = oldTS->evalTimeSlewing(ch, tot);
414 if (tscorr < -1000000 || tscorr > 1000000) {
415 skip = true;
416 continue;
417 }
418 time -= tscorr;
419
420 if (bcSel[ii] > -9000) {
421 time += bcSel[ii] * o2::tof::Geo::BC_TIME_INPS;
422 } else {
423 bcSel[ii] = 0;
424 }
425 while (time < -5000) {
427 bcSel[ii] += 1;
428 }
429 while (time > 20000) {
431 bcSel[ii] -= 1;
432 }
433
434 // adjust to avoid borders effect
435 if (time > 12500) {
437 } else if (time < -12500) {
439 }
440
441 h[ii]->Fill(tot, time);
442 }
443 }
444 }
445
446 for (int ii = 0; ii < NCHPERBUNCH; ii++) {
447 mNfits += fitSingleChannel(chStart + ii, h[ii], oldTS, newTS);
448 delete h[ii]; // clean histo once fitted
449 }
450}
451
453{
454 const int nchPerSect = Geo::NCHANNELS / Geo::NSECTORS;
455
456 int fitted = 0;
457 float offset = oldTS->getChannelOffset(ch);
458 int sec = ch / nchPerSect;
459 int chInSec = ch % nchPerSect;
460 int istart = oldTS->getStartIndexForChannel(sec, chInSec);
461 int istop = oldTS->getStopIndexForChannel(sec, chInSec);
462 int nbinPrev = istop - istart;
463 int np = 0;
464
465 unsigned short oldtot[10000];
466 short oldcorr[10000];
467 unsigned short newtot[10000];
468 short newcorr[10000];
469
470 int count = 0;
471
472 const std::vector<std::pair<unsigned short, short>>& vect = oldTS->getVector(sec);
473 for (int i = istart; i < istop; i++) {
474 oldtot[count] = vect[i].first;
475 oldcorr[count] = vect[i].second;
476 count++;
477 }
478
479 TH1D* hpro = h->ProjectionX("hpro");
480
481 int ibin = 1;
482 int nbin = h->GetXaxis()->GetNbins();
483 float integralToEnd = h->Integral();
484
485 if (nbinPrev == 0) {
486 nbinPrev = 1;
487 oldtot[0] = 0;
488 oldcorr[0] = 0;
489 }
490
491 // propagate problematic from old TS
492 newTS->setFractionUnderPeak(sec, chInSec, oldTS->getFractionUnderPeak(ch));
493 newTS->setSigmaPeak(sec, chInSec, oldTS->getSigmaPeak(ch));
494 bool isProb = oldTS->getFractionUnderPeak(ch) < 0.5 || oldTS->getSigmaPeak(ch) > 1000;
495
496 if (isProb) { // if problematic
497 // skip fit procedure
498 integralToEnd = 0;
499 }
500
501 if (integralToEnd < NMINTOFIT) { // no update to be done
502 np = 1;
503 newtot[0] = 0;
504 newcorr[0] = 0;
505 newTS->setTimeSlewingInfo(ch, offset, nbinPrev, oldtot, oldcorr, np, newtot, newcorr);
506 if (hpro) {
507 delete hpro;
508 }
509 return fitted;
510 }
511
512 float totHalfWidth = h->GetXaxis()->GetBinWidth(1) * 0.5;
513
514 static TF1* fitFunc = new TF1("fTOFfit", "gaus", -5000, 5000);
515
516 int integral = 0;
517 float x[10000], y[10000];
518 for (int i = 1; i <= nbin; i++) {
519 integral += hpro->GetBinContent(i);
520 integralToEnd -= hpro->GetBinContent(i);
521
522 if (integral < NMINTOFIT || (integralToEnd < NMINTOFIT && i < nbin)) {
523 continue;
524 }
525
526 // get a point
527 float xmin = h->GetXaxis()->GetBinCenter(ibin) - totHalfWidth;
528 float xmax = h->GetXaxis()->GetBinCenter(i) + totHalfWidth;
529 TH1D* hfit = h->ProjectionY(Form("mypro"), ibin, i);
530 float xref = hfit->GetBinCenter(hfit->GetMaximumBin());
531
532 hfit->Fit(fitFunc, "QN0", "", xref - 500, xref + 500);
533 fitted++;
534
535 x[np] = (xmin + xmax) * 0.5;
536 y[np] = fitFunc->GetParameter(1);
537 if (x[np] > 65.534) {
538 continue; // max tot acceptable in ushort representation / 1000.
539 }
540 newtot[np] = x[np] * 1000;
541 newcorr[np] = y[np];
542 np++;
543 ibin = i + 1;
544 integral = 0;
545 delete hfit;
546 }
547
548 newTS->setTimeSlewingInfo(ch, offset, nbinPrev, oldtot, oldcorr, np, newtot, newcorr);
549
550 if (hpro) {
551 delete hpro;
552 }
553 return fitted;
554}
ClassImp(o2::tof::Utils)
#define MAX_NUM_EVENT_AUTODETECT
Definition Utils.cxx:22
uint64_t bc
Definition RawEventData.h:5
int16_t time
Definition RawEventData.h:4
int32_t i
Class for time synchronization of RawReader instances.
void setDeltaTimePi(float time)
const std::vector< std::pair< unsigned short, short > > & getVector(int sector) const
float evalTimeSlewing(int channel, float tot) const
float getFractionUnderPeak(int sector, int channel) const
void setSigmaPeak(int sector, int channel, float value)
float getSigmaPeak(int sector, int channel) const
int getStartIndexForChannel(int sector, int channel) const
void setFractionUnderPeak(int sector, int channel, float value)
int getStopIndexForChannel(int sector, int channel) const
void setTimeSlewingInfo(int channel, float offsetold, int nold, const unsigned short *oldtot, const short *olddt, int nnew, const unsigned short *newtot, const short *newdt)
static constexpr Int_t NSECTORS
Definition Geo.h:120
static constexpr Double_t BC_TIME_INPS
Definition Geo.h:103
static constexpr Double_t BC_TIME_INPS_INV
Definition Geo.h:104
static constexpr Int_t LATENCYWINDOW_IN_BC
Definition Geo.h:172
static constexpr Int_t LATENCY_ADJ_LHC_IN_BC
Definition Geo.h:173
static constexpr int NCHANNELS
Definition Geo.h:124
static constexpr int BC_IN_ORBIT
Definition Geo.h:105
TOF utils.
Definition Utils.h:41
static double subtractInteractionBC(double time, int &mask, bool subLatency=false)
Definition Utils.cxx:122
static void fitTimeSlewing(int sector, const dataformats::CalibTimeSlewingParamTOF *oldTS, dataformats::CalibTimeSlewingParamTOF *newTS)
Definition Utils.cxx:375
static void addBC(float toftime, bool subLatency=false)
Definition Utils.cxx:220
static int extractNewTimeSlewing(const dataformats::CalibTimeSlewingParamTOF *oldTS, dataformats::CalibTimeSlewingParamTOF *newTS)
Definition Utils.cxx:330
static float mEtaMin
Definition Utils.h:60
static void addCalibTrack(float time)
Definition Utils.cxx:72
static int addMaskBC(int mask, int channel)
Definition Utils.cxx:270
static void addInteractionBC(int bc, bool fromCollisonCotext=false)
Definition Utils.cxx:52
static void fitChannelsTS(int chStart, const dataformats::CalibTimeSlewingParamTOF *oldTS, dataformats::CalibTimeSlewingParamTOF *newTS)
Definition Utils.cxx:383
static float mLHCPhase
Definition Utils.h:62
static void computeLHCphase()
Definition Utils.cxx:84
static int getMaxUsed()
Definition Utils.cxx:304
static int getMaxUsedChannel(int channel)
Definition Utils.cxx:317
static int getNinteractionBC()
Definition Utils.cxx:117
static float mEventTimeSpread
Definition Utils.h:59
static void init()
Definition Utils.cxx:67
static void printFillScheme()
Definition Utils.cxx:109
static float mEtaMax
Definition Utils.h:61
static bool hasFillScheme()
Definition Utils.cxx:261
static int getInteractionBC(int ibc)
Definition Utils.h:50
static int fitSingleChannel(int ch, TH2F *h, const dataformats::CalibTimeSlewingParamTOF *oldTS, dataformats::CalibTimeSlewingParamTOF *newTS)
Definition Utils.cxx:452
GLint GLenum GLint x
Definition glcorearb.h:403
GLint GLsizei count
Definition glcorearb.h:399
GLdouble f
Definition glcorearb.h:310
GLuint GLuint GLfloat weight
Definition glcorearb.h:5477
GLintptr offset
Definition glcorearb.h:660
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLuint GLfloat * val
Definition glcorearb.h:1582
GLint GLuint mask
Definition glcorearb.h:291
constexpr int LHCMaxBunches