Project
Loading...
Searching...
No Matches
LHCClockCalibrator.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
13#include "Framework/Logger.h"
14#include "MathUtils/fit.h"
16#include "CCDB/CcdbApi.h"
18#include "TOFBase/Utils.h"
19
20namespace o2
21{
22namespace tof
23{
24
29
30//_____________________________________________
32{
33 LOG(info) << "Default c-tor, not to be used";
34}
35
36//_____________________________________________
37void LHCClockDataHisto::fill(const gsl::span<const o2::dataformats::CalibInfoTOF> data)
38{
39 // fill container
40 for (int i = data.size(); i--;) {
41 auto flags = data[i].getFlags();
42 if (flags & o2::dataformats::CalibInfoTOF::kMultiHit) { // skip multi-hit clusters
43 continue;
44 }
45 if (flags & o2::dataformats::CalibInfoTOF::kNoBC) { // skip events far from Int BC
46 continue;
47 }
48
49 auto ch = data[i].getTOFChIndex();
50 auto dt = data[i].getDeltaTimePi();
51 auto tot = data[i].getTot();
52 int used = o2::tof::Utils::addMaskBC(data[i].getMask(), data[i].getTOFChIndex()); // fill the current BC candidate mask and return the one used
53 dt -= used * o2::tof::Geo::BC_TIME_INPS; // report the time using the current 0 deltaBC as reference (the right one will be added later)
54 auto corr = calibApi->getTimeCalibration(ch, tot, 0.); // we take into offsets and time slewing but not lhc phase
55 dt -= corr;
56
57 // printf("ch=%d - tot=%f - corr=%f -> dtcorr = %f (range=%f, bin=%d)\n",ch,tot,corr,dt,range,int((dt+range)*v2Bin));
58
59 float dtRange = dt + range;
60 if (dtRange > 0 && dtRange < 2 * range) {
61 histo[int(dtRange * v2Bin)]++;
62#ifdef DEBUGGING
63 mTimeHist->Fill(mSlot, dt);
64#endif
65 entries++;
66 }
67 }
68}
69
70//_____________________________________________
72{
73 // merge data of 2 slots
74 for (int i = histo.size(); i--;) {
75 histo[i] += prev->histo[i];
76 }
77 entries += prev->entries;
78}
79
80//_____________________________________________
82{
83 LOG(info) << entries << " entries";
84}
85
86//===================================================================
87
88//_____________________________________________
90{
91 // Here we initialize the vector of our output objects
92 mInfoVector.clear();
93 mLHCphaseVector.clear();
94 return;
95}
96
97//_____________________________________________
99{
100 // Extract results for the single slot
101
102 // marging in milliseconds for the end validity of the object to be uploaded
103 static long endValidityMarging = long((5 + getMaxSlotsDelay()) * getSlotLength() * o2::base::GRPGeomHelper::getNHBFPerTF() * o2::constants::lhc::LHCOrbitMUS * 1e-3);
104
106 LOG(info) << "Finalize slot " << slot.getTFStart() << " <= TF <= " << slot.getTFEnd() << " with "
107 << c->getEntries() << " entries";
108 std::array<double, 3> fitValues;
109 std::vector<float> histoValues;
110 int imax = c->nbins / 2;
111 double maxval = 0;
112 for (unsigned i = 0; i < c->nbins; ++i) { // find peak
113 const auto& v = c->histo.at(i);
114 if (v > maxval) {
115 maxval = v;
116 imax = i;
117 }
118 }
119
120 float renorm = 1.; // to avoid fit problem when stats is too large (bad chi2)
121 if (maxval > 10) {
122 renorm = 10. / maxval;
123 }
124
125 int nbinsUsed = 0;
126 double binwidth = 2 * c->range / c->nbins;
127 int binrange = int(1500 / binwidth) + 1;
128 for (unsigned i = 0; i < c->nbins; ++i) {
129 const auto& v = c->histo.at(i);
130 if (i >= imax - binrange && i < imax + binrange) {
131 histoValues.push_back(v * renorm);
132 nbinsUsed++;
133 }
134 }
135
136 float minRange = (imax - c->nbins / 2 - binrange) * binwidth;
137 float maxRange = (imax - c->nbins / 2 + binrange) * binwidth;
138
139 double fitres = fitGaus(nbinsUsed, histoValues.data(), minRange, maxRange, fitValues, nullptr, 2., false);
140 if (fitres >= 0) {
141 LOG(info) << "Fit result " << fitres << " Mean = " << fitValues[1] << " Sigma = " << fitValues[2];
142 } else {
143 LOG(warning) << "Fit failed with result = " << fitres;
144 }
145
146 std::map<std::string, std::string> md;
147 LHCphase l;
148 int tobeused = o2::tof::Utils::getMaxUsed();
149 fitValues[1] += tobeused * o2::tof::Geo::BC_TIME_INPS; // adjust by adding the right BC
150 l.addLHCphase(0, fitValues[1]);
153 auto flName = o2::ccdb::CcdbApi::generateFileName(clName);
154
155 auto starting = slot.getStartTimeMS() - o2::ccdb::CcdbObjectInfo::SECOND * 10; // adding a marging, in case some TFs were not processed
156 auto stopping = slot.getEndTimeMS() + endValidityMarging;
157 LOG(info) << "starting = " << starting << " - stopping = " << stopping << " -> phase = " << fitValues[1] << " ps (added BC = " << tobeused << ")";
158 l.setStartValidity(starting);
159 l.setEndValidity(stopping);
160
161 mInfoVector.emplace_back("TOF/Calib/LHCphase", clName, flName, md, starting, stopping);
162 mLHCphaseVector.emplace_back(l);
163
164 slot.print();
165#ifdef DEBUGGING
166 TFile fout("debug_tof_phase.root", "RECREATE");
167 mTimeHist->Write();
168 fout.Close();
169#endif
170}
171
172//_____________________________________________
173Slot& LHCClockCalibrator::emplaceNewSlot(bool front, TFType tstart, TFType tend)
174{
175 auto& cont = getSlots();
176 auto& slot = front ? cont.emplace_front(tstart, tend) : cont.emplace_back(tstart, tend);
177#ifndef DEBUGGING
178 slot.setContainer(std::make_unique<LHCClockDataHisto>(mNBins, mRange, mCalibTOFapi));
179#else
180 slot.setContainer(std::make_unique<LHCClockDataHisto>(mNBins, mRange, mCalibTOFapi, mNslot, mTimeHist));
181 mNslot++;
182#endif
183 return slot;
184}
185
186} // end namespace tof
187} // end namespace o2
Utils and constants for calibration and related workflows.
int32_t i
uint32_t c
Definition RawData.h:2
std::tuple< ransState_t, stream_IT > renorm(ransState_t state, stream_IT outputIter, count_t frequency, size_t symbolTablePrecision)
TFType getTFEnd() const
Definition TimeSlot.h:47
long getStartTimeMS() const
Definition TimeSlot.h:50
long getEndTimeMS() const
Definition TimeSlot.h:51
const Container * getContainer() const
Definition TimeSlot.h:53
TFType getTFStart() const
Definition TimeSlot.h:46
static std::string generateFileName(const std::string &inp)
Definition CcdbApi.cxx:798
static constexpr long SECOND
static constexpr long INFINITE_TIMESTAMP_SECONDS
void addLHCphase(int timestamp, float phaseLHC)
float getTimeCalibration(int ich, float tot) const
static constexpr Double_t BC_TIME_INPS
Definition Geo.h:103
Slot & emplaceNewSlot(bool front, TFType tstart, TFType tend) final
void finalizeSlot(Slot &slot) final
static int addMaskBC(int mask, int channel)
Definition Utils.cxx:270
static int getMaxUsed()
Definition Utils.cxx:304
const GLdouble * v
Definition glcorearb.h:832
GLenum GLint * range
Definition glcorearb.h:1899
GLboolean * data
Definition glcorearb.h:298
GLbitfield flags
Definition glcorearb.h:1570
constexpr double LHCOrbitMUS
Double_t fitGaus(const size_t nBins, const T *arr, const T xMin, const T xMax, std::vector< T > &param)
Definition fit.h:231
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
o2::tof::CalibTOFapi * calibApi
void fill(const gsl::span< const o2::dataformats::CalibInfoTOF > data)
void merge(const LHCClockDataHisto *prev)
static std::string getClassName(const T &obj)
get the class name of the object
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"