33int eventTimeContainer::maxNtracksInSet = -1;
35constexpr unsigned long combinatorial[20] = {1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721, 129140163, 387420489, 1162261467};
40 static constexpr int maxNumberOfSets = 200;
41 static constexpr float weightLimit = 1E-6;
43 const int ntracks = tracks.size();
44 LOG(
debug) <<
"For the collision time using " << ntracks <<
" tracks";
47 std::map<int, int> bcCand;
48 for (
const auto& trk : tracks) {
55 for (
const auto& [
bc,
count] : bcCand) {
56 if (
count > maxcount) {
67 LOG(
debug) <<
"Skipping event because at least 2 tracks are required";
72 int hypo[maxNtrackInSet];
74 int nmaxtracksinset = ntracks > 22 ? 6 : maxNtrackInSet;
77 LOG(
debug) <<
"nmaxtracksinset " << nmaxtracksinset;
78 int ntracksinset = std::min(ntracks, nmaxtracksinset);
79 LOG(
debug) <<
"ntracksinset " << ntracksinset;
81 int nset = ((ntracks - 1) / ntracksinset) + 1;
83 int ntrackUsable = ntracks;
84 LOG(
debug) <<
"ntrackUsable " << ntrackUsable;
86 if (nset > maxNumberOfSets) {
87 nset = maxNumberOfSets;
88 LOG(
debug) <<
"resetting nset " << nset;
89 ntrackUsable = nmaxtracksinset * nset;
90 LOG(
debug) <<
"resetting ntrackUsable " << ntrackUsable;
94 std::vector<int> trackInSet[maxNumberOfSets];
96 for (
int i = 0;
i < ntrackUsable;
i++) {
99 trackInSet[iset].push_back(
i);
104 for (
int iset = 0; iset < nset; iset++) {
105 LOG(
debug) <<
"iset " << iset <<
" has size " << trackInSet[iset].size();
106 unsigned long bestComb = 0;
107 while (!(status =
getStartTimeInSet(tracks, trackInSet[iset], bestComb, t0fill))) {
111 int ntracks = trackInSet[iset].size();
113 for (
int itrk = 0; itrk < ntracks; itrk++) {
114 hypo[itrk] = bestComb % 3;
117 int index = trkIndex[trackInSet[iset][itrk]];
119 LOG(
debug) <<
"Using hypothesis: " << hypo[itrk] <<
" tofSignal: " << ctrack.
mSignal <<
" exp. time: " << ctrack.
expTimes[hypo[itrk]] <<
" exp. sigma: " << ctrack.
expSigma[hypo[itrk]];
126 LOG(
debug) <<
"iset " << iset <<
" did not have good status";
132 double finalTime = 0, allweights = 0;
136 finalTime = 0, allweights = 0;
148 double averageBest = finalTime / allweights;
156 if (err > errworse) {
168 LOG(
debug) <<
"Removed " << nRemoved <<
" tracks from start time calculation";
170 if (allweights < weightLimit) {
171 LOG(
debug) <<
"Skipping because allweights " << allweights <<
" are lower than " << weightLimit;
182 static constexpr int maxNumberOfSets = 200;
183 static constexpr float weightLimit = 1E-6;
185 const int ntracks = tracks.size();
186 LOG(
debug) <<
"For the collision time using " << ntracks;
189 LOG(
debug) <<
"Skipping event because at least 2 tracks are required";
194 int hypo[maxNtrackInSet];
196 int nmaxtracksinset = ntracks > 22 ? 6 : maxNtrackInSet;
197 int ntracksinset = std::min(ntracks, nmaxtracksinset);
199 int nset = ((ntracks - 1) / ntracksinset) + 1;
200 int ntrackUsable = ntracks;
202 if (nset > maxNumberOfSets) {
203 nset = maxNumberOfSets;
204 ntrackUsable = nmaxtracksinset * nset;
208 std::vector<int> trackInSet[maxNumberOfSets];
210 for (
int i = 0;
i < ntrackUsable;
i++) {
213 trackInSet[iset].push_back(
i);
218 for (
int iset = 0; iset < nset; iset++) {
219 unsigned long bestComb = 0;
224 int ntracks = trackInSet[iset].size();
226 for (
int itrk = 0; itrk < ntracks; itrk++) {
227 hypo[itrk] = bestComb % 3;
230 int index = trkIndex[trackInSet[iset][itrk]];
232 LOG(
debug) <<
"Using hypothesis: " << hypo[itrk] <<
" tofSignal: " << ctrack.
mSignal <<
" exp. time: " << ctrack.
expTimes[hypo[itrk]] <<
" exp. sigma: " << ctrack.
expSigma[hypo[itrk]];
242 double finalTime = 0, allweights = 0;
253 if (allweights < weightLimit) {
254 LOG(
debug) <<
"Skipping because allweights " << allweights <<
" are lower than " << weightLimit;
263int getStartTimeInSet(
const std::vector<eventTimeTrack>& tracks, std::vector<int>& trackInSet,
unsigned long& bestComb,
double refT0)
266 float errworse =
params.maxNsigma;
268 float chi2, chi2best;
269 double averageBest = 0;
270 int hypo[maxNtrackInSet];
271 double starttime[maxNtrackInSet], weighttime[maxNtrackInSet];
274 int ntracks = trackInSet.size();
275 LOG(
debug) <<
"Computing the start time in set with " << ntracks <<
" tracks";
283 double preStarttime[maxNtrackInSet][3];
284 double preWeighttime[maxNtrackInSet][3];
285 int validHypo[maxNtrackInSet][3];
286 int nValidHypo[maxNtrackInSet];
288 unsigned long ncombReduced = 1;
289 for (
int itrk = 0; itrk < ntracks; itrk++) {
291 nValidHypo[itrk] = 0;
292 for (
int h = 0;
h < 3;
h++) {
294 if (std::abs(
st - refT0) < 2000) {
295 int idx = nValidHypo[itrk];
296 validHypo[itrk][idx] =
h;
297 preStarttime[itrk][idx] =
st;
302 if (nValidHypo[itrk] == 0) {
305 validHypo[itrk][0] = 0;
306 preStarttime[itrk][0] = 0;
307 preWeighttime[itrk][0] = 0;
308 nValidHypo[itrk] = 1;
310 ncombReduced *= nValidHypo[itrk];
314 for (
unsigned long comb = 0; comb < ncombReduced; comb++) {
315 unsigned long curr = comb;
319 double sumweights = 0;
321 unsigned long origComb = 0;
322 unsigned long origBase = 1;
323 for (
int itrk = 0; itrk < ntracks; itrk++) {
324 int localIdx = curr % nValidHypo[itrk];
325 curr /= nValidHypo[itrk];
326 int h = validHypo[itrk][localIdx];
328 origComb +=
h * origBase;
330 starttime[itrk] = preStarttime[itrk][localIdx];
331 weighttime[itrk] = preWeighttime[itrk][localIdx];
333 if (weighttime[itrk] > 0) {
334 average += starttime[itrk] * weighttime[itrk];
335 sumweights += weighttime[itrk];
344 average /= sumweights;
349 for (
int itrk = 0; itrk < ntracks; itrk++) {
350 deltat = starttime[itrk] - average;
351 chi2 += deltat * deltat * weighttime[itrk];
355 if (chi2 < chi2best) {
358 averageBest = average;
364 unsigned long curr = bestComb;
365 for (
int itrk = 0; itrk < ntracks; itrk++) {
366 hypo[itrk] = curr % 3;
370 float err = ctrack.
mSignal - ctrack.
expTimes[hypo[itrk]] - averageBest;
373 if (err > errworse) {
382 trackInSet.erase(trackInSet.begin() + worse);
389int getStartTimeInSetFast(
const std::vector<eventTimeTrack>& tracks, std::vector<int>& trackInSet,
unsigned long& bestComb)
392 float chi2, chi2best;
393 double averageBest = 0;
394 int hypo[maxNtrackInSet];
395 double starttime[maxNtrackInSet], weighttime[maxNtrackInSet];
398 int ntracks = trackInSet.size();
406 unsigned long comb = 0;
410 double sumweights = 0;
413 for (
int itrk = 0; itrk < ntracks; itrk++) {
417 weighttime[itrk] = 1. / (ctrack.
expSigma[hypo[itrk]] * ctrack.
expSigma[hypo[itrk]]);
419 average += starttime[itrk] * weighttime[itrk];
420 sumweights += weighttime[itrk];
424 average /= sumweights;
429 for (
int itrk = 0; itrk < ntracks; itrk++) {
430 deltat = starttime[itrk] - average;
431 chi2 += deltat * deltat * weighttime[itrk];
437 averageBest = average;
443 for (
int itrk = 0; itrk < ntracks; itrk++) {
445 float err = ctrack.
mSignal - ctrack.
expTimes[hypo[itrk]] - averageBest;
448 if (err > errworse) {
457 trackInSet.erase(trackInSet.begin() + worse);
467 constexpr float masses[3] = {0.13957000, 0.49367700, 0.93827200};
468 constexpr float kCSPEED = TMath::C() * 1.0e2f * 1.0e-12f;
470 float betas[3] = {0.f};
472 float pMismatch = ntracks * 0.00005;
474 for (
int i = 0;
i < ntracks;
i++) {
476 track.
mP = gRandom->Exp(1);
477 track.
mPt = track.
mP;
479 track.
mHypo = gRandom->Exp(1);
480 if (track.
mHypo > 2) {
483 for (
int j = 0;
j < 3;
j++) {
484 energy = sqrt(masses[
j] * masses[
j] + track.
mP * track.
mP);
485 betas[
j] = track.
mP / energy;
491 if (gRandom->Rndm() < pMismatch) {
492 float p = gRandom->Exp(1);
494 int hypo = gRandom->Exp(1);
498 energy = sqrt(masses[hypo] * masses[hypo] + p * p);
499 float beta = p / energy;
500 track.
mSignal = l / (beta * kCSPEED) + gRandom->Gaus(0.f, track.
expSigma[
j]);
504 tracks.push_back(track);
#define O2ParamImpl(classname)
Definition of the TOF event time maker.
Class for time synchronization of RawReader instances.
static const EventTimeTOFParams & Instance()
static constexpr Double_t BC_TIME_INPS
static constexpr Double_t BC_TIME_INPS_INV
GLenum const GLfloat * params
int getStartTimeInSet(const std::vector< eventTimeTrack > &tracks, std::vector< int > &trackInSet, unsigned long &bestComb, double refT0=0)
void computeEvTimeFast(const std::vector< eventTimeTrack > &tracks, const std::vector< int > &trkIndex, eventTimeContainer &evtime)
void computeEvTime(const std::vector< eventTimeTrack > &tracks, const std::vector< int > &trkIndex, eventTimeContainer &evtime)
int getStartTimeInSetFast(const std::vector< eventTimeTrack > &tracks, std::vector< int > &trackInSet, unsigned long &bestComb)
void generateEvTimeTracks(std::vector< eventTimeTrackTest > &tracks, int ntracks, float evTime=0.0)
constexpr unsigned long combinatorial[20]
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::vector< double > mTrackTimes
weights (1/sigma^2) associated to a track in event time computation, 0 if track not used
double mEventTimeError
Value of the event time.
unsigned short mEventTimeMultiplicity
Uncertainty on the computed event time.
std::vector< float > mWeights
sum of weights of all track contributors
static int getMaxNtracksInSet()
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"