ATLAS Offline Software
LumiCalibrator.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2 
3 #
4 # LumiCalibrator
5 #
6 # Eric Torrence - September 2011
7 #
8 # Contents:
9 # LumiCalibrator - utility class to apply the luminosity calibration stored in COOL
10 # to raw per-bcid lumi values.
11 #
12 # This must be initialized with the payload of a calibration record from COOL, then the raw luminosity
13 # will be calibrated with a call to calibrate
14 
15 from __future__ import print_function
16 import math
17 
18 from CoolLumiUtilities.LumiBlobConversion import bConvertList
19 
21 
22  def __init__(self):
23 
24  self.nPar = 0
25  self.fType = 'None'
26  self.muToLumi = 0.
27  self.parVec = []
28  self.rflag = 0
29 
30  self.currVersion = 0
31  self.currParA = 0.
32  self.currParB = 0.
33  self.currParC = 0.
34  self.currType = 1 # Use A+C by default
35 
36  self.polyVersion = 0
37  self.polyParA = 0.
38  self.polyParB = 0.
39  self.polyParC = 0.
40 
41  self.nBunches = 1
42 
43  # PMT currents
44  self.currentA = -1.
45  self.currentC = -1.
46 
47  self.oldCurrentA = -1.
48  self.oldCurrentC = -1.
49 
50  self.verbose = False
51  # self.verbose = True
52 
53  self.facTable = [1, 1]
54 
55  self.nParUsed = 0
56 
57  # Cached factorial values
58  def factorial(self, n):
59 
60  if n >= len(self.facTable):
61 
62  last = len(self.facTable) - 1
63  total = self.facTable[last]
64  for i in range(last+1, n+1):
65  total *= i
66  self.facTable.append(total)
67 
68  return self.facTable[n]
69 
70  def setCalibration(self, calibPayload):
71  self.nPar = calibPayload['NumOfParameters']
72  self.fType = calibPayload['Function']
73  self.muToLumi = calibPayload['MuToLumi']
74  blob = calibPayload['Parameters']
75  s=blob.read()
76  self.parVec = bConvertList(s, 4, self.nPar)
77 
78  if self.verbose:
79  print('LumiCalibrator.setCalibration for %s found %d parameters: ' % (self.fType, self.nPar))
80  print(self.parVec)
81  print(' muToLumi = %f' % self.muToLumi)
82 
83 
84  algname = self.fType
85  polyPos = algname.find("_PolyCorr")
86  currPos = algname.find("_CurrCorr")
87 
88  if polyPos > 0 and currPos > 0:
89  algname = algname[:-18]
90  elif polyPos > 0 or currPos > 0:
91  algname = algname[:-9]
92 
93  if self.verbose:
94  print('LumiCalibrator.setCalibration - Found poly: %d curr: %d' % (polyPos, currPos))
95 
96  if polyPos > currPos:
97 
98  if self.verbose:
99  print('LumiCalibrator.setCalibration - reading polynomial from', self.parVec[-4:-1])
100 
101  self.polyParC = self.parVec.pop()
102  self.polyParB = self.parVec.pop()
103  self.polyParA = self.parVec.pop()
104  self.polyVersion = self.parVec.pop()
105  self.nPar -= 4
106 
107  if currPos > 0:
108 
109  # Call calibrate to get number of parameters
110  self.calibrate(0.1)
111  npar = self.nParUsed
112  self.currType = 1 # Use A+C by default
113 
114  self.currVersion = int(self.parVec[npar])
115  if self.verbose:
116  print('LumiCalibrator.setCalibration - found %d parameters in %s' % (npar, algname))
117  print('LumiCalibrator.setCalibration - reading current vers %d from position %d' % (self.currVersion, npar))
118 
119  if self.currVersion == 4:
120  self.currType = int(self.parVec.pop())
121  self.nPar -= 1
122 
123  if self.currVersion >= 3:
124  self.currParC = self.parVec.pop()
125  self.nPar -= 1
126 
127  self.currParB = self.parVec.pop()
128  self.currParA = self.parVec.pop()
129  self.currVersion = self.parVec.pop()
130  self.nPar -= 3
131 
132  if self.verbose:
133  print('LumiCalibrator.setCalibration found current correction %d type %d' % (self.currVersion, self.currType))
134 
135  elif currPos > polyPos:
136 
137  # Call calibrate to get number of parameters
138  self.calibrate(0.1)
139  npar = self.nParUsed
140  self.currType = 1 # Use A+C by default
141 
142  if self.verbose:
143  print('LumiCalibrator.setCalibration - found %d parameters in %s' % (npar, algname))
144  if polyPos > 0:
145  npar += 4
146 
147  self.currVersion = int(self.parVec[npar])
148 
149  if self.verbose:
150  print('LumiCalibrator.setCalibration - reading current vers %d from position %d' % (self.currVersion, npar))
151 
152  if self.currVersion == 4:
153  self.currType = int(self.parVec.pop())
154  self.nPar -= 1
155 
156  if self.currVersion >= 3:
157  self.currParC = self.parVec.pop()
158  self.nPar -= 1
159 
160  self.currParB = self.parVec.pop()
161  self.currParA = self.parVec.pop()
162  self.currVersion = self.parVec.pop()
163  self.nPar -= 3
164 
165  if self.verbose:
166  print('LumiCalibrator.setCalibration found current correction %d type %d' % (self.currVersion, self.currType))
167 
168  if polyPos > 0:
169  if self.verbose:
170  print('LumiCalibrator.setCalibration - reading polynomial from list' , self.parVec[-4:])
171 
172  self.polyParC = self.parVec.pop()
173  self.polyParB = self.parVec.pop()
174  self.polyParA = self.parVec.pop()
175  self.polyVersion = self.parVec.pop()
176  self.nPar -= 4
177 
178 
179  def setLucidCurrent(self, currPayload):
180 
181  self.oldCurrentA = self.currentA
182  self.oldCurrentC = self.currentC
183 
184  if currPayload is None:
185  self.currentA = -1.
186  self.currentC = -1.
187  else:
188  self.currentA = currPayload['CurrentSideA']
189  self.currentC = currPayload['CurrentSideC']
190 
191 
192  if self.verbose:
193  print('LumiCalibrator.setLucidCurrent found Side A: %f Side C: %f' % (self.currentA, self.currentC))
194 
195  def dump(self):
196 
197  print('Calibration: %s, muToLumi: %f', (self.fType, self.muToLumi))
198  if self.fType == 'Logarithm':
199  print('par[0]: %f', self.parVec[0])
200 
201  elif self.fType == 'LookupTable_EventAND_Lin':
202  print('par[0]: %f', self.parVec[0])
203  print('par[1]: %f', self.parVec[1])
204  print('par[5]: %f', self.parVec[5])
205 
206  # Take raw luminosity (rate) value and return calibrated luminosity
207  def calibrate(self, rawLumi):
208 
209  cal = -1.
210  self.rflag = 0 # Success unless we fail
211 
212  if (rawLumi < 0.):
213  print('LumiCalibrator.calibrate(%f) - non-physical value!' % rawLumi)
214  self.rflag = 1
215  return 0.
216 
217  elif (rawLumi == 0.):
218  return 0.
219 
220  # Check for polynomial correction
221  calibstr = self.fType
222 
223  if calibstr.find('Polynomial') == 0:
224 
225  cal = self.calibPolynomial(rawLumi)
226 
227  elif calibstr.find('Logarithm') == 0:
228 
229  cal = self.calibLogarithm(rawLumi)
230 
231  elif calibstr.find('HitLogarithm') == 0:
232 
233  cal = self.calibHitLogarithm(rawLumi)
234 
235  elif calibstr.find('LookupTable_EventAND_Lin') == 0:
236 
237  try:
238  cal = self.calibLookupTable(rawLumi)
239  except Exception as e:
240  cal = 0.
241  self.rflag = 1
242  print('LumiCalibrator.calibLookupTable(%f) - Error: %s' % (rawLumi, e))
243 
244  elif calibstr.find('LookupTable_EventAND_Log') == 0:
245 
246  try:
247  cal = self.calibLookupTableLog(rawLumi)
248  except Exception as e:
249  cal = 0.
250  self.rflag = 1
251  print('LumiCalibrator.calibLookupTableLog(%f) - Error: %s' % (rawLumi, e))
252 
253  elif calibstr.find('LookupTable_EventANDFull_Log') == 0:
254 
255  try:
256  cal = self.calibLookupTableFullLog(rawLumi)
257  except Exception as e:
258  cal = 0.
259  self.rflag = 1
260  print('LumiCalibrator.calibLookupTableFullLog(%f) - Error: %s' % (rawLumi, e))
261 
262  elif calibstr.find('LookupTablePoisson_Lin') == 0:
263 
264  try:
265  cal = self.calibLookupTablePoisson(rawLumi)
266  except Exception as e:
267  cal = 0.
268  self.rflag = 1
269  print('LumiCalibrator.calibLookupTablePoisson(%f) - Error: %s' % (rawLumi, e))
270 
271  elif calibstr.find('LookupTableZeroPoisson_Lin') == 0:
272 
273  try:
274  cal = self.calibLookupTableZeroPoisson(rawLumi)
275  except Exception as e:
276  cal = 0.
277  self.rflag = 1
278  print('LumiCalibrator.calibLookupTableZeroPoisson(%f) - Error: %s' % (rawLumi, e))
279 
280  else:
281  print('LumiCalibrator.calibrate(%f) - Unknown calibration type %s!' % (rawLumi, self.fType))
282  self.rflag = 1
283  cal = 0.
284 
285  if self.rflag == 1:
286  return cal
287 
288  # Try to do polynomial and current correction in proper order
289  polyPos = calibstr.find("_PolyCorr")
290  currPos = calibstr.find("_CurrCorr")
291 
292  # No extra corrections
293  if polyPos == -1 and currPos == -1:
294  pass
295 
296  elif polyPos == -1 and currPos > 0:
297  cal = self.currentCorrection(cal)
298 
299  elif polyPos > 0 and currPos == -1:
300  cal = self.polyCorrection(cal)
301 
302  elif polyPos < currPos:
303  cal = self.polyCorrection(cal)
304  cal = self.currentCorrection(cal)
305 
306  elif currPos < polyPos:
307  cal = self.currentCorrection(cal)
308  cal = self.polyCorrection(cal)
309 
310  else:
311  print('LumiCalibrator.calibrate() - I am so confused: %s' % calibstr)
312 
313  return self.muToLumi * cal
314 
315  def currentCorrection(self, mu):
316 
317  correction = 1.
318 
319  current = -1.
320  if self.currType == 1:
321  current = self.currentA+self.currentC
322 
323  elif self.currType == 2:
324  current = self.currentA
325 
326  elif self.currType == 3:
327  current = self.currentC
328 
329  else:
330  print('LumiCalibrator.currentCorrection() - unknown current type: %d' % self.currType)
331  self.rflag = 1
332  return mu
333 
334  if self.currVersion == 0:
335  return mu
336 
337  if current == -1.:
338  if self.verbose:
339  print('LumiCalibrator.currentCorrection() - invalid LUCID currents found - A: %f C: %f' % (self.currentA, self.currentC))
340  print('LumiCalibrator.currentCorrection() - try using last values found - A: %f C: %f' % (self.oldCurrentA, self.oldCurrentC))
341 
342  self.rflag = 1 # Flag this as bad
343 
344  # Try using previous version
345  if self.currType == 1:
346  current = self.oldCurrentA+self.oldCurrentC
347 
348  elif self.currType == 2:
349  current = self.oldCurrentA
350 
351  elif self.currType == 3:
352  current = self.oldCurrentC
353 
354  if current == -1.:
355  return mu
356 
357  elif self.currVersion == 1:
358  correction = 100./(100.+self.currParA+self.currParB*current/self.nBunches)
359 
360  elif self.currVersion == 2:
361  correction = 100./(100.+self.currParA+self.currParB*current)
362 
363  elif self.currVersion == 3:
364  correction = 100./(100.+self.currParA+self.currParB*current+self.currParC*current**2)
365 
366  elif self.currVersion == 4: # Same as 3
367  correction = 100./(100.+self.currParA+self.currParB*current+self.currParC*current**2)
368 
369  else:
370  print('LumiCalibrator.currentCorrection() - unknown calibration version %d' % self.currVersion)
371 
372  if self.verbose and self.currVersion != 0:
373  print('LumiCalibrator.currentCorrection() - version %d -> currentA = %f, currentC = %f, correction = %f' % (self.currVersion, self.currentA, self.currentC, correction))
374 
375  return mu*correction
376 
377  def polyCorrection(self, mu):
378 
379  mucorr = mu
380 
381  # Parameters have already been parsed
382 
383  if self.polyVersion == 0:
384  pass
385 
386  elif self.polyVersion == 1:
387  mucorr = self.polyParA + self.polyParB * mu + self.polyParC * mu * mu
388 
389  else:
390  print('LumiCalibrator.polyCorrection() - unknown calibration version %d' % self.polyVersion)
391 
392  return mucorr
393 
394  def calibPolynomial(self, rawLumi):
395  cal = 0.
396  self.rflag = 1
397 
398  nrange = int(self.parVec[0])
399  self.nParUsed = 8 * nrange + 1
400 
401  for i in range(nrange):
402  rmin = self.parVec[i+1]
403  rmax = self.parVec[i+2]
404  if rawLumi < rmax and rawLumi >= rmin:
405  a = [self.parVec[i+3]]
406  a.append(self.parVec[i+4])
407  a.append(self.parVec[i+5])
408  a.append(self.parVec[i+6])
409  a.append(self.parVec[i+7])
410  a.append(self.parVec[i+8])
411  for k in range(6):
412  cal += a[k]*pow(rawLumi, k)
413 
414  self.rflag = 0
415  break
416 
417  if self.rflag == 1:
418  print('LumiCalibrator.calibPolynomial(%f) - Value out of range' % rawLumi)
419 
420  return cal
421 
422  def calibLogarithm(self, rawLumi):
423 
424  cal = 0.
425  self.rflag = 0
426 
427  self.nParUsed = 1
428 
429  invEff = self.parVec[0]
430 
431  try:
432  cal = -invEff*math.log(1.-rawLumi)
433 
434  except Exception:
435  cal = 0.
436  self.rflag = 1
437  # Don't print for simple saturation
438  if rawLumi != 1.:
439  print('LumiCalibrator.calibLogarithm(%f) - Unphysical input!' % rawLumi)
440 
441  return cal
442 
443  def calibHitLogarithm(self, rawLumi):
444 
445  cal = 0.
446 
447  invEff = self.parVec[0]
448  channels = self.parVec[1]
449  offset = self.parVec[2]
450  maxRawLumiperBX = self.parVec[3]
451 
452  self.nParUsed = 4
453 
454  # rawLumi can be > 1 here, check value against maxRawLumiPerBX
455  if rawLumi > maxRawLumiperBX:
456  self.rflag = 1
457  print('LumiCalibrator.calibHitLogarithm(%f) - input greater than max range %f!' % (rawLumi, maxRawLumiperBX))
458  return cal
459 
460  try:
461  cal = -invEff*math.log(1.-rawLumi/channels)/(1-offset)
462 
463  except Exception:
464  cal = 0.
465  self.rflag = 1
466  print('LumiCalibrator.calibHitLogarithm(%f) - Unphysical input!' % rawLumi)
467 
468  return cal
469 
470  # LookupTable_EventAND_Lin
471  def calibLookupTable(self, rawLumi):
472 
473  cal = 0.
474 
475  self.nParUsed = 6
476 
477  if rawLumi < 0.:
478  self.rflag = 1
479  print('LumiCalibrator.calibLookupTable(%f) - Unphysical input to LUT!' % rawLumi)
480 
481  elif rawLumi > 0.:
482  sigo = self.parVec[0]
483  siga = self.parVec[1]
484  # Try fast algorithm first
485  cal = self.parVec[5]*self.getMuvis(rawLumi, sigo, siga)
486  if self.rflag == 1:
487  # Try again with slower algorithm
488  cal = self.parVec[5]*self.getMuvis2(rawLumi, sigo, siga)
489 
490  return cal
491 
492  # LookupTable_EventAND_Log
493  def calibLookupTableLog(self, rawLumi):
494 
495  cal = 0.
496 
497  self.nParUsed = 8
498 
499  if (rawLumi < 0.) or (rawLumi >= 1.):
500  self.rflag = 1
501  print('LumiCalibrator.calibLookupTableLog(%f) - Unphysical input to LUT!' % rawLumi)
502 
503  elif rawLumi > 0.:
504  sigo = self.parVec[0]
505  siga = self.parVec[1]
506  # Try fast algorithm first
507  cal = self.parVec[7]*self.getMuvis(rawLumi, sigo, siga)
508  if self.rflag == 1:
509  # Try again with slower algorithm
510  cal = self.parVec[7]*self.getMuvis2(rawLumi, sigo, siga)
511 
512  return cal
513 
514  # From Vincent
515  def getMuvis(self, rawPerBX, sigo, siga):
516 
517  # Guess?
518  munew = 0.01
519 
520  b = sigo/siga
521  a = (b + 1)/2.
522 
523  # Set error, and clear below if we converge
524  self.iflag = 1
525 
526  # Set a fixed number of cycles, but break if we converge faster
527  for i in range(30):
528  mu = munew
529  y = 1 - 2 * math.exp(-a * mu) + math.exp(-b * mu)
530  dy = 2 * a * math.exp(-a * mu) - b * math.exp(-b * mu)
531 
532  munew = mu - (y-rawPerBX)/dy
533 
534  #print "Iteration: %d, Munew: %f, Muold: %f" % (i, munew, mu)
535  if munew <= 0.:
536  return 0.
537 
538  if math.fabs(munew-mu)/munew < 1.e-5:
539  self.iflag = 0
540  return munew
541 
542 
543  print('LumiCalibrator.calibLookupTable(', rawPerBX, ') - did not converge (Vincent method)!')
544  return munew
545 
546  # From Mika
547  def getMuvis2(self, rawPerBX, sigo, siga):
548  muvl=1e-10
549  muvu=100
550  muvm=10
551  sr=sigo/siga
552  rbxl=self.rpbx(sr,muvl)
553  rbxu=self.rpbx(sr,muvu)
554  rbxm=self.rpbx(sr,muvm)
555 
556  # Set error and clear below if we converge
557  self.rflag = 1
558 
559  # Check that starting value is in the valid range
560  if rawPerBX < rbxl or rawPerBX > rbxu:
561  print('LumiCalibrator.calibLookupTable(', rawPerBX, ') - raw lumi value outside of LUT range', rbxl, 'to', rbxu, '!')
562  return 0.
563 
564  # Restrict to a fixed number of iterations
565  for i in range(50):
566  if rbxl<rawPerBX and rbxm>rawPerBX:
567  rbxu=rbxm
568  muvu=muvm
569  muvm=0.5*(muvu+muvl)
570  else:
571  rbxl=rbxm
572  muvl=muvm
573  muvm=0.5*(muvu+muvl)
574 
575  rbxm = self.rpbx(sr, muvm)
576 
577  if (muvu-muvl)/muvl < 1e-5:
578  self.rflag = 0
579  return muvm
580 
581  # Did not converge
582  print('LumiCalibrator.calibLookupTable(', rawPerBX, ') - did not converge (Mika method)!')
583  return muvm
584 
585  def rpbx(self, sr, muvis):
586  return 1 - 2*math.exp(-(1+sr)*muvis/2) + math.exp(-sr*muvis)
587 
588  # LookupTable_EventANDFull_Log
589  def calibLookupTableFullLog(self, rawLumi):
590 
591  cal = 0.
592 
593  self.nParUsed = 9
594 
595  if (rawLumi < 0.) or (rawLumi >= 1.):
596  self.rflag = 1
597  print('LumiCalibrator.calibLookupTableFullLog(%f) - Unphysical input to LUT!' % rawLumi)
598 
599  elif rawLumi > 0.:
600  sigA = self.parVec[0]
601  sigC = self.parVec[1]
602  sigAND = self.parVec[2]
603 
604  # Try fast algorithm first
605  cal = self.parVec[8]*self.getMuvisFull(rawLumi, sigA, sigC, sigAND)
606  if self.rflag == 1:
607  # Try again with slower algorithm
608  cal = self.parVec[8]*self.getMuvisFull2(rawLumi, sigA, sigC, sigAND)
609 
610  return cal
611 
612  # Full version
613  def getMuvisFull(self, rawPerBX, sigA, sigC, sigAND):
614 
615  # Guess?
616  munew = 0.01
617 
618  ra = sigA/sigAND
619  rc = sigC/sigAND
620  b = ra+rc-1 # sigOR/sigAND
621 
622  # Set error, and clear below if we converge
623  self.iflag = 1
624 
625  # Set a fixed number of cycles, but break if we converge faster
626  for i in range(30):
627  mu = munew
628  y = 1 - math.exp(-ra * mu) - math.exp(-rc * mu) + math.exp(-b * mu)
629  dy = ra * math.exp(-ra * mu) + rc * math.exp(-rc * mu) - b * math.exp(-b * mu)
630 
631  munew = mu - (y-rawPerBX)/dy
632 
633  #print "Iteration: %d, Munew: %f, Muold: %f" % (i, munew, mu)
634  if munew <= 0.:
635  return 0.
636 
637  if math.fabs(munew-mu)/munew < 1.e-5:
638  self.iflag = 0
639  return munew
640 
641 
642  print('LumiCalibrator.calibLookupTable(', rawPerBX, ') - did not converge (Vincent method)!')
643  return munew
644 
645  # From Mika
646  def getMuvisFull2(self, rawPerBX, sigA, sigC, sigAND):
647  muvl=1e-10
648  muvu=100
649  muvm=10
650 
651  ra = sigA/sigAND
652  rc = sigC/sigAND
653  sr=ra+rc-1 # = sigOR/sigAND
654  rbxl=self.rpbxFull(ra, rc, sr,muvl)
655  rbxu=self.rpbxFull(ra, rc, sr,muvu)
656  rbxm=self.rpbxFull(ra, rc, sr,muvm)
657 
658  # Set error and clear below if we converge
659  self.rflag = 1
660 
661  # Check that starting value is in the valid range
662  if rawPerBX < rbxl or rawPerBX > rbxu:
663  print('LumiCalibrator.calibLookupTable(', rawPerBX, ') - raw lumi value outside of LUT range', rbxl, 'to', rbxu, '!')
664  return 0.
665 
666  # Restrict to a fixed number of iterations
667  for i in range(50):
668  if rbxl<rawPerBX and rbxm>rawPerBX:
669  rbxu=rbxm
670  muvu=muvm
671  muvm=0.5*(muvu+muvl)
672  else:
673  rbxl=rbxm
674  muvl=muvm
675  muvm=0.5*(muvu+muvl)
676 
677  rbxm = self.rpbxFull(ra, rc, sr, muvm)
678 
679  if (muvu-muvl)/muvl < 1e-5:
680  self.rflag = 0
681  return muvm
682 
683  # Did not converge
684  print('LumiCalibrator.calibLookupTable(', rawPerBX, ') - did not converge (Mika method)!')
685  return muvm
686 
687  def rpbxFull(self, ra, rc, sr, muvis):
688  return 1 - math.exp(-ra*muvis) - math.exp(-rc*muvis) + math.exp(-sr*muvis)
689 
690  # LookupTablePoisson_Lin':
691  def calibLookupTablePoisson(self, rawLumi):
692 
693  offset = self.parVec[0]
694  maxRawLumiperBX = self.parVec[1]
695  #mu_max = self.parVec[2]
696  #points = self.parVec[3]
697  nRefs = int(self.parVec[4])
698  ref = self.parVec[5:]
699 
700  self.nParUsed = 5+nRefs
701 
702  cal = 0.
703  self.rflag = 1
704 
705  if rawLumi > maxRawLumiperBX:
706  print('LumiCalibrator.calibLookupTablePoisson(%f) - input greater than max range %f!' % (rawLumi, maxRawLumiperBX))
707  return cal
708 
709  # Iteratively solve
710  munew = 0.001
711 
712  # Set a fixed number of cycles, but break faster if we converge
713  for i in range(30):
714  mu = munew
715  # No constant term in hit counting
716  y = 0
717  dy = 0
718  # Now add additional terms in sum, divide out factor of e^(-mu)
719  # Use running product to calculate mu^n/n!
720  fact = 1
721  for j in range(nRefs):
722  n = j+1
723  #term = ref[j] * math.pow(mu, n) / self.factorial(n)
724  #term = ref[j] * math.pow(mu, n) / math.factorial(n)
725  fact *= (mu/n)
726  term = ref[j] * fact
727  y += term
728  dy += term*(n/mu-1)
729 
730  # Here we are computing the probability of a hit, so we compare to the hit rate
731  munew = mu - (y-rawLumi/math.exp(-mu))/dy # Remember to put back in e^(-mu)
732  cal = munew
733 
734  if munew <= 0.:
735  cal = 0.
736  print('LumiCalibrator.calibLookupTablePoisson(%f) - failed to converge (went negative)!'% (rawLumi))
737  return cal
738 
739  if math.fabs(munew-mu)/munew < 1.e-5:
740  self.rflag = 0
741  return cal/(1-offset)
742 
743 
744  print('LumiCalibrator.calibLookupTablePoisson(%f) - failed to converge (trials)!'% (rawLumi))
745  return cal/(1-offset)
746 
747  # LookupTableZeroPoisson_Lin':
748  def calibLookupTableZeroPoisson(self, rawLumi):
749 
750  offset = self.parVec[0]
751  maxRawLumiperBX = self.parVec[1]
752  #mu_max = self.parVec[2]
753  #points = self.parVec[3]
754  nRefs = int(self.parVec[4])
755  ref = self.parVec[5:]
756 
757  self.nParUsed = 5+nRefs
758 
759  cal = 0.
760  self.rflag = 1
761 
762  if rawLumi > maxRawLumiperBX:
763  print('LumiCalibrator.calibLookupTableZeroPoisson(%f) - input greater than max range %f!' % (rawLumi, maxRawLumiperBX))
764  return cal
765 
766  # Iteratively solve
767  munew = 0.001
768 
769  # Set a fixed number of cycles, but break faster if we converge
770  for i in range(30):
771  mu = munew
772  # Constant term first (n=0) - divide out constant factor of e^(-mu)
773  y = 1
774  dy = -1
775  fact = 1
776  # Now add additional terms in sum
777  for j in range(nRefs):
778  n = j+1
779  fact *= (mu/n)
780  # term = ref[j] * math.pow(mu, n) / self.factorial(n)
781  term = ref[j] * fact
782  y += term
783  dy += term*(n/mu-1)
784 
785  # Here we are computing the probability of a *zero*, so compare to observed *zero* rate: (1-rawLumi)
786  zRate = (1-rawLumi)
787  munew = mu - (y-zRate/math.exp(-mu))/dy # Remember to put back in e^(-mu)
788  cal = munew
789 
790  if munew <= 0.:
791  print('LumiCalibrator.calibLookupTableZeroPoisson(%f) - failed to converge (negative)!'% (rawLumi))
792  cal = 0.
793  return cal
794 
795  if math.fabs(munew-mu)/munew < 1.e-5:
796  self.rflag = 0
797  return cal/(1-offset)
798 
799  print('LumiCalibrator.calibLookupTableZeroPoisson(%f) - failed to converge (trials)!'% (rawLumi))
800  return cal/(1-offset)
python.LumiCalibrator.LumiCalibrator.nBunches
nBunches
Definition: LumiCalibrator.py:41
python.LumiCalibrator.LumiCalibrator.dump
def dump(self)
Definition: LumiCalibrator.py:195
python.LumiCalibrator.LumiCalibrator.currentA
currentA
Definition: LumiCalibrator.py:44
python.LumiCalibrator.LumiCalibrator.calibrate
def calibrate(self, rawLumi)
Definition: LumiCalibrator.py:207
python.LumiCalibrator.LumiCalibrator.factorial
def factorial(self, n)
Definition: LumiCalibrator.py:58
python.LumiCalibrator.LumiCalibrator.currType
currType
Definition: LumiCalibrator.py:34
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.LumiCalibrator.LumiCalibrator.iflag
iflag
Definition: LumiCalibrator.py:524
python.LumiBlobConversion.bConvertList
def bConvertList(b, nbyte=1, nval=1)
Definition: LumiBlobConversion.py:39
python.LumiCalibrator.LumiCalibrator
Definition: LumiCalibrator.py:20
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
python.LumiCalibrator.LumiCalibrator.setCalibration
def setCalibration(self, calibPayload)
Definition: LumiCalibrator.py:70
python.LumiCalibrator.LumiCalibrator.currentCorrection
def currentCorrection(self, mu)
Definition: LumiCalibrator.py:315
python.LumiCalibrator.LumiCalibrator.calibLogarithm
def calibLogarithm(self, rawLumi)
Definition: LumiCalibrator.py:422
python.LumiCalibrator.LumiCalibrator.polyParA
polyParA
Definition: LumiCalibrator.py:37
python.LumiCalibrator.LumiCalibrator.polyParB
polyParB
Definition: LumiCalibrator.py:38
python.LumiCalibrator.LumiCalibrator.oldCurrentC
oldCurrentC
Definition: LumiCalibrator.py:48
python.LumiCalibrator.LumiCalibrator.calibLookupTablePoisson
def calibLookupTablePoisson(self, rawLumi)
Definition: LumiCalibrator.py:691
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.LumiCalibrator.LumiCalibrator.calibPolynomial
def calibPolynomial(self, rawLumi)
Definition: LumiCalibrator.py:394
python.LumiCalibrator.LumiCalibrator.setLucidCurrent
def setLucidCurrent(self, currPayload)
Definition: LumiCalibrator.py:179
python.LumiCalibrator.LumiCalibrator.__init__
def __init__(self)
Definition: LumiCalibrator.py:22
python.LumiCalibrator.LumiCalibrator.polyParC
polyParC
Definition: LumiCalibrator.py:39
python.LumiCalibrator.LumiCalibrator.oldCurrentA
oldCurrentA
Definition: LumiCalibrator.py:47
python.LumiCalibrator.LumiCalibrator.polyVersion
polyVersion
Definition: LumiCalibrator.py:36
python.LumiCalibrator.LumiCalibrator.parVec
parVec
Definition: LumiCalibrator.py:27
python.LumiCalibrator.LumiCalibrator.nParUsed
nParUsed
Definition: LumiCalibrator.py:55
python.LumiCalibrator.LumiCalibrator.verbose
verbose
Definition: LumiCalibrator.py:50
python.LumiCalibrator.LumiCalibrator.calibLookupTableFullLog
def calibLookupTableFullLog(self, rawLumi)
Definition: LumiCalibrator.py:589
python.LumiCalibrator.LumiCalibrator.polyCorrection
def polyCorrection(self, mu)
Definition: LumiCalibrator.py:377
python.LumiCalibrator.LumiCalibrator.rpbx
def rpbx(self, sr, muvis)
Definition: LumiCalibrator.py:585
python.LumiCalibrator.LumiCalibrator.currParC
currParC
Definition: LumiCalibrator.py:33
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.LumiCalibrator.LumiCalibrator.currentC
currentC
Definition: LumiCalibrator.py:45
python.LumiCalibrator.LumiCalibrator.calibLookupTableLog
def calibLookupTableLog(self, rawLumi)
Definition: LumiCalibrator.py:493
python.LumiCalibrator.LumiCalibrator.getMuvis
def getMuvis(self, rawPerBX, sigo, siga)
Definition: LumiCalibrator.py:515
python.LumiCalibrator.LumiCalibrator.getMuvisFull2
def getMuvisFull2(self, rawPerBX, sigA, sigC, sigAND)
Definition: LumiCalibrator.py:646
python.LumiCalibrator.LumiCalibrator.getMuvisFull
def getMuvisFull(self, rawPerBX, sigA, sigC, sigAND)
Definition: LumiCalibrator.py:613
python.LumiCalibrator.LumiCalibrator.currParB
currParB
Definition: LumiCalibrator.py:32
python.LumiCalibrator.LumiCalibrator.currParA
currParA
Definition: LumiCalibrator.py:31
python.LumiCalibrator.LumiCalibrator.getMuvis2
def getMuvis2(self, rawPerBX, sigo, siga)
Definition: LumiCalibrator.py:547
python.LumiCalibrator.LumiCalibrator.muToLumi
muToLumi
Definition: LumiCalibrator.py:26
python.LumiCalibrator.LumiCalibrator.calibLookupTable
def calibLookupTable(self, rawLumi)
Definition: LumiCalibrator.py:471
python.LumiCalibrator.LumiCalibrator.currVersion
currVersion
Definition: LumiCalibrator.py:30
python.LumiCalibrator.LumiCalibrator.calibLookupTableZeroPoisson
def calibLookupTableZeroPoisson(self, rawLumi)
Definition: LumiCalibrator.py:748
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
python.LumiCalibrator.LumiCalibrator.rflag
rflag
Definition: LumiCalibrator.py:28
python.LumiCalibrator.LumiCalibrator.nPar
nPar
Definition: LumiCalibrator.py:24
python.LumiCalibrator.LumiCalibrator.fType
fType
Definition: LumiCalibrator.py:25
python.LumiCalibrator.LumiCalibrator.calibHitLogarithm
def calibHitLogarithm(self, rawLumi)
Definition: LumiCalibrator.py:443
python.LumiCalibrator.LumiCalibrator.rpbxFull
def rpbxFull(self, ra, rc, sr, muvis)
Definition: LumiCalibrator.py:687
python.LumiCalibrator.LumiCalibrator.facTable
facTable
Definition: LumiCalibrator.py:53