ATLAS Offline Software
OnlineLumiCalibrator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include "CoralBase/Attribute.h"
8 #include "CoralBase/Blob.h"
9 #include "CoolKernel/StorageType.h"
10 
11 #include <cmath>
12 #include <iostream>
13 
14 #ifdef __linux__
15 #include <endian.h>
16 static_assert (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN,
17  "OnlineLumiCalibrator assumes little-endian byte ordering.");
18 #endif
19 
20 //--------------------------------------------------
22  m_nPar(0),
23  m_fType(""),
24  m_muToLumi(-1.) // Nonsensical intialization value
25 {
26  m_parVec.clear();
27 }
28 
30  : m_nPar (other.m_nPar),
31  m_fType (std::move (other.m_fType)),
32  m_muToLumi (other.m_muToLumi),
33  m_parVec (std::move (other.m_parVec))
34 {
35 }
36 
37 
40 {
41  if (this != &other) {
42  m_nPar = other.m_nPar;
43  m_fType = std::move (other.m_fType);
44  m_muToLumi = other.m_muToLumi;
45  m_parVec = std::move (other.m_parVec);
46  }
47  return *this;
48 }
49 
50 
51 // Return false on error
52 bool
54 {
55  if (attrList["NumOfParameters"].isNull()) return false;
56  m_nPar = attrList["NumOfParameters"].data<uint32_t>();
57 
58  if (attrList["Function"].isNull()) return false;
59  m_fType = attrList["Function"].data<std::string>();
60 
61  if (attrList["MuToLumi"].isNull()) return false;
62  m_muToLumi = attrList["MuToLumi"].data<float>();
63 
64  if (attrList["Parameters"].isNull()) return false;
65  const coral::Blob& blob = attrList["Parameters"].data<coral::Blob>();
66 
67 
68  // Verify length
69  if ( static_cast<uint32_t>( blob.size() ) != 4*m_nPar) return false;
70 
71  // Read calibration parameters
72  const float* p = static_cast<const float*>(blob.startingAddress());
73  for (unsigned int i=0; i<m_nPar; i++, p++)
74  m_parVec.push_back(*p);
75 
76  return true;
77 }
78 
79 float
81 {
82  return m_muToLumi;
83 }
84 
85 // Return False on error
86 bool
87 OnlineLumiCalibrator::calibrateLumi(const std::vector<float>& rawLumi, std::vector<float>& calLumi) const
88 {
89  calLumi.clear();
90  bool error = false;
91  float calValue;
92  for (float val : rawLumi) {
93  calValue = 0;
94  if (!calibrateLumi(val, calValue)) {
95  error = true;
96  calLumi.push_back(0.);
97  } else {
98  calLumi.push_back(calValue);
99  }
100  }
101  return error;
102 }
103 
104 // Return False on error
105 bool
106 OnlineLumiCalibrator::calibrateMu(const std::vector<float>& rawLumi, std::vector<float>& calMu) const
107 {
108  calMu.clear();
109  bool error = false;
110  float calValue;
111  for (float val : rawLumi) {
112  calValue = 0;
113  if (!calibrateMu(val, calValue)) {
114  error = true;
115  calMu.push_back(0.);
116  } else {
117  calMu.push_back(calValue);
118  }
119  }
120  return error;
121 }
122 
123 // Return False on error
124 bool
125 OnlineLumiCalibrator::calibrateLumi(float rawLumi, float& calLumi) const
126 {
127  calLumi = 0;
128  float calMu = 0.;
129  if (!calibrateMu(rawLumi, calMu)) return false;
130  calLumi = calMu * m_muToLumi;
131  return true;
132 }
133 
134 // Return False on error
135 bool
136 OnlineLumiCalibrator::calibrateMu(float rawLumi, float& calMu) const
137 {
138  calMu = 0.;
139 
140  if (m_fType == "Polynomial") {
141 
142  // Check parameter length
143  if (m_parVec.size() < 1) return false;
144 
145  unsigned int nrange = m_parVec[0];
146 
147  // Check parameter size again
148  if (m_parVec.size() < (8*nrange + 1)) return false;
149 
150  for (unsigned int i=0; i<nrange; i++) {
151  float rmin = m_parVec[8*i+1];
152  float rmax = m_parVec[8*i+2];
153  if (rawLumi < rmax and rawLumi >= rmin) {
154  calMu += m_parVec[8*i+3] * pow(rawLumi, 0);
155  calMu += m_parVec[8*i+4] * pow(rawLumi, 1);
156  calMu += m_parVec[8*i+5] * pow(rawLumi, 2);
157  calMu += m_parVec[8*i+6] * pow(rawLumi, 3);
158  calMu += m_parVec[8*i+7] * pow(rawLumi, 4);
159  calMu += m_parVec[8*i+8] * pow(rawLumi, 5);
160  break;
161  }
162  }
163  return true;
164  }
165 
166  if (m_fType == "Logarithm") {
167 
168  // Check parameter length
169  if (m_parVec.size() != 1) return false;
170 
171  // Check input for physically allowed range
172  if ((1.-rawLumi) <= 0.) return false;
173 
174  // Convert negative luminosity to zero
175  if (rawLumi < 0.) return false;
176 
177  calMu = -m_parVec[0] * log(1.-rawLumi);
178  return true;
179  }
180 
181  if (m_fType == "HitLogarithm") {
182 
183  // Check parameter length
184  if (m_parVec.size() != 4) return false;
185 
186  // Channel count must be > 0
187  if (m_parVec[1] <= 0.) return false;
188 
189  // Check input value for physically allowed range
190  if ((1.-rawLumi/m_parVec[1]) <= 0.) return false;
191 
192  // Convert negative luminosity to zero
193  if (rawLumi < 0.) return false;
194 
195  calMu = -m_parVec[0] * log(1.-rawLumi/m_parVec[1])/(1.-m_parVec[2]);
196  return true;
197  }
198 
199  if (m_fType == "LookupTable_EventAND_Lin") {
200 
201  // Check parameter size
202  if (m_parVec.size() != 6) return false;
203 
204  if (rawLumi < 0.) return false;
205 
206  float sigo = m_parVec[0];
207  float siga = m_parVec[1];
208  calMu = m_parVec[5] * getMuVis(rawLumi, sigo, siga);
209 
210  if (calMu < 0.) { // Indicates an error, try again
211  calMu = m_parVec[5] * getMuVis2(rawLumi, sigo, siga);
212  }
213 
214  if (calMu < 0.) { // Indicates an error
215  calMu = 0.;
216  return false;
217  }
218 
219  return true;
220  }
221 
222  if (m_fType == "LookupTable_EventAND_Log") {
223 
224  // Check parameter size
225  if (m_parVec.size() != 8) return false;
226 
227  if (rawLumi < 0.) return false;
228 
229  float sigo = m_parVec[0];
230  float siga = m_parVec[1];
231  calMu = m_parVec[7] * getMuVis(rawLumi, sigo, siga);
232 
233  if (calMu < 0.) { // Indicates an error, try again
234  calMu = m_parVec[7] * getMuVis2(rawLumi, sigo, siga);
235  }
236 
237  if (calMu < 0.) { // Indicates an error
238  calMu = 0.;
239  return false;
240  }
241 
242  return true;
243  }
244 
245  // Unknown type
246  return false;
247 }
248 
249 // Vincent's Newton-Rhapson method
250 float
251 OnlineLumiCalibrator::getMuVis(float rawPerBX, float sigo, float siga) const
252 {
253 
254  //std::cout << "getMuVis("<<rawPerBX<<","<<sigo<<","<<siga<<")"<<std::endl;
255 
256  float mu, y, dy;
257  float munew = 0.01;
258  float a = (sigo/siga + 1) / 2.;
259  float b = sigo/siga;
260 
261  // Set a fixed number of cycles, but break if we converge faster
262  for (int i=0; i<30; i++) {
263  mu = munew;
264  y = rawPerBX - 1. - exp(-b * mu) + 2. * exp(-a * mu);
265  dy = b * exp(-b * mu) - 2. * a * exp(-a * mu);
266  munew = mu-y/dy;
267 
268  //std::cout << i <<" - munew: " << munew << " mu:" << mu << " diff:"
269  // << fabs(munew-mu) << std::endl;
270 
271  // Protect against unphysical values
272  if (munew <= 0.) return -1.;
273  if (fabs(munew-mu)/munew < 1.E-5) break;
274  }
275 
276  return munew;
277 }
278 
279 // Mika's original brute-force method
280 float rpbx(float sr, float mu) {
281  return 1. - 2.*exp(-(1+sr)*mu/2.) + exp(-sr*mu);
282 }
283 
284 float
285 OnlineLumiCalibrator::getMuVis2(float rawPerBX, float sigo, float siga) const
286 {
287  float muvl=1e-10;
288  float muvu=100.;
289  float muvm=10.;
290  float sr=sigo/siga;
291  float rbxl=rpbx(sr,muvl);
292  float rbxu=rpbx(sr,muvu);
293  float rbxm=rpbx(sr,muvm);
294 
295  // Check that starting value is in the valid range
296  if (rawPerBX < rbxl || rawPerBX > rbxu) return -1.;
297 
298  int i=0;
299  while (++i <= 50) {
300  if (rbxl<rawPerBX && rbxm>rawPerBX) {
301  rbxu=rbxm;
302  muvu=muvm;
303  muvm=0.5*(muvu+muvl);
304  } else {
305  rbxl=rbxm;
306  muvl=muvm;
307  muvm=0.5*(muvu+muvl);
308  }
309 
310  rbxm = rpbx(sr, muvm);
311  //std::cout << i <<" - munew: " << muvu << " mu:" << muvl << " diff:" << fabs(muvu-muvl) << std::endl;
312 
313  if ((muvu-muvl)/muvl < 1e-5) return muvm;
314  }
315 
316  // Didn't converge
317  return -1.;
318 }
319 
320 // Dump out parameters
321 MsgStream&
323  stream << m_fType << " Npar = " << m_nPar << " MuToLumi = " << m_muToLumi << " ParVec: " << m_parVec;
324  return stream;
325 }
OnlineLumiCalibrator::m_nPar
unsigned int m_nPar
Definition: OnlineLumiCalibrator.h:50
OnlineLumiCalibrator::calibrateLumi
bool calibrateLumi(float rawLumi, float &calLumi) const
Definition: OnlineLumiCalibrator.cxx:125
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
OnlineLumiCalibrator::getMuVis2
float getMuVis2(float rawPerBX, float sigo, float siga) const
Definition: OnlineLumiCalibrator.cxx:285
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
OnlineLumiCalibrator::operator=
OnlineLumiCalibrator & operator=(const OnlineLumiCalibrator &)=default
OnlineLumiCalibrator::calibrateMu
bool calibrateMu(float rawLumi, float &calMu) const
Definition: OnlineLumiCalibrator.cxx:136
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
python.subdetectors.tile.Blob
Blob
Definition: tile.py:17
python.PyKernel.AttributeList
AttributeList
Definition: PyKernel.py:36
OnlineLumiCalibrator::m_parVec
std::vector< float > m_parVec
Definition: OnlineLumiCalibrator.h:53
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
rpbx
float rpbx(float sr, float mu)
Definition: OnlineLumiCalibrator.cxx:280
AthenaPoolTestWrite.stream
string stream
Definition: AthenaPoolTestWrite.py:12
OnlineLumiCalibrator
Utility class to apply calibrations from /TDAQ/OLC/CALIBRATIONS folder.
Definition: OnlineLumiCalibrator.h:20
OnlineLumiCalibrator::getMuVis
float getMuVis(float rawPerBX, float sigo, float siga) const
Definition: OnlineLumiCalibrator.cxx:251
python.SystemOfUnits.sr
int sr
Definition: SystemOfUnits.py:113
lumiFormat.i
int i
Definition: lumiFormat.py:92
OnlineLumiCalibrator::setCalibration
bool setCalibration(const coral::AttributeList &attrList)
Definition: OnlineLumiCalibrator.cxx:53
OnlineLumiCalibrator::m_muToLumi
float m_muToLumi
Definition: OnlineLumiCalibrator.h:52
OnlineLumiCalibrator::OnlineLumiCalibrator
OnlineLumiCalibrator()
Definition: OnlineLumiCalibrator.cxx:21
OnlineLumiCalibrator::m_fType
std::string m_fType
Definition: OnlineLumiCalibrator.h:51
OnlineLumiCalibrator::dump
MsgStream & dump(MsgStream &) const
Definition: OnlineLumiCalibrator.cxx:322
VP1PartSpect::E
@ E
Definition: VP1PartSpectFlags.h:21
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
OnlineLumiCalibrator.h
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
a
TList * a
Definition: liststreamerinfos.cxx:10
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
y
#define y
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
OnlineLumiCalibrator::getMuToLumi
float getMuToLumi() const
Definition: OnlineLumiCalibrator.cxx:80
get_generator_info.error
error
Definition: get_generator_info.py:40
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
error
Definition: IImpactPoint3dEstimator.h:70
CaloCondBlobAlgs_fillNoiseFromASCII.blob
blob
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:96