Project
Loading...
Searching...
No Matches
CTPRateFetcher.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 <map>
16#include <vector>
18
19using namespace o2::ctp;
20
21namespace
22{
23// sigma_ZNC / sigma_hadronic. Being a ratio of cross sections it belongs on mu and not on a
24// counting rate that has already saturated; see CTPRateFetcher.md in the parent directory.
25double zncHadronicRatio(const std::string& sourceName)
26{
27 const bool isZNChadronic = sourceName.find("ZNC") != std::string::npos &&
28 sourceName.find("hadronic") != std::string::npos;
29 return isZNChadronic ? 28. : 1.;
30}
31} // namespace
32
33double CTPRateFetcher::fetch(o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, int runNumber, std::string sourceName)
34{
35 auto triggerRate = fetchNoPuCorr(ccdb, timeStamp, runNumber, sourceName);
36 if (triggerRate < 0) {
37 return -1;
38 }
39 // fetchNoPuCorr has already divided by the ratio; put it back, invert the Poisson, divide again
40 const double ratio = zncHadronicRatio(sourceName);
41 return pileUpCorrection(triggerRate * ratio) / ratio;
42}
43double CTPRateFetcher::fetchNoPuCorr(o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, int runNumber, std::string sourceName)
44{
45 setupRun(runNumber, ccdb, timeStamp, 1);
46 if (sourceName.find("ZNC") != std::string::npos) {
47 if (runNumber < 544448) {
48 return fetchCTPratesInputsNoPuCorr(timeStamp, 25) / (sourceName.find("hadronic") != std::string::npos ? 28. : 1.);
49 } else {
50 return fetchCTPratesClassesNoPuCorr(timeStamp, "C1ZNC-B-NOPF-CRU", 6) / (sourceName.find("hadronic") != std::string::npos ? 28. : 1.);
51 }
52 } else if (sourceName == "T0CE") {
53 return fetchCTPratesClassesNoPuCorr(timeStamp, "CMTVXTCE-B-NOPF");
54 } else if (sourceName == "T0SC") {
55 return fetchCTPratesClassesNoPuCorr(timeStamp, "CMTVXTSC-B-NOPF");
56 } else if (sourceName == "T0VTX") {
57 if (runNumber < 534202) {
58 return fetchCTPratesClassesNoPuCorr(timeStamp, "minbias_TVX_L0", 3); // 2022
59 } else {
60 double ret = fetchCTPratesClassesNoPuCorr(timeStamp, "CMTVX-B-NOPF");
61 if (ret == -2.) {
62 LOG(info) << "Trying different class";
63 ret = fetchCTPratesClassesNoPuCorr(timeStamp, "CMTVX-NONE");
64 if (ret < 0) {
65 LOG(error) << "None of the classes used for lumi found";
66 return -1.;
67 }
68 }
69 return ret;
70 }
71 }
72 LOG(error) << "CTP rate for " << sourceName << " not available";
73 return -1.;
74}
76{
77 mScalers = scalers;
78 mScalers.convertRawToO2();
79}
80//
81int CTPRateFetcher::getRates(std::array<double, 3>& rates, o2::ccdb::BasicCCDBManager* ccdb, int runNumber, const std::string sourceName) // rates at start,stop and middle of the run
82{
83 setupRun(runNumber, ccdb, 0, 1);
84 mOrbit = 1;
85 mOutsideLimits = 1;
86 auto orbitlimits = mScalers.getOrbitLimit();
87 // std::cout << "1st orbit:" << orbitlimits.first << " last:" << orbitlimits.second << " Middle:" << (orbitlimits.first + orbitlimits.second)/2 << std::endl;
88 double rate0 = fetch(ccdb, orbitlimits.first, mRunNumber, sourceName);
89 double rateLast = fetch(ccdb, orbitlimits.second, mRunNumber, sourceName);
90 double rateM = fetch(ccdb, (orbitlimits.first + orbitlimits.second) / 2, mRunNumber, sourceName);
91 // std::cout << rate0 << " " << rateLast << " " << rateM << std::endl;
92 rates[0] = rate0;
93 rates[1] = rateLast;
94 rates[2] = rateM;
95 return 0;
96}
97double CTPRateFetcher::getLumiNoPuCorr(const std::string& classname, int type)
98{
99 if (classname == "zncinp") {
100 return mScalers.getLumiNoPuCorr(26, 7);
101 }
102 std::vector<ctp::CTPClass>& ctpcls = mConfig.getCTPClasses();
103 std::vector<int> clslist = mConfig.getTriggerClassList();
104 int classIndex = -1;
105 for (size_t i = 0; i < clslist.size(); i++) {
106 if (ctpcls[i].name.find(classname) != std::string::npos) {
107 classIndex = i;
108 break;
109 }
110 }
111 if (classIndex == -1) {
112 LOG(warn) << "Trigger class " << classname << " not found in CTPConfiguration";
113 return -1;
114 }
115 return mScalers.getLumiNoPuCorr(classIndex, type);
116}
117double CTPRateFetcher::getLumiWPuCorr(const std::string& classname, int type)
118{
119 std::vector<std::pair<double, double>> scals;
120 if (classname == "zncinp") {
121 scals = mScalers.getRatesForIndex(26, 7);
122 } else {
123 std::vector<ctp::CTPClass>& ctpcls = mConfig.getCTPClasses();
124 std::vector<int> clslist = mConfig.getTriggerClassList();
125 int classIndex = -1;
126 for (size_t i = 0; i < clslist.size(); i++) {
127 if (ctpcls[i].name.find(classname) != std::string::npos) {
128 classIndex = i;
129 break;
130 }
131 }
132 if (classIndex == -1) {
133 LOG(warn) << "Trigger class " << classname << " not found in CTPConfiguration";
134 return -1;
135 }
136 scals = mScalers.getRatesForIndex(classIndex, type);
137 }
138 double lumi = 0;
139 for (auto const& ss : scals) {
140 // std::cout << ss.first << " " << ss.second << " " << pileUpCorrection(ss.first/ss.second) << std::endl;
141 lumi += pileUpCorrection(ss.first / ss.second) * ss.second;
142 }
143 return lumi;
144}
145double CTPRateFetcher::getLumi(const std::string& classname, int type, int puCorr)
146{
147 if (puCorr) {
148 return getLumiWPuCorr(classname, type);
149 } else {
150 return getLumiNoPuCorr(classname, type);
151 }
152}
153
154double CTPRateFetcher::getLumi(o2::ccdb::BasicCCDBManager* ccdb, int runNumber, const std::string sourceName, int puCorr)
155{
156 // setupRun(runNumber, ccdb, timeStamp, 1);
157 if (sourceName.find("ZNC") != std::string::npos) {
158 if (runNumber < 544448) {
159 return getLumi("zncinp", 1, puCorr) / (sourceName.find("hadronic") != std::string::npos ? 28. : 1.);
160 } else {
161 return getLumi("C1ZNC-B-NOPF-CRU", 6, puCorr) / (sourceName.find("hadronic") != std::string::npos ? 28. : 1.);
162 }
163 } else if (sourceName == "T0CE") {
164 return getLumi("CMTVXTCE-B-NOPF", 1, puCorr);
165 } else if (sourceName == "T0SC") {
166 return getLumi("CMTVXTSC-B-NOPF", 1, puCorr);
167 } else if (sourceName == "T0VTX") {
168 if (runNumber < 534202) {
169 return getLumi("minbias_TVX_L0", 3, puCorr); // 2022
170 } else {
171 double ret = getLumi("CMTVX-B-NOPF", 1, puCorr);
172 if (ret == -1.) {
173 LOG(info) << "Trying different class";
174 ret = getLumi("CMTVX-NONE", 1, puCorr);
175 if (ret < 0) {
176 LOG(fatal) << "None of the classes used for lumi found";
177 }
178 }
179 return ret;
180 }
181 }
182 LOG(error) << "CTP Lumi for " << sourceName << " not available";
183 return 0;
184}
185//
186double CTPRateFetcher::fetchCTPratesClasses(uint64_t timeStamp, const std::string& className, int inputType)
187{
188 auto triggerRate = fetchCTPratesClassesNoPuCorr(timeStamp, className, inputType);
189 if (triggerRate >= 0) {
190 return pileUpCorrection(triggerRate);
191 }
192 return -1;
193}
194double CTPRateFetcher::fetchCTPratesClassesNoPuCorr(uint64_t timeStamp, const std::string& className, int inputType)
195{
196 std::vector<ctp::CTPClass>& ctpcls = mConfig.getCTPClasses();
197 std::vector<int> clslist = mConfig.getTriggerClassList();
198 int classIndex = -1;
199 for (size_t i = 0; i < clslist.size(); i++) {
200 if (ctpcls[i].name.find(className) != std::string::npos) {
201 classIndex = i;
202 break;
203 }
204 }
205 if (classIndex == -1) {
206 LOG(warn) << "Trigger class " << className << " not found in CTPConfiguration";
207 return -2.;
208 }
209 if (mOrbit) {
210 auto rate{mScalers.getRate((uint32_t)timeStamp, classIndex, inputType, mOutsideLimits)};
211 return rate.second;
212 } else {
213 auto rate{mScalers.getRateGivenT(timeStamp * 1.e-3, classIndex, inputType, mOutsideLimits)};
214 return rate.second;
215 }
216}
217double CTPRateFetcher::fetchCTPratesInputs(uint64_t timeStamp, int input)
218{
219 std::vector<ctp::CTPScalerRecordO2>& recs = mScalers.getScalerRecordO2();
220 if (recs[0].scalersInps.size() == 48) {
221 if (mOrbit) {
222 return pileUpCorrection(mScalers.getRate((uint32_t)timeStamp, input, 7, mOutsideLimits).second);
223 } else {
224 return pileUpCorrection(mScalers.getRateGivenT(timeStamp * 1.e-3, input, 7, mOutsideLimits).second);
225 }
226 } else {
227 LOG(error) << "Inputs not available";
228 return -1.;
229 }
230}
231double CTPRateFetcher::fetchCTPratesInputsNoPuCorr(uint64_t timeStamp, int input)
232{
233 std::vector<ctp::CTPScalerRecordO2>& recs = mScalers.getScalerRecordO2();
234 if (recs[0].scalersInps.size() == 48) {
235 if (mOrbit) {
236 return mScalers.getRate((uint32_t)timeStamp, input, 7, mOutsideLimits).second;
237 } else {
238 return mScalers.getRateGivenT(timeStamp * 1.e-3, input, 7, mOutsideLimits).second; // qc flag implemented only for time
239 }
240 } else {
241 LOG(error) << "Inputs not available";
242 return -1.;
243 }
244}
245
246double CTPRateFetcher::pileUpCorrection(double triggerRate)
247{
248 if (mLHCIFdata.getFillNumber() == 0) {
249 LOG(fatal) << "No filling" << std::endl;
250 }
251 double nbc = mLHCIFdata.getBunchFilling().getPattern().count();
252 double nTriggersPerFilledBC = triggerRate / nbc / constants::lhc::LHCRevFreq;
253 double mu = -std::log(1 - nTriggersPerFilledBC);
254 return mu * nbc * constants::lhc::LHCRevFreq;
255}
256
257void CTPRateFetcher::setupRun(int runNumber, o2::ccdb::BasicCCDBManager* ccdb, uint64_t timeStamp, bool initScalers)
258{
259 if (runNumber == mRunNumber) {
260 return;
261 }
262 mRunNumber = runNumber;
263 LOG(info) << "Setting up CTP scalers for run " << mRunNumber << " and timestamp : " << timeStamp;
264 auto ptrLHCIFdata = ccdb->getSpecific<parameters::GRPLHCIFData>("GLO/Config/GRPLHCIF", timeStamp);
265 if (ptrLHCIFdata == nullptr) {
266 LOG(error) << "GRPLHCIFData not in database, timestamp:" << timeStamp;
267 return;
268 }
269 mLHCIFdata = *ptrLHCIFdata;
270 std::map<std::string, std::string> metadata;
271 metadata["runNumber"] = std::to_string(mRunNumber);
272 auto ptrConfig = ccdb->getSpecific<ctp::CTPConfiguration>("CTP/Config/Config", timeStamp, metadata);
273 if (ptrConfig == nullptr) {
274 LOG(error) << "CTPRunConfig not in database, timestamp:" << timeStamp;
275 return;
276 }
277 mConfig = *ptrConfig;
278 if (initScalers) {
279 auto ptrScalers = ccdb->getSpecific<ctp::CTPRunScalers>("CTP/Calib/Scalers", timeStamp, metadata);
280 if (ptrScalers) {
281 mScalers = *ptrScalers;
282 mScalers.convertRawToO2();
283 } else {
284 LOG(error) << "CTPRunScalers not in database, timestamp:" << timeStamp;
285 }
286 }
287}
int32_t i
Header to collect LHC related constants.
const auto & getPattern(int dir=-1) const
T * getSpecific(std::string const &path, long timestamp=-1, MD metaData=MD(), std::map< std::string, std::string > *headers=nullptr)
retrieve an object of type T from CCDB as stored under path, timestamp and metaData
std::vector< CTPClass > & getCTPClasses()
std::vector< int > getTriggerClassList() const
int getRates(std::array< double, 3 > &rates, o2::ccdb::BasicCCDBManager *ccdb, int runNumber, const std::string sourceName)
double getLumiWPuCorr(const std::string &classname, int type=1)
double getLumi(o2::ccdb::BasicCCDBManager *ccdb, int runNumber, const std::string sourceName, int puCorr=0)
void setupRun(int runNumber, o2::ccdb::BasicCCDBManager *ccdb, uint64_t timeStamp, bool initScalers)
double fetchNoPuCorr(o2::ccdb::BasicCCDBManager *ccdb, uint64_t timeStamp, int runNumber, const std::string sourceName)
double getLumiNoPuCorr(const std::string &classname, int type=1)
void updateScalers(ctp::CTPRunScalers &scalers)
double fetch(o2::ccdb::BasicCCDBManager *ccdb, uint64_t timeStamp, int runNumber, const std::string sourceName)
uint64_t getLumiNoPuCorr(int classindex, int type) const
retrieves integral - same interface as getRate, no pileup correction
Definition Scalers.cxx:661
std::pair< double, double > getRate(uint32_t orbit, int classindex, int type, bool qc=0) const
Definition Scalers.cxx:735
std::pair< double, double > getRateGivenT(double timestamp, int classindex, int type, bool qc=0) const
same with absolute timestamp (not orbit) as argument
Definition Scalers.cxx:809
std::pair< unsigned long, unsigned long > getOrbitLimit() const
retrieves orbit boundaries of this scaler object from O2
Definition Scalers.h:161
std::vector< CTPScalerRecordO2 > & getScalerRecordO2()
Definition Scalers.h:106
std::vector< std::pair< double_t, double_t > > getRatesForIndex(int classindex, int type) const
retrieves vector of counters - same interface as getRate, needed for
Definition Scalers.cxx:693
const o2::BunchFilling & getBunchFilling() const
int32_t getFillNumber() const
GLuint GLenum * rate
Definition glcorearb.h:5735
GLuint const GLchar * name
Definition glcorearb.h:781
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLuint GLsizei const GLenum * rates
Definition glcorearb.h:5738
constexpr double LHCRevFreq
constexpr double mu
Definition Specs.h:32
std::string to_string(gsl::span< T, Size > span)
Definition common.h:52
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
LumiInfo lumi