Project
Loading...
Searching...
No Matches
CalibTimeSlewingParamTOF.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
14
15#include <algorithm>
16#include <cstdio>
18
19using namespace o2::dataformats;
20
22{
23
24 for (int i = 0; i < NSECTORS; i++) {
25 memset((*(mChannelStart[i])).data(), -1, sizeof(*(mChannelStart[i])));
26 for (int j = 0; j < NCHANNELXSECTOR; j++) {
27 (*(mFractionUnderPeak[i]))[j] = -100.;
28 (*(mSigmaPeak[i]))[j] = -1.;
29 }
30 }
31}
32
33//______________________________________________
35{
36 int sector = channel / NCHANNELXSECTOR;
37 channel = channel % NCHANNELXSECTOR;
38
39 return (*(mGlobalOffset[sector]))[channel];
40}
41
42//______________________________________________
44{
45 int sector = channel / NCHANNELXSECTOR;
46 channel = channel % NCHANNELXSECTOR;
47
48 (*(mGlobalOffset[sector]))[channel] = val;
49}
50//______________________________________________
52{
53 mGlobalOffset[0] = &mGlobalOffsetSec0;
54 mGlobalOffset[1] = &mGlobalOffsetSec1;
55 mGlobalOffset[2] = &mGlobalOffsetSec2;
56 mGlobalOffset[3] = &mGlobalOffsetSec3;
57 mGlobalOffset[4] = &mGlobalOffsetSec4;
58 mGlobalOffset[5] = &mGlobalOffsetSec5;
59 mGlobalOffset[6] = &mGlobalOffsetSec6;
60 mGlobalOffset[7] = &mGlobalOffsetSec7;
61 mGlobalOffset[8] = &mGlobalOffsetSec8;
62 mGlobalOffset[9] = &mGlobalOffsetSec9;
63 mGlobalOffset[10] = &mGlobalOffsetSec10;
64 mGlobalOffset[11] = &mGlobalOffsetSec11;
65 mGlobalOffset[12] = &mGlobalOffsetSec12;
66 mGlobalOffset[13] = &mGlobalOffsetSec13;
67 mGlobalOffset[14] = &mGlobalOffsetSec14;
68 mGlobalOffset[15] = &mGlobalOffsetSec15;
69 mGlobalOffset[16] = &mGlobalOffsetSec16;
70 mGlobalOffset[17] = &mGlobalOffsetSec17;
71
72 mChannelStart[0] = &mChannelStartSec0;
73 mChannelStart[1] = &mChannelStartSec1;
74 mChannelStart[2] = &mChannelStartSec2;
75 mChannelStart[3] = &mChannelStartSec3;
76 mChannelStart[4] = &mChannelStartSec4;
77 mChannelStart[5] = &mChannelStartSec5;
78 mChannelStart[6] = &mChannelStartSec6;
79 mChannelStart[7] = &mChannelStartSec7;
80 mChannelStart[8] = &mChannelStartSec8;
81 mChannelStart[9] = &mChannelStartSec9;
82 mChannelStart[10] = &mChannelStartSec10;
83 mChannelStart[11] = &mChannelStartSec11;
84 mChannelStart[12] = &mChannelStartSec12;
85 mChannelStart[13] = &mChannelStartSec13;
86 mChannelStart[14] = &mChannelStartSec14;
87 mChannelStart[15] = &mChannelStartSec15;
88 mChannelStart[16] = &mChannelStartSec16;
89 mChannelStart[17] = &mChannelStartSec17;
90
91 mTimeSlewing[0] = &mTimeSlewingSec0;
92 mTimeSlewing[1] = &mTimeSlewingSec1;
93 mTimeSlewing[2] = &mTimeSlewingSec2;
94 mTimeSlewing[3] = &mTimeSlewingSec3;
95 mTimeSlewing[4] = &mTimeSlewingSec4;
96 mTimeSlewing[5] = &mTimeSlewingSec5;
97 mTimeSlewing[6] = &mTimeSlewingSec6;
98 mTimeSlewing[7] = &mTimeSlewingSec7;
99 mTimeSlewing[8] = &mTimeSlewingSec8;
100 mTimeSlewing[9] = &mTimeSlewingSec9;
101 mTimeSlewing[10] = &mTimeSlewingSec10;
102 mTimeSlewing[11] = &mTimeSlewingSec11;
103 mTimeSlewing[12] = &mTimeSlewingSec12;
104 mTimeSlewing[13] = &mTimeSlewingSec13;
105 mTimeSlewing[14] = &mTimeSlewingSec14;
106 mTimeSlewing[15] = &mTimeSlewingSec15;
107 mTimeSlewing[16] = &mTimeSlewingSec16;
108 mTimeSlewing[17] = &mTimeSlewingSec17;
109
110 mFractionUnderPeak[0] = &mFractionUnderPeakSec0;
111 mFractionUnderPeak[1] = &mFractionUnderPeakSec1;
112 mFractionUnderPeak[2] = &mFractionUnderPeakSec2;
113 mFractionUnderPeak[3] = &mFractionUnderPeakSec3;
114 mFractionUnderPeak[4] = &mFractionUnderPeakSec4;
115 mFractionUnderPeak[5] = &mFractionUnderPeakSec5;
116 mFractionUnderPeak[6] = &mFractionUnderPeakSec6;
117 mFractionUnderPeak[7] = &mFractionUnderPeakSec7;
118 mFractionUnderPeak[8] = &mFractionUnderPeakSec8;
119 mFractionUnderPeak[9] = &mFractionUnderPeakSec9;
120 mFractionUnderPeak[10] = &mFractionUnderPeakSec10;
121 mFractionUnderPeak[11] = &mFractionUnderPeakSec11;
122 mFractionUnderPeak[12] = &mFractionUnderPeakSec12;
123 mFractionUnderPeak[13] = &mFractionUnderPeakSec13;
124 mFractionUnderPeak[14] = &mFractionUnderPeakSec14;
125 mFractionUnderPeak[15] = &mFractionUnderPeakSec15;
126 mFractionUnderPeak[16] = &mFractionUnderPeakSec16;
127 mFractionUnderPeak[17] = &mFractionUnderPeakSec17;
128
129 mSigmaPeak[0] = &mSigmaPeakSec0;
130 mSigmaPeak[1] = &mSigmaPeakSec1;
131 mSigmaPeak[2] = &mSigmaPeakSec2;
132 mSigmaPeak[3] = &mSigmaPeakSec3;
133 mSigmaPeak[4] = &mSigmaPeakSec4;
134 mSigmaPeak[5] = &mSigmaPeakSec5;
135 mSigmaPeak[6] = &mSigmaPeakSec6;
136 mSigmaPeak[7] = &mSigmaPeakSec7;
137 mSigmaPeak[8] = &mSigmaPeakSec8;
138 mSigmaPeak[9] = &mSigmaPeakSec9;
139 mSigmaPeak[10] = &mSigmaPeakSec10;
140 mSigmaPeak[11] = &mSigmaPeakSec11;
141 mSigmaPeak[12] = &mSigmaPeakSec12;
142 mSigmaPeak[13] = &mSigmaPeakSec13;
143 mSigmaPeak[14] = &mSigmaPeakSec14;
144 mSigmaPeak[15] = &mSigmaPeakSec15;
145 mSigmaPeak[16] = &mSigmaPeakSec16;
146 mSigmaPeak[17] = &mSigmaPeakSec17;
147}
148
149//______________________________________________
150float CalibTimeSlewingParamTOF::evalTimeSlewing(int channel, float totIn) const
151{
152 // totIn is in ns
153 // the correction is returned in ps
154
155 int sector = channel / NCHANNELXSECTOR;
156 channel = channel % NCHANNELXSECTOR;
157
158 if (sector >= NSECTORS) {
159 return 0.; // something went wrong!
160 }
161
162 int n = (*(mChannelStart[sector]))[channel];
163 int nFirst = n;
164
165 if (n < 0) {
166 return (*(mGlobalOffset[sector]))[channel];
167 }
168 int nstop = mTimeSlewing[sector]->size();
169
170 if (channel < NCHANNELXSECTOR - 1) {
171 nstop = (*(mChannelStart[sector]))[channel + 1];
172 }
173
174 if (n >= nstop) {
175 return (*(mGlobalOffset[sector]))[channel]; // something went wrong!
176 }
177
178 if (totIn == 0) {
179 return (float)((*(mTimeSlewing[sector]))[n].second + (*(mGlobalOffset[sector]))[channel]);
180 }
181
182 if (totIn > MAXTOT) {
183 totIn = MAXTOT;
184 }
185
186 // we convert tot from ns to ps and to unsigned short
187 unsigned short tot = (unsigned short)(totIn * 1000);
188
189 while (n < nstop && tot > (*(mTimeSlewing[sector]))[n].first) {
190 n++;
191 }
192 n--;
193
194 if (n < 0) { // tot is lower than the first available value
195 return (*(mGlobalOffset[sector]))[channel];
196 }
197
198 if (n == nstop - 1) {
199 return (float)((*(mTimeSlewing[sector]))[n].second + (*(mGlobalOffset[sector]))[channel]); // use the last value stored for that channel
200 }
201
202 if (n < nFirst) { // this is before the first point (probably tot = 0 calibration is missing)
203 return (*(mGlobalOffset[sector]))[channel];
204 }
205
206 float w1 = (float)(tot - (*(mTimeSlewing[sector]))[n].first);
207 float w2 = (float)((*(mTimeSlewing[sector]))[n + 1].first - tot);
208
209 return (float)((*(mGlobalOffset[sector]))[channel] + (((*(mTimeSlewing[sector]))[n].second * w2 + (*(mTimeSlewing[sector]))[n + 1].second * w1) / (w1 + w2)));
210}
211//______________________________________________
212void CalibTimeSlewingParamTOF::setTimeSlewingInfo(int channel, float offsetold, int nold, const unsigned short* oldtot, const short* olddt, int nnew, const unsigned short* newtot, const short* newdt)
213{
214 // to be used when updating new calibration from scratch and merging it with the old one (all channels should be called in order)
215 int sector = channel / NCHANNELXSECTOR;
216 channel = channel % NCHANNELXSECTOR;
217
218 // work with float to avoid to loose precision due to short (in case offset will be adjust before to move deltat to short)
219 std::vector<float> deltat;
220
221 float minVal = 100000;
222 float maxVal = -100000;
223
224 // new scheme
225 int k1 = 0;
226 int k2 = 0;
227
228 int ntotFin = 0;
229 std::vector<short> totFin;
230
231 while (k1 < nnew && k2 < nold) {
232 if (newtot[k1] == oldtot[k2]) {
233 k1++;
234 } else if (newtot[k1] < oldtot[k2]) {
235 totFin.push_back(newtot[k1]);
236 if (k2 > 0) {
237 deltat.push_back(float(newdt[k1]) + olddt[k2 - 1]);
238 } else {
239 deltat.push_back(float(newdt[k1] + olddt[k2]));
240 }
241 k1++;
242 } else {
243 totFin.push_back(oldtot[k2]);
244 if (k1 > 0) {
245 deltat.push_back(float(olddt[k2]) + newdt[k1 - 1]);
246 } else {
247 deltat.push_back(float(olddt[k2] + newdt[k1]));
248 }
249 k2++;
250 }
251 }
252
253 if (k1 < nnew) {
254 while (k1 < nnew) {
255 totFin.push_back(newtot[k1]);
256 if (nold) {
257 deltat.push_back(float(newdt[k1]) + olddt[nold - 1]);
258 } else {
259 deltat.push_back(float(newdt[k1]));
260 }
261 k1++;
262 }
263 } else if (k2 < nold) {
264 while (k2 < nold) {
265 totFin.push_back(oldtot[k2]);
266 if (nnew) {
267 deltat.push_back(float(olddt[k2]) + newdt[nnew - 1]);
268 } else {
269 deltat.push_back(float(olddt[k2]));
270 }
271 k2++;
272 }
273 }
274
275 for (int i = 0; i < deltat.size(); i++) {
276 if (deltat[i] < minVal) {
277 minVal = deltat[i];
278 }
279 if (deltat[i] > maxVal) {
280 maxVal = deltat[i];
281 }
282 }
283
284 float recentering = (minVal + maxVal) * 0.5;
285 (*(mGlobalOffset[sector]))[channel] = offsetold + recentering;
286 (*(mChannelStart[sector]))[channel] = mTimeSlewing[sector]->size();
287
288 for (int i = 0; i < deltat.size(); i++) {
289 (*(mTimeSlewing[sector])).emplace_back(totFin[i], (short)(deltat[i] - recentering));
290 }
291}
292//______________________________________________
293void CalibTimeSlewingParamTOF::addTimeSlewingInfo(int channel, float tot, float time)
294{
295 // WE ARE ASSUMING THAT:
296 // channels have to be filled in increasing order (within the sector)
297 // tots have to be filled in increasing order (within the channel)
298
299 // tot here is provided in ns, time in ps;
300 // tot will have to be converted into ps;
301 // type will have to be converted to unsigned short (tot) and short (time)
302
303 int sector = channel / NCHANNELXSECTOR;
304 channel = channel % NCHANNELXSECTOR;
305
306 // printf("DBG: addTimeSlewinginfo sec=%i\n",sector);
307
308 if (sector >= NSECTORS) {
309 return; // something went wrong!
310 }
311
312 int currentch = channel;
313 while (currentch > -1 && (*(mChannelStart[sector]))[currentch] == -1) {
314 // printf("DBG: fill channel %i\n",currentch);
315 // set also all the previous ones which were not filled
316 (*(mChannelStart[sector]))[currentch] = mTimeSlewing[sector]->size();
317 (*(mGlobalOffset[sector]))[currentch] = time;
318 currentch--;
319 }
320 // printf("DBG: emplace back (%f,%f)\n",tot,time);
321 (*(mTimeSlewing[sector])).emplace_back((unsigned short)(tot * 1000), (short)(time - (*(mGlobalOffset[sector]))[channel]));
322}
323//______________________________________________
324
325bool CalibTimeSlewingParamTOF::updateOffsetInfo(int channel, float residualOffset)
326{
327
328 // to update only the channel offset info in an existing CCDB object
329 // residual offset is given in ps
330
331 int sector = channel / NCHANNELXSECTOR;
332 channel = channel % NCHANNELXSECTOR;
333 // printf("sector = %d, channel = %d\n", sector, channel);
334
335 (*(mGlobalOffset[sector]))[channel] += residualOffset;
336 return true;
337
338 /*
339 // printf("DBG: addTimeSlewinginfo sec=%i\n",sector);
340
341 int n = (*(mChannelStart[sector]))[channel]; // first time slewing entry for the current channel. this corresponds to tot = 0
342 if ((*(mTimeSlewing[sector]))[n].first != 0) {
343 printf("DBG: there was no time offset set yet! first tot is %d\n", (*(mTimeSlewing[sector]))[n].first);
344 std::pair<unsigned short, short> offsetToBeInserted(0, (short)residualOffset);
345 auto it = (*(mTimeSlewing[sector])).begin();
346 (*(mTimeSlewing[sector])).insert(it + n, offsetToBeInserted);
347 // now we have to increase by 1 all the mChannelStart for the channels that come after this
348 for (auto ch = channel + 1; ch < NCHANNELXSECTOR; ch++) {
349 (*(mChannelStart[sector]))[ch]++;
350 }
351 return false;
352 }
353 (*(mTimeSlewing[sector]))[n].second += (short)residualOffset;
354 return true;
355*/
356}
357//______________________________________________
359{
360 for (int i = 0; i < NSECTORS; i++) {
361 if (other.mTimeSlewing[i]->size() > mTimeSlewing[i]->size()) {
362 *(mTimeSlewing[i]) = *(other.mTimeSlewing[i]);
363 (*(mChannelStart[i])) = (*(other.mChannelStart[i]));
364 *(mFractionUnderPeak[i]) = *(other.mFractionUnderPeak[i]);
365 *(mSigmaPeak[i]) = *(other.mSigmaPeak[i]);
366 *(mGlobalOffset[i]) = *(other.mGlobalOffset[i]);
367 }
368 }
369 return *this;
370}
371//______________________________________________
373{
374 bind();
375 for (int i = 0; i < NSECTORS; i++) {
376 *(mTimeSlewing[i]) = *(source.mTimeSlewing[i]);
377 (*(mChannelStart[i])) = (*(source.mChannelStart[i]));
378 *(mFractionUnderPeak[i]) = *(source.mFractionUnderPeak[i]);
379 *(mSigmaPeak[i]) = *(source.mSigmaPeak[i]);
380 *(mGlobalOffset[i]) = *(source.mGlobalOffset[i]);
381 }
382 mStartValidity = source.mStartValidity;
383 mEndValidity = source.mEndValidity;
384}
Class to store the output of the matching to TOF for calibration.
int16_t time
Definition RawEventData.h:4
int32_t i
uint32_t j
Definition RawData.h:0
float evalTimeSlewing(int channel, float tot) const
void addTimeSlewingInfo(int channel, float tot, float time)
CalibTimeSlewingParamTOF & operator+=(const CalibTimeSlewingParamTOF &other)
bool updateOffsetInfo(int channel, float residualOffset)
void setTimeSlewingInfo(int channel, float offsetold, int nold, const unsigned short *oldtot, const short *olddt, int nnew, const unsigned short *newtot, const short *newdt)
GLdouble n
Definition glcorearb.h:1982
GLsizei GLsizei GLchar * source
Definition glcorearb.h:798
GLboolean * data
Definition glcorearb.h:298
GLuint GLfloat * val
Definition glcorearb.h:1582
Definition of a container to keep/associate and arbitrary number of labels associated to an index wit...
VectorOfTObjectPtrs other