ATLAS Offline Software
LumiCalibrator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "LumiCalibrator.h"
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 //--------------------------------------------------
15 
17  m_nPar(0),
18  m_fType(""),
19  m_muToLumi(0.)
20 {
21  m_parVec.clear();
22 }
23 
24 // Return false on error
25 bool
27 {
28  if (attrList["NumOfParameters"].isNull()) return false;
29  m_nPar = attrList["NumOfParameters"].data<uint32_t>();
30 
31  if (attrList["Function"].isNull()) return false;
32  m_fType = attrList["Function"].data<std::string>();
33 
34  if (attrList["MuToLumi"].isNull()) return false;
35  m_muToLumi = attrList["MuToLumi"].data<float>();
36 
37  if (attrList["Parameters"].isNull()) return false;
38  const coral::Blob& blob = attrList["Parameters"].data<coral::Blob>();
39 
40 
41  // Verify length
42  if ( static_cast<uint32_t>( blob.size() ) != 4*m_nPar) return false;
43 
44  // Read calibration parameters
45  const float* p = static_cast<const float*>(blob.startingAddress());
46  for (unsigned int i=0; i<m_nPar; i++, p++)
47  m_parVec.push_back(*p);
48 
49  return true;
50 }
51 
52 // Return False on error
53 bool
54 LumiCalibrator::calibrateLumi(float rawLumi, float& calLumi) const
55 {
56  calLumi = 0;
57  float calMu = 0.;
58  if (!calibrateMu(rawLumi, calMu)) return false;
59  calLumi = calMu * m_muToLumi;
60  return true;
61 }
62 
63 // Return False on error
64 bool
65 LumiCalibrator::calibrateMu(float rawLumi, float& calMu) const
66 {
67  calMu = 0.;
68 
69  if (m_fType == "Polynomial") {
70 
71  // Check parameter length
72  if (m_parVec.empty()) return false;
73 
74  unsigned int nrange = m_parVec[0];
75 
76  // Check parameter size again
77  if (m_parVec.size() < (8*nrange + 1)) return false;
78 
79  for (unsigned int i=0; i<nrange; i++) {
80  float rmin = m_parVec[8*i+1];
81  float rmax = m_parVec[8*i+2];
82  if (rawLumi < rmax and rawLumi >= rmin) {
83  calMu += m_parVec[8*i+3] * pow(rawLumi, 0);
84  calMu += m_parVec[8*i+4] * pow(rawLumi, 1);
85  calMu += m_parVec[8*i+5] * pow(rawLumi, 2);
86  calMu += m_parVec[8*i+6] * pow(rawLumi, 3);
87  calMu += m_parVec[8*i+7] * pow(rawLumi, 4);
88  calMu += m_parVec[8*i+8] * pow(rawLumi, 5);
89  break;
90  }
91  }
92  return true;
93  }
94 
95  if (m_fType == "Logarithm") {
96 
97  // Check parameter length
98  if (m_parVec.size() != 1) return false;
99 
100  // Check input for physically allowed range
101  if ((1.-rawLumi) <= 0.) return false;
102 
103  // Convert negative luminosity to zero
104  if (rawLumi < 0.) return false;
105 
106  calMu = -m_parVec[0] * log(1.-rawLumi);
107  return true;
108  }
109 
110  if (m_fType == "HitLogarithm") {
111 
112  // Check parameter length
113  if (m_parVec.size() != 4) return false;
114 
115  // Channel count must be > 0
116  if (m_parVec[1] <= 0.) return false;
117 
118  // Check input value for physically allowed range
119  if ((1.-rawLumi/m_parVec[1]) <= 0.) return false;
120 
121  // Convert negative luminosity to zero
122  if (rawLumi < 0.) return false;
123 
124  calMu = -m_parVec[0] * log(1.-rawLumi/m_parVec[1])/(1.-m_parVec[2]);
125  return true;
126  }
127 
128  if (m_fType == "LookupTable_EventAND_Lin") {
129 
130  // Check parameter size
131  if (m_parVec.size() != 6) return false;
132 
133  if (rawLumi < 0.) return false;
134 
135  float sigo = m_parVec[0];
136  float siga = m_parVec[1];
137  calMu = m_parVec[5] * getMuVis(rawLumi, sigo, siga);
138 
139  if (calMu < 0.) { // Indicates an error, try again
140  calMu = m_parVec[5] * getMuVis2(rawLumi, sigo, siga);
141  }
142 
143  if (calMu < 0.) { // Indicates an error
144  calMu = 0.;
145  return false;
146  }
147 
148  return true;
149  }
150 
151  if (m_fType == "LookupTable_EventAND_Log") {
152 
153  // Check parameter size
154  if (m_parVec.size() != 8) return false;
155 
156  if (rawLumi < 0.) return false;
157 
158  float sigo = m_parVec[0];
159  float siga = m_parVec[1];
160  calMu = m_parVec[7] * getMuVis(rawLumi, sigo, siga);
161 
162  if (calMu < 0.) { // Indicates an error, try again
163  calMu = m_parVec[7] * getMuVis2(rawLumi, sigo, siga);
164  }
165 
166  if (calMu < 0.) { // Indicates an error
167  calMu = 0.;
168  return false;
169  }
170 
171  return true;
172  }
173 
174  // Unknown type
175  return false;
176 }
177 
178 // Vincent's Newton-Rhapson method
179 float
180 LumiCalibrator::getMuVis(float rawPerBX, float sigo, float siga)
181 {
182 
183  //std::cout << "getMuVis("<<rawPerBX<<","<<sigo<<","<<siga<<")"<<std::endl;
184 
185  float mu, y, dy;
186  float munew = 0.01;
187  float a = (sigo/siga + 1) / 2.;
188  float b = sigo/siga;
189 
190  // Set a fixed number of cycles, but break if we converge faster
191  for (int i=0; i<30; i++) {
192  mu = munew;
193  y = rawPerBX - 1. - std::exp(-b * mu) + 2. * std::exp(-a * mu);
194  dy = b * std::exp(-b * mu) - 2. * a * std::exp(-a * mu);
195  munew = mu-y/dy;
196 
197  //std::cout << i <<" - munew: " << munew << " mu:" << mu << " diff:"
198  // << fabs(munew-mu) << std::endl;
199 
200  // Protect against unphysical values
201  if (munew <= 0.) return -1.;
202  if (std::abs(munew-mu)/munew < 1.E-5) break;
203  }
204 
205  return munew;
206 }
207 
208 // Mika's original brute-force method
209 float rpbx(float sr, float mu) {
210  return 1. - 2.*std::exp(-(1+sr)*mu/2.) + std::exp(-sr*mu);
211 }
212 
213 float
214 LumiCalibrator::getMuVis2(float rawPerBX, float sigo, float siga)
215 {
216  float muvl=1e-10;
217  float muvu=100.;
218  float muvm=10.;
219  float sr=sigo/siga;
220  float rbxl=rpbx(sr,muvl);
221  float rbxu=rpbx(sr,muvu);
222  float rbxm=rpbx(sr,muvm);
223 
224  // Check that starting value is in the valid range
225  if (rawPerBX < rbxl || rawPerBX > rbxu) return -1.;
226 
227  int i=0;
228  while (++i <= 50) {
229  if (rbxl<rawPerBX && rbxm>rawPerBX) {
230  rbxu=rbxm;
231  muvu=muvm;
232  muvm=0.5*(muvu+muvl);
233  } else {
234  rbxl=rbxm;
235  muvl=muvm;
236  muvm=0.5*(muvu+muvl);
237  }
238 
239  rbxm = rpbx(sr, muvm);
240  //std::cout << i <<" - munew: " << muvu << " mu:" << muvl << " diff:" << fabs(muvu-muvl) << std::endl;
241 
242  if ((muvu-muvl)/muvl < 1e-5) return muvm;
243  }
244 
245  // Didn't converge
246  return -1.;
247 }
248 
249 // Dump out parameters
250 MsgStream&
251 LumiCalibrator::dump(MsgStream &stream) const {
252  stream << m_fType << " Npar = " << m_nPar << " MuToLumi = " << m_muToLumi << " ParVec: " << m_parVec;
253  return stream;
254 }
LumiCalibrator::m_nPar
unsigned int m_nPar
Definition: LumiCalibrator.h:40
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
rpbx
float rpbx(float sr, float mu)
Definition: LumiCalibrator.cxx:209
LumiCalibrator::m_muToLumi
float m_muToLumi
Definition: LumiCalibrator.h:42
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
LumiCalibrator::setCalibration
bool setCalibration(const coral::AttributeList &attrList)
Definition: LumiCalibrator.cxx:26
python.subdetectors.tile.Blob
Blob
Definition: tile.py:17
LumiCalibrator::LumiCalibrator
LumiCalibrator()
Definition: LumiCalibrator.cxx:16
python.PyKernel.AttributeList
AttributeList
Definition: PyKernel.py:36
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
AthenaPoolTestWrite.stream
string stream
Definition: AthenaPoolTestWrite.py:12
python.SystemOfUnits.sr
int sr
Definition: SystemOfUnits.py:113
LumiCalibrator::getMuVis2
static float getMuVis2(float rawPerBX, float sigo, float siga)
Definition: LumiCalibrator.cxx:214
lumiFormat.i
int i
Definition: lumiFormat.py:92
LumiCalibrator::dump
MsgStream & dump(MsgStream &) const
Definition: LumiCalibrator.cxx:251
LumiCalibrator::m_parVec
std::vector< float > m_parVec
Definition: LumiCalibrator.h:43
LumiCalibrator::getMuVis
static float getMuVis(float rawPerBX, float sigo, float siga)
Definition: LumiCalibrator.cxx:180
VP1PartSpect::E
@ E
Definition: VP1PartSpectFlags.h:21
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
LumiCalibrator::m_fType
std::string m_fType
Definition: LumiCalibrator.h:41
LumiCalibrator::calibrateLumi
bool calibrateLumi(float rawLumi, float &calLumi) const
Definition: LumiCalibrator.cxx:54
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
y
#define y
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
LumiCalibrator.h
CaloCondBlobAlgs_fillNoiseFromASCII.blob
blob
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:96
LumiCalibrator::calibrateMu
bool calibrateMu(float rawLumi, float &calMu) const
Definition: LumiCalibrator.cxx:65