ATLAS Offline Software
WriteCellNoiseToCool.py
Go to the documentation of this file.
1 #!/bin/env python
2 
3 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4 #
5 # File: WriteCellNoiseToCool.py
6 # Purpose: Manual update of cell noise constants from ascii file
7 #
8 # 2014-07-14 - Sasha, based on update_noise_bulk.py from Carlos,Gui,Blake,Yuri
9 # 2016-12-14 - Yuri Smirnov, change for PyCintex->cppyy for ROOT6
10 # 2020-06-06 - Sasha - introducing --end and --endlumi parameters
11 
12 import getopt,sys,os,re,bisect
13 os.environ['TERM'] = 'linux'
14 
15 def usage():
16  print ("Usage: ",sys.argv[0]," [OPTION] ... ")
17  print ("Updates Cell Noise database using new values from ASCII file")
18  print ("")
19  print ("-h, --help shows this help")
20  print ("-i, --infile= specify the input sqlite file or full schema string")
21  print ("-o, --outfile= specify the output sqlite file")
22  print ("-t, --intag= specify the input tag")
23  print ("-T, --outtag= specify the output tag")
24  print ("-f, --folder= specify status folder to use e.g. /TILE/OFL02/NOISE/CELL ")
25  print ("-d, --dbname= specify the database name e.g. OFLP200")
26  print ("-S, --server= specify server - ORACLE or FRONTIER, default is FRONTIER")
27  print ("-x, --txtfile= specify the text file with the new noise constants")
28  print ("-r, --run= specify run number for start of IOV")
29  print ("-l, --lumi= specify lumiblock number for start of IOV, default is 0")
30  print ("-b, --begin= specify run number of first iov in multi-iov mode, by default uses very first iov")
31  print ("-e, --end= specify run number of last iov in multi-iov mode, by default uses latest iov")
32  print ("-L, --endlumi= specify lumi block number for last iov in multi-iov mode, default is 0")
33  print ("-A, --adjust in multi-iov mode adjust iov boundaries to nearest iov available in DB, default is False")
34  print ("-n, --channel= specify cool channel to use (48 by defalt)")
35  print ("-s, --scale= specify scale factor for all the fields except ratio field")
36  print ("-u --update set this flag if output sqlite file should be updated, otherwise it'll be recreated")
37  print ("--scaleElec= specify separate scale factor for all electronic noise fields except ratio field")
38  print ("if run number and lumiblock number are omitted - all IOVs from input file are updated")
39 
40 letters = "hi:o:t:T:f:d:S:x:r:l:b:e:L:A:n:s:u"
41 keywords = ["help","infile=","outfile=","intag=","outtag=","folder=","dbname=","server=","txtfile=","run=","lumi=","begin=","end=","endlumi=","adjust",
42  "channel=","scale=","scaleA=","scaleB=","scaleD=","scaleE=","scaleD4=","scaleC10=","scaleD4sp=","scaleC10sp=","scaleElec=","update"]
43 
44 try:
45  opts, extraparams = getopt.getopt(sys.argv[1:],letters,keywords)
46 except getopt.GetoptError as err:
47  print (str(err))
48  usage()
49  sys.exit(2)
50 
51 # defaults
52 inFile = ''
53 outFile = ''
54 inTag = ''
55 outTag = ''
56 folderPath = ''
57 dbName = ''
58 server = ''
59 txtFile = ''
60 run = -1
61 lumi = 0
62 beg = -1
63 end = 2147483647
64 endlumi = 0
65 iov = True
66 adjust = False
67 update = False
68 chan = 48 # represents Tile
69 scale = 0.0 # means do not scale
70 scaleA = 0.0 # scale for pileup term in A cells
71 scaleB = 0.0 # scale for pileup term in B cells
72 scaleD = 0.0 # scale for pileup term in D cells
73 scaleE = 0.0 # scale for pileup term in E cells
74 scaleD4 = 0.0 # scale for pileup term in D4
75 scaleC10 = 0.0 # scale for pileup term in C10
76 scaleD4sp = 0.0 # scale for pileup term in D4 special
77 scaleC10sp = 0.0 # scale for pileup term in C10 special
78 scaleElec = 0.0 # scale for electronic noise
79 
80 for o, a in opts:
81  a = a.strip()
82  if o in ("-i","--infile"):
83  inFile = a
84  elif o in ("-o","--outfile"):
85  outFile = a
86  elif o in ("-t","--intag"):
87  inTag = a
88  elif o in ("-T","--outtag"):
89  outTag = a
90  elif o in ("-f","--folder"):
91  folderPath = a
92  elif o in ("-d","--dbname"):
93  dbName = a
94  elif o in ("-S","--server"):
95  server = a
96  elif o in ("-r","--run"):
97  run = int(a)
98  if run>=0:
99  iov = False
100  elif o in ("-l","--lumi"):
101  lumi = int(a)
102  elif o in ("-b","--begin"):
103  beg = int(a)
104  iov = True
105  elif o in ("-e","--end"):
106  end = int(a)
107  elif o in ("-L","--endlumi"):
108  endlumi = int(a)
109  elif o in ("-A","--adjust"):
110  adjust = True
111  elif o in ("-u","--update"):
112  update = True
113  elif o in ("-n","--channel"):
114  chan = int(a)
115  elif o in ("-s","--scale"):
116  scale = float(a)
117  elif o in ("-s","--scaleA"):
118  scaleA = float(a)
119  elif o in ("-s","--scaleB"):
120  scaleB = float(a)
121  elif o in ("-s","--scaleD"):
122  scaleD = float(a)
123  elif o in ("-s","--scaleE"):
124  scaleE = float(a)
125  elif o in ("-s","--scaleD4"):
126  scaleD4 = float(a)
127  elif o in ("-s","--scaleC10"):
128  scaleC10 = float(a)
129  elif o in ("-s","--scaleD4sp"):
130  scaleD4sp = float(a)
131  elif o in ("-s","--scaleC10sp"):
132  scaleC10sp = float(a)
133  elif o in ("-s","--scaleElec"):
134  scaleElec = float(a)
135  elif o in ("-x","--txtfile"):
136  txtFile = a
137  elif o in ("-h","--help"):
138  usage()
139  sys.exit(2)
140  else:
141  print (o, a)
142  usage()
143  sys.exit(2)
144 
145 tile=(chan==48)
146 
147 rescale=(scale>0.0)
148 if scaleElec == 0.0:
149  scaleElec = scale
150 else:
151  rescale=True
152 if scaleA == 0.0:
153  scaleA = scale
154 else:
155  rescale=True
156 if scaleB == 0.0:
157  scaleB = scale
158 else:
159  rescale=True
160 if scaleD == 0.0:
161  scaleD = scale
162 else:
163  rescale=True
164 if scaleE == 0.0:
165  scaleE = scale
166 else:
167  rescale=True
168 if scaleD4 == 0.0:
169  scaleD4 = scaleD
170 else:
171  rescale=True
172 if scaleC10 == 0.0:
173  scaleC10 = scaleB
174 else:
175  rescale=True
176 if scaleD4sp == 0.0:
177  scaleD4sp = scaleD4
178 else:
179  rescale=True
180 if scaleC10sp == 0.0:
181  scaleC10sp = scaleC10
182 else:
183  rescale=True
184 
185 #=== check presence of all parameters
186 print ("")
187 if len(inFile)<1:
188  raise Exception("Please, provide infile (e.g. --infile=tileSqlite.db or --infile=COOLOFL_TILE/OFLP200)")
189 if len(outFile)<1:
190  raise Exception("Please, provide outfile (e.g. --outfile=tileSqlite_New.db)")
191 if len(inTag)<1:
192  raise Exception("Please, provide intag (e.g. --intag=TileOfl02NoiseCell-IOVDEP-01)")
193 if len(outTag)<1:
194  raise Exception("Please, provide outtag (e.g. --outtag=TileOfl02NoiseCell-IOVDEP-01)")
195 if len(folderPath)<1:
196  raise Exception("Please, provide folder (e.g. --folder=/TILE/OFL02/NOISE/CELL)")
197 if len(dbName)<1:
198  raise Exception("Please, provide dbname (e.g. --dbname=OFLP200 or --dbname=CONDBR2)")
199 
200 import cppyy
201 
202 from CaloCondBlobAlgs import CaloCondTools, CaloCondLogger
203 from TileCalibBlobPython import TileCalibTools
204 from TileCalibBlobPython import TileCellTools
205 
206 # get a logger
207 log = CaloCondLogger.getLogger("WriteCellNoise")
208 import logging
209 if iov:
210  log.setLevel(logging.INFO)
211 else:
212  log.setLevel(logging.DEBUG)
213 
214 
215 if inTag=="HEAD":
216  inTag=""
217 if outTag=="HEAD":
218  outTag=""
219 
220 if os.path.isfile(inFile):
221  ischema = 'sqlite://;schema='+inFile+';dbname='+dbName
222 else:
223  log.info("File %s was not found, assuming it's full schema string" , inFile)
224  ischema = inFile
225  # possible strings for inFile - full schema connection string or short names like
226  # COOLOFL_CALO/OFLP200 COOLOFL_CALO/COMP200 COOLOFL_CALO/CONDBR2
227  # COOLOFL_TILE/OFLP200 COOLOFL_TILE/COMP200 COOLOFL_TILE/CONDBR2
228 
229 rb = max(run,beg)
230 if run<0:
231  if run<=-30:
232  cabling = 'RUN3'
233  elif run<=-21:
234  cabling = 'RUN2a'
235  elif run<=-20:
236  cabling = 'RUN2'
237  elif run<=-10:
238  cabling = 'RUN1'
239  else:
240  cabling = 'RUN2a'
241 elif run<222222 or 'COMP200' in ischema:
242  cabling = 'RUN1'
243 else:
244  if ('OFLP200' in ischema and rb>=330000) or rb>=400000:
245  cabling = 'RUN3'
246  elif ('OFLP200' in ischema and rb>=310000) or rb>=342550:
247  cabling = 'RUN2a'
248  else:
249  cabling = 'RUN2'
250 hashMgr=None
251 hashMgrDef=TileCellTools.TileCellHashMgr(cabling=cabling)
252 hashMgrA=TileCellTools.TileCellHashMgr("UpgradeA")
253 hashMgrBC=TileCellTools.TileCellHashMgr("UpgradeBC")
254 hashMgrABC=TileCellTools.TileCellHashMgr("UpgradeABC")
255 
256 iovList = []
257 iovUntil = []
258 until = (TileCalibTools.MAXRUN,TileCalibTools.MAXLBK)
259 if end >= TileCalibTools.MAXRUN:
260  end = TileCalibTools.MAXRUN
261  endlumi = TileCalibTools.MAXLBK
262 
263 if iov:
264  #=== Get list of IOVs by tricking TileCalibTools to read a Calo blob
265  idb = TileCalibTools.openDbConn(ischema,server)
266  try:
267  blobReader = TileCalibTools.TileBlobReader(idb,folderPath, inTag)
268  iovList = blobReader.getIOVsWithinRange(-1,chan)
269  except Exception:
270  log.warning("Can not read IOVs from input DB file")
271  idb.closeDatabase()
272 
273  iovList += [until]
274  if beg<0:
275  since = iovList[0]
276  else:
277  since = (beg, lumi)
278  ib=bisect.bisect(iovList,since)-1
279  if ib<0:
280  ib=0
281  if iovList[ib] != since:
282  if adjust:
283  since = iovList[ib]
284  log.info( "Moving beginning of first IOV with new cell noise from (%d,%d) to (%d,%d)" , beg,lumi,since[0],since[1])
285  else:
286  iovList[ib] = since
287  log.info( "Creating new IOV starting from (%d,%d) with new cell noise" , beg,lumi)
288 
289  if end<0:
290  ie=ib+1
291  if ie>=len(iovList):
292  ie=ib
293  until=iovList[ie]
294  log.info( "Next IOV with old cell noise starts from (%d,%d)" , until[0],until[1])
295  else:
296  until=(end,endlumi)
297  ie=bisect.bisect_left(iovList,until)
298  if ie>=len(iovList):
299  ie=len(iovList)-1
300 
301  if iovList[ie] != until:
302  if adjust:
303  until=iovList[ie]
304  log.info( "Moving end of last IOV from (%d,%d) to (%d,%d)" , end,endlumi,until[0],until[1])
305  else:
306  log.info( "Keeping end of last IOV at (%d,%d) - new IOV is shorter than IOV in input DB" , end,endlumi)
307  iovList[ie] = until
308 
309  iovList = iovList[ib:ie]
310  iovUntil = iovList[1:] + [until]
311  run = since[0]
312  lumi = since[1]
313  log.info( "IOVs: %s" , str(iovList))
314  log.info( "%d IOVs in total, end of last IOV is %s" , ie-ib,str(until))
315 
316 if len(iovList)==0:
317  if run<0:
318  raise Exception("Please, provide run number at command line")
319  else:
320  log.info( "Creating single IOV starting from run,lumi %d,%d" , run,lumi)
321  since = (run, lumi)
322  until = (end, endlumi)
323  iovList = [since]
324  iovUntil = [until]
325 
326 #=== Open DB connections
327 oschema = 'sqlite://;schema='+outFile+';dbname='+dbName
328 dbr = CaloCondTools.openDbConn(ischema,server)
329 update = update or (inFile==outFile)
330 dbw = CaloCondTools.openDbConn(oschema,('UPDATE' if update else 'RECREATE'))
331 reader = CaloCondTools.CaloBlobReader(dbr,folderPath,inTag)
332 writer = CaloCondTools.CaloBlobWriter(dbw,folderPath,'Flt',(outTag!="" and outTag!="HEAD"))
333 
334 
335 #== read input file
336 cellData = {}
337 ival=0
338 igain=0
339 icell=[0,0,0,0,0,0,0]
340 gain=-1
341 useNames=None
342 useModuleNames=None
343 useGain=None
344 
345 if len(txtFile):
346 # try:
347  with open(txtFile,"r") as f:
348  cellDataText = f.readlines()
349 
350  for line in cellDataText:
351  fields = line.strip().split()
352  #=== ignore empty and comment lines
353  if not len(fields) :
354  continue
355  if fields[0].startswith("#"):
356  continue
357 
358  if fields[0][:1].isalpha():
359  print (fields)
360  if useNames is not None and not useNames:
361  raise Exception("Mixture of formats in inpyt file %s - useNames" % (txtFile))
362  useNames=True
363  if fields[0]=='Cell':
364  if useModuleNames is not None and useModuleNames:
365  raise Exception("Mixture of formats in inpyt file %s - useModuleNames" % (txtFile))
366  useModuleNames=False
367  modName=''
368  cellName=fields[1]
369  else:
370  if useModuleNames is not None and not useModuleNames:
371  raise Exception("Mixture of formats in inpyt file %s - useModuleNames" % (txtFile))
372  useModuleNames=True
373  modName=fields[0]
374  cellName=fields[1]
375  if fields[2].isdigit():
376  if useGain is not None and not useGain:
377  raise Exception("Mixture of formats in inpyt file %s - useGain" % (txtFile))
378  useGain=True
379  gain=int(fields[2])
380  noise = fields[3:]
381  if ival<len(noise):
382  ival=len(noise)
383  if igain<gain:
384  igain=gain
385  else:
386  if useGain is not None and useGain:
387  raise Exception("Mixture of formats in inpyt file %s - useGain" % (txtFile))
388  if len(fields)>3:
389  raise Exception("Too many fields in input file %s" % (txtFile))
390  useGain=False
391  gain=-1
392  noise = [-1]+fields[2:]
393  ival=1
394  if cellName=='D0':
395  cellName='D*0'
396  if cellName.startswith('BC'):
397  cellName='B'+cellName[2:]
398  if not ('+' in cellName or '-' in cellName or '*' in cellName):
399  p = re.search("\\d", cellName).start()
400  cellPos = modName+cellName[:p] + '+' + cellName[p:]
401  cellNeg = modName+cellName[:p] + '-' + cellName[p:]
402  dictKey = (cellPos,gain)
403  cellData[dictKey] = noise
404  dictKey = (cellNeg,gain)
405  cellData[dictKey] = noise
406  if (cellName=='spE1'):
407  for cellNm in ['mbE+1','mbE-1','e4E+1','e4E-1']:
408  cellN = modName+cellNm
409  dictKey = (cellN,gain)
410  if dictKey not in cellData:
411  cellData[dictKey] = noise
412  else:
413  cellN = modName+cellName
414  dictKey = (cellN,gain)
415  cellData[dictKey] = noise
416  if (cellName=='spE+1'):
417  for cellNm in ['mbE+1','e4E+1']:
418  cellN = modName+cellNm
419  dictKey = (cellN,gain)
420  if dictKey not in cellData:
421  cellData[dictKey] = noise
422  if (cellName=='spE-1'):
423  for cellNm in ['mbE-1','e4E-1']:
424  cellN = modName+cellNm
425  dictKey = (cellN,gain)
426  if dictKey not in cellData:
427  cellData[dictKey] = noise
428  icell[gain]+=1
429  else:
430  if useNames is not None and useNames:
431  raise Exception("Mixture of formats in inpyt file %s - useNames" % (txtFile))
432  useNames=False
433  cellHash = int(fields[0])
434  cellGain = int(fields[1])
435  noise = fields[2:]
436  dictKey = (cellHash,cellGain)
437  cellData[dictKey] = noise
438  if icell[gain]<cellHash:
439  icell[gain]=cellHash
440  if igain<cellGain:
441  igain=cellGain
442  if ival<len(noise):
443  ival=len(noise)
444  if not useNames:
445  icell[gain]+=1
446  else:
447  print (cellData)
448  igain=igain+1
449 # except:
450 # raise Exception("Can not read input file %s" % (txtFile))
451 else:
452  log.info("No input txt file provided, making copy from input DB to output DB")
453 
454 nval=ival
455 ngain=igain
456 ncell=max(icell)
457 
458 if not tile:
459  modName="LAr %2d" % chan
460  cellName=""
461  fullName=modName
462 
463 #=== loop over all iovs
464 for io,since in enumerate(iovList):
465 
466  sinceRun = since[0]
467  sinceLum = since[1]
468 
469  until=iovUntil[io]
470  untilRun = until[0]
471  untilLum = until[1]
472 
473  log.info("")
474  log.info("Updating IOV [%d,%d] - [%d,%d)" , sinceRun, sinceLum, untilRun, untilLum)
475 
476  blobR = reader.getCells(chan,(sinceRun,sinceLum))
477  if blobR is None:
478  continue
479  mcell=blobR.getNChans()
480  mgain=blobR.getNGains()
481  mval=blobR.getObjSizeUint32()
482 
483  log.info("input file: ncell: %d ngain %d nval %d" , max(icell), igain, ival)
484  log.info("input db: ncell: %d ngain %d nval %d" , mcell, mgain, mval)
485  if mcell>ncell:
486  ncell=mcell
487  if mgain>ngain:
488  ngain=mgain
489  if mval>nval:
490  nval=mval
491 
492  log.info("output db: ncell: %d ngain %d nval %d" , ncell, ngain, nval)
493 
494  if ncell>hashMgrA.getHashMax():
495  hashMgr=hashMgrABC
496  elif ncell>hashMgrBC.getHashMax():
497  hashMgr=hashMgrA
498  elif ncell>hashMgrDef.getHashMax():
499  hashMgr=hashMgrBC
500  else:
501  hashMgr=hashMgrDef
502  log.info("Using %s CellMgr with hashMax %d" , hashMgr.getGeometry(),hashMgr.getHashMax())
503 
504  GainDefVec = cppyy.gbl.std.vector('float')()
505  for val in range(nval):
506  GainDefVec.push_back(0.0)
507  defVec = cppyy.gbl.std.vector('std::vector<float>')()
508  for gain in range(ngain):
509  defVec.push_back(GainDefVec)
510  blobW = writer.getCells(chan)
511  blobW.init(defVec,ncell,1)
512 
513  src = ['Default','DB','File','Scale']
514  FullName=None
515  cell=None
516  gain=None
517  field=None
518  strval=None
519  noise=None
520 
521  try:
522  for cell in range(ncell):
523  exist0 = (cell<mcell)
524  if tile:
525  (modName,cellName)=hashMgr.getNames(cell)
526  fullName="%s %6s" % (modName,cellName)
527  for gain in range(ngain):
528  exist1 = (exist0 and (gain<mgain))
529  if useNames:
530  if useGain:
531  gn=gain
532  else:
533  gn=-1
534  if useModuleNames:
535  dictKey = (modName+cellName,gn)
536  else:
537  dictKey = (cellName,gn)
538  else:
539  dictKey = (cell, gain)
540  noise = cellData.get(dictKey,[])
541  nF = len(noise)
542  for field in range(nval):
543  exist = (exist1 and (field<mval))
544  value = GainDefVec[field]
545  if field<nF:
546  strval=str(noise[field])
547  if strval.startswith("*"):
548  coef=float(strval[1:])
549  value = blobR.getData(cell,gain,field)*coef
550  elif strval.startswith("++") or strval.startswith("+-") :
551  coef=float(strval[1:])
552  value = blobR.getData(cell,gain,field)+coef
553  elif strval=="keep" or strval=="None":
554  value = None
555  else:
556  value = float(strval)
557  if (value is None or value<0) and exist: # negative value means that we don't want to update this field
558  value = blobR.getData(cell,gain,field)
559  elif exist:
560  exist = 2
561  elif exist:
562  value = blobR.getData(cell,gain,field)
563  if rescale:
564  if field==1 or field>4:
565  if 'spC' in cellName:
566  sc = scaleC10sp
567  elif 'spD' in cellName:
568  sc = scaleD4sp
569  elif 'C' in cellName and '10' in cellName:
570  sc = scaleC10
571  elif 'D' in cellName and '4' in cellName:
572  sc = scaleD4
573  elif 'E' in cellName:
574  sc = scaleE
575  elif 'D' in cellName:
576  sc = scaleD
577  elif 'B' in cellName:
578  sc = scaleB
579  elif 'A' in cellName:
580  sc = scaleA
581  else:
582  sc = scale
583  if sc>0.0:
584  exist = 3
585  value *= sc
586  src[exist] = "ScalePileUp %s" % str(sc)
587  elif field<4 and scaleElec>0.0:
588  exist = 3
589  value *= scaleElec
590  src[exist] = "ScaleElec %s" % str(scaleElec)
591 
592  blobW.setData( cell, gain, field, value )
593  if rescale or exist>1:
594  print ("%s hash %4d gain %d field %d value %f Source %s" % (fullName, cell, gain, field, value, src[exist]))
595  except Exception as e:
596  log.warning("Exception on IOV [%d,%d]-[%d,%d)" , sinceRun, sinceLum, untilRun, untilLum)
597  print (FullName,"Cell",cell,"gain",gain,"field",field,"value",strval,"noise vector",noise)
598  #e = sys.exc_info()[0]
599  print (e)
600 
601  writer.register((sinceRun,sinceLum), (untilRun,untilLum), outTag)
602 
603 log.info("Using %s CellMgr with hashMax %d" , hashMgr.getGeometry(),hashMgr.getHashMax())
604 #=== Cleanup
605 dbw.closeDatabase()
606 dbr.closeDatabase()
max
#define max(a, b)
Definition: cfImp.cxx:41
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:14
WriteCellNoiseToCool.usage
def usage()
Definition: WriteCellNoiseToCool.py:15
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
Trk::open
@ open
Definition: BinningType.h:40
str
Definition: BTagTrackIpAccessor.cxx:11
readCCLHist.float
float
Definition: readCCLHist.py:83
Trk::split
@ split
Definition: LayerMaterialProperties.h:38