9import getopt,sys,os,bisect
10os.environ[
'TERM'] =
'linux'
13 print (
"Usage: ",sys.argv[0],
" [OPTION] ... ")
14 print (
"Update TileCal calibration constants in COOL")
16 print (
"-h, --help shows this help")
17 print (
"-f, --folder= specify folder to use f.i. /TILE/OFL02/CALIB/CIS/LIN or /TILE/OFL02/TIME/CHANNELOFFSET/GAP/LAS")
18 print (
"-F, --outfolder= specify the name of output folder if different from input folder")
19 print (
"-t, --tag= specify tag to use, f.i. RUN2-HLT-UPD1-00 or RUN2-UPD4-00")
20 print (
"-T, --outtag= specify output tag if different from input tag")
21 print (
"-r, --run= specify run number, default is 0")
22 print (
"-N, --run1= specify run number at which new IOV should be ended")
23 print (
"-R, --run2= specify run number for new IOV where correction is undone")
24 print (
"-l, --lumi= specify lumi block number, default is 0")
25 print (
"-B, --lumi1= specify lumi block number at which new IOV should be eneded, default is 0")
26 print (
"-L, --lumi2= specify lumi block number for new IOV where correction is undone")
27 print (
"-b, --begin= specify run number of first iov in multi-iov mode, by default uses very first iov")
28 print (
"-e, --end= specify run number of last iov in multi-iov mode, by default uses latest iov")
29 print (
"-A, --adjust in multi-iov mode adjust iov boundaries to nearest iov available in DB, default is False")
30 print (
"-D, --module= specify module to use in multi-IOV update, default is all")
31 print (
"-c, --channel if present, means that one constant per channel is expected (i.e. no gain field)")
32 print (
"-d, --default if present, means that also default values stored in AUX01-AUX20 should be updated")
33 print (
"-a, --all if present, means that all drawers are saved, otherwise only those which were updated")
34 print (
"-z, --zero if present, means that zero-sized blob is written for missing drawers")
35 print (
"-Z, --allzero if present, means that zero-sized blob is created for all drawers which are not present in input file")
36 print (
"-C, --nchannel= specify number of channels to store to DB, default is 0 - means the same as in input DB")
37 print (
"-G, --ngain= specify number of gains to store to DB, default is 0 - means the same as in input DB")
38 print (
"-n, --nval= specify number of values to store to DB, default is 0 - means all")
39 print (
"-v, --version= specify blob version, by default version from input DB is used" )
40 print (
"-x, --txtfile= specify the text file with the new constants for reading")
41 print (
"-m, --comment= specify comment which should be written to DB, in multi-iov mode it is appended to old comment")
42 print (
"-M, --Comment= specify comment which should be written to DB, in mutli-iov mode it overwrites old comment")
43 print (
"-U, --user= specify username for comment")
44 print (
"-p, --prefix= specify prefix which is expected on every line in input file, default - no prefix")
45 print (
"-k, --keep= field numbers or channel numbers to ignore, e.g. '0,2,3,EBch0,EBch1,EBch12,EBch13,EBspD4ch18,EBspD4ch19,EBspC10ch4,EBspC10ch5' ")
46 print (
"-i, --inschema= specify the input schema to use, default is 'COOLOFL_TILE/CONDBR2'")
47 print (
"-o, --outschema= specify the output schema to use, default is 'sqlite://;schema=tileSqlite.db;dbname=CONDBR2'")
48 print (
"-s, --schema= specify input/output schema to use when both input and output schemas are the same")
49 print (
"-S, --server= specify server - ORACLE or FRONTIER, default is FRONTIER")
50 print (
"-u --update set this flag if output sqlite file should be updated, otherwise it'll be recreated")
51 print (
"-w, --swap= specify pair of modules which will be swapped in multi-IOV update, e.g. swap=EBA61,EBA63")
53letters =
"hr:l:N:B:R:L:b:e:AD:S:s:i:o:t:T:f:F:C:G:n:v:x:m:M:U:p:dcazZuw:k:"
54keywords = [
"help",
"run=",
"lumi=",
"run1=",
"lumi1=",
"run2=",
"lumi2=",
"begin=",
"end=",
"adjust",
"module=",
"server=",
"schema=",
"inschema=",
"outschema=",
"tag=",
"outtag=",
"folder=",
"outfolder=",
"nchannel=",
"ngain=",
"nval=",
"version=",
"txtfile=",
"comment=",
"Comment=",
"user=",
"prefix=",
"default",
"channel",
"all",
"zero",
"allzero",
"update",
"swap=",
"keep="]
57 opts, extraparams = getopt.getopt(sys.argv[1:],letters,keywords)
58except getopt.GetoptError
as err:
71schema =
'sqlite://;schema=tileSqlite.db;dbname=CONDBR2'
72inSchema =
'COOLOFL_TILE/CONDBR2'
73outSchema =
'sqlite://;schema=tileSqlite.db;dbname=CONDBR2'
74folderPath =
"/TILE/OFL02/TIME/CHANNELOFFSET/GAP/LAS"
107 if o
in (
"-f",
"--folder"):
109 elif o
in (
"-F",
"--outfolder"):
111 elif o
in (
"-t",
"--tag"):
113 elif o
in (
"-T",
"--outtag"):
115 elif o
in (
"-S",
"--server"):
117 elif o
in (
"-s",
"--schema"):
121 elif o
in (
"-i",
"--inschema"):
123 elif o
in (
"-o",
"--outschema"):
125 elif o
in (
"-n",
"--nval"):
127 elif o
in (
"-G",
"--ngain"):
129 elif o
in (
"-C",
"--nchannel"):
131 elif o
in (
"-v",
"--version"):
133 elif o
in (
"-d",
"--default"):
135 elif o
in (
"-c",
"--channel"):
137 elif o
in (
"-a",
"--all"):
139 elif o
in (
"-z",
"--zero"):
141 elif o
in (
"-Z",
"--allzero"):
143 elif o
in (
"-u",
"--update"):
145 elif o
in (
"-w",
"--swap"):
147 elif o
in (
"-r",
"--run"):
149 elif o
in (
"-l",
"--lumi"):
151 elif o
in (
"-N",
"--run1"):
153 elif o
in (
"-B",
"--lumi1"):
155 elif o
in (
"-R",
"--run2"):
157 elif o
in (
"-L",
"--lumi2"):
159 elif o
in (
"-b",
"--begin"):
162 elif o
in (
"-e",
"--end"):
165 elif o
in (
"-A",
"--adjust"):
167 elif o
in (
"-D",
"--module"):
168 moduleList += a.split(
",")
169 elif o
in (
"-x",
"--txtfile"):
171 elif o
in (
"-m",
"--comment"):
173 elif o
in (
"-M",
"--Comment"):
176 elif o
in (
"-U",
"--user"):
178 elif o
in (
"-p",
"--prefix"):
180 elif o
in (
"-k",
"--keep"):
182 elif o
in (
"-h",
"--help"):
186 raise RuntimeError(
"unhandeled option")
191 RuntimeError(
"wrong module list for swap option")
193 from TileCalibBlobPython
import TileBchTools
197 moduleSwap[m1]=TileBchTools.TileBchMgr.decodeModule(
None,m2)
201if not len(outSchema):
207update = update
or (inSchema==outSchema)
209if outfolderPath
is None:
210 outfolderPath=folderPath
211elif tag==
'UPD5' and outfolderPath!=folderPath:
212 print (
'--tag="UPD5" option is not compatible with --outfolderPath option')
219from TileCalibBlobPython
import TileCalibTools
220from TileCalibBlobObjs.Classes
import TileCalibUtils, TileCalibType
222if iov
and end >= TileCalibTools.MAXRUN:
223 end = TileCalibTools.MAXRUN
224 lumi2 = TileCalibTools.MAXLBK
225until = (TileCalibTools.MAXRUN,TileCalibTools.MAXLBK)
227from TileCalibBlobPython.TileCalibLogger
import getLogger
228log = getLogger(
"WriteCalibToCool")
231 log.setLevel(logging.INFO)
233 log.setLevel(logging.DEBUG)
236dbr = TileCalibTools.openDbConn(inSchema,server)
237dbw = TileCalibTools.openDbConn(outSchema,(
'UPDATE' if update
else 'RECREATE'))
241 outfolderPath=folderPath
242 folderTag = TileCalibTools.getFolderTag(dbr, folderPath, tag )
243 tag2=folderTag.split(
'-')
244 tag2[len(tag2)-1]=
"%02d"%(int(tag2[len(tag2)-1])+1)
245 outfolderTag=
"-".join(tag2)
247 folderTag = TileCalibTools.getFolderTag(dbr, folderPath, tag )
248 if outfolderPath==folderPath
and outtag==tag:
249 outfolderTag = folderTag
251 outfolderTag = TileCalibTools.getFolderTag(dbr, outfolderPath, outtag )
252log.info(
"Initializing folder %s with tag %s", folderPath, folderTag)
260blobReader = TileCalibTools.TileBlobReader(dbr,folderPath, folderTag)
264 log.info(
"Looking for IOVs" )
265 if moduleList!=[
'CMT']:
266 for ros
in range(rosmin,5):
269 if len(moduleList)>0
and modName
not in moduleList
and 'ALL' not in moduleList:
272 iovMod = blobReader.getIOVsWithinRange(ros,mod)
275 if 'ALL' in moduleList:
276 moduleList.remove(
'ALL')
278 for ros
in range(rosmin,5):
280 if 'CMT' in moduleList:
282 iovListCMT = blobReader.getIOVsWithinRange(-1,1000)
287 moduleList.remove(
'CMT')
291 if item1[0]!=item2[0]:
292 return item1[0]-item2[0]
294 return item1[1]-item2[1]
295 iovList=list(
set(iovList))
296 iovList=sorted(iovList,key=functools.cmp_to_key(compare))
301 ib=bisect.bisect(iovList,since)-1
304 if iovList[ib] != since:
307 log.info(
"Moving beginning of first IOV with new constants from (%d,%d) to (%d,%d)", beg,lumi,since[0],since[1])
310 log.info(
"Creating new IOV starting from (%d,%d) with new constants", beg,lumi)
317 log.info(
"Next IOV without new constants starts from (%d,%d)", until[0],until[1])
320 ie=bisect.bisect_left(iovList,until)
324 if iovList[ie] != until:
327 log.info(
"Moving end of last IOV from (%d,%d) to (%d,%d)", end,lumi2,until[0],until[1])
329 log.info(
"Keeping end of last IOV at (%d,%d) - new IOV is shorter than IOV in input DB", end,lumi2)
333 iovList = iovList[ib:ie]
334 iovUntil = iovList[1:] + [until]
339 log.info(
"IOVs: %s",
str(iovList))
341 if len(iovListMOD)>0
and len(iovListCMT)>0:
346 for io,since
in enumerate(iovList):
347 p = bisect.bisect(iovListCMT,since)
348 if p<len(iovListCMT):
349 iovUntilCMT += [iovListCMT[p]]
350 if iovUntil[io] != iovListCMT[p]:
351 log.info(
"End of iov %s in comments record is %s",
str(since),
str(iovListCMT[p]))
354 iovUntilCMT += [since]
360 iovUntilCMT = iovUntil
362 log.info(
"%d IOVs in total, end of last IOV is %s", ie-ib,
str(until))
370 run=TileCalibTools.getPromptCalibRunNumber()
371 log.warning(
"Run number is not specified, using minimal run number in calibration loop %d", run )
373 run=TileCalibTools.getNextRunNumber()
374 log.warning(
"Run number is not specified, using next run number %d", run )
376 log.error(
"Bad run number" )
378 if (run1>run
or (run1==run
and lumi1>lumi))
and run2<0:
384 iovUntilCMT = [until]
385 if "begin" not in dir():
389 if run2>begin[0]
or (run2==begin[0]
and lumi2>begin[1]):
395 log.info(
"Initializing for run %d, lumiblock %d", run,lumi)
408 flt = blobReader.getDrawer(r, d, since,
False,
False)
410 blobT=flt.getObjType()
411 blobV=flt.getObjVersion()
412 mchan=flt.getNChans()
413 mgain=flt.getNGains()
414 mval=flt.getObjSizeUint32()
415 log.info(
"Blob type: %d version: %d Nchannels: %d Ngains: %d Nval: %d", blobT,blobV,mchan,mgain,mval)
432 blobWriter2 = TileCalibTools.TileBlobWriter(dbw,outfolderPath,typeName,(
True if len(outtag)
else False))
439 comm=blobReader.getComment(since)
440 log.info(
"Comment: %s", comm)
443 commentsSplit+=[blobReader.getComment(since,
True)]
444 blobWriters += [TileCalibTools.TileBlobWriter(dbw,outfolderPath,typeName,(
True if len(outtag)
else False))]
450 defConst = cppyy.gbl.std.vector(
'std::vector<float>')()
451 default = cppyy.gbl.std.vector(
'float')()
454 defConst = cppyy.gbl.std.vector(
'std::vector<int>')()
455 default = cppyy.gbl.std.vector(
'int')()
458 for n
in range(nval
if nval>0
else mval):
459 default.push_back(defVal)
461 for ng
in range(ngain
if ngain>0
else mgain):
462 defConst.push_back(default)
464 blobParser = TileCalibTools.TileASCIIParser2(txtFile,prefix,readGain)
468 for io,since
in enumerate(iovList):
470 if since==iovUntil[io]:
473 log.info(
"Updating IOV %s",
str(since) )
484 for ros
in range(rosmin,5):
487 if iov
and since!=begin
and (since
not in iovAll[irm]):
490 if modName
in [
'EBA39',
'EBA40',
'EBA41',
'EBA42',
'EBA55',
'EBA56',
'EBA57',
'EBA58',
491 'EBC39',
'EBC40',
'EBC41',
'EBC42',
'EBC55',
'EBC56',
'EBC57',
'EBC58' ]:
493 elif modName
in [
'EBA15',
'EBC18']:
495 elif modName
in [
'EBC29',
'EBC32',
'EBC34',
'EBC37']:
497 elif modName
in [
'EBA07',
'EBA25',
'EBA44',
'EBA53',
498 'EBC07',
'EBC25',
'EBC44',
'EBC53',
499 'EBC28',
'EBC31',
'EBC35',
'EBC38' ]:
501 elif modName
in [
'EBA08',
'EBA24',
'EBA43',
'EBA54',
502 'EBC08',
'EBC24',
'EBC43',
'EBC54' ]:
507 flt1 = blobReader.getDrawer(ros, mod, since,
False,
False)
509 oldNchan = flt1.getNChans()
510 oldNgain = flt1.getNGains()
511 oldVsize = flt1.getObjSizeUint32()
519 (rosR,modR,modNameR) = (ros,mod,modName)
520 (rosW,modW,modNameW) = (ros,mod,modName)
521 if swap
and modName
in moduleSwap:
522 (rosW,modW) = moduleSwap[modName]
524 log.warning(
"Swap: read %s write %s", modName,modNameW)
525 for chn
in range(nchan):
527 for adc
in range(ngain):
528 data = blobParser.getData(rosR,modR,chn,adc,since)
529 if not len(data)
and allzero:
531 if not len(data)
and (
not all
or (
not flt1
and not rosmin)):
533 log.warning(
"%i/%2i/%2i/%i: No value found in file", rosR,modR,chn,adc)
538 blobWriters[io].zeroBlob(rosW,modW)
540 calibDrawer = blobWriters[io].getDrawer(rosW,modW)
541 if not calibDrawer.getNObjs():
542 log.info(
"Initializing drawer %s", modNameW)
543 flt = blobReader.getDrawer(rosR, modR, since)
545 mval = flt.getObjSizeUint32()
547 for n
in range(mval):
548 default.push_back(defVal)
550 for ng
in range(ngain):
551 defConst.push_back(default)
554 kval = mval
if mval < flt.getObjSizeUint32()
else flt.getObjSizeUint32()
556 blobVersion = flt.getObjVersion()
557 calibDrawer.init(defConst,nchan,blobVersion)
559 calibDrawer2 = blobWriter2.getDrawer(rosW,modW)
560 calibDrawer2.init(defConst,nchan,blobVersion)
561 for ch
in range(nchan):
562 for ad
in range(ngain):
564 for n
in range(0,kval):
566 val=flt.getData(ch,ad,n)
567 log.debug(
"%i/%2i/%2i/%i: old data[%i] = %f", rosR,modR,ch,ad, n, val)
568 calibDrawer.setData(ch,ad,n,val)
570 calibDrawer2.setData(ch,ad,n,val)
571 for n
in range(kval,nval):
573 val=calibDrawer.getData(ch,ad,n)
574 log.debug(
"%i/%2i/%2i/%i: def data[%i] = %f", rosR,modR,ch,ad, n, val)
578 log.warning(
"%i/%2i/%2i/%i: No value found in file", rosR,modR,chn,adc)
582 mval = flt.getObjSizeUint32()
588 if chn>=oldNchan
or adc>=oldNgain:
591 for n
in range(mval):
594 if strval.startswith(
"*"):
595 coef=float(strval[1:])
596 val = calibDrawer.getData(chn,adc,n)*coef
597 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s scale old value by %s", rosW,modW,chn,adc, n, val, coef)
598 elif strval.startswith(
"++")
or strval.startswith(
"+-") :
599 coef=float(strval[1:])
600 val = calibDrawer.getData(chn,adc,n)+coef
601 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s shift old value by %s", rosW,modW,chn,adc, n, val, coef)
603 val = calibDrawer.getData(chn,adc,n)
604 if val==0.0
or val==-1.0
or val==1.0:
605 val = calibDrawer.getData(chn,1-adc,n)
607 val = calibDrawer.getData(chn,1-adc,n)
608 elif strval==
"lg" and adc==1:
609 val = calibDrawer.getData(chn,0,n)
610 elif strval==
"hg" and adc==0:
611 val = calibDrawer.getData(chn,1,n)
612 elif strval==
"keep" or strval==
"None" or str(n)
in keep
or modName
in keep
or modSpec
in keep
or modName[:3]
in keep
or modName[:2]
in keep \
613 or (
"%sch%i"% (modName,chn))
in keep
or (
"%sch%i"% (modSpec,chn))
in keep
or (
"%sch%i"% (modName[:3],chn))
in keep
or (
"%sch%i"% (modName[:2],chn))
in keep \
614 or (
"%sch%ig%i"% (modName,chn,adc))
in keep
or (
"%sch%ig%i"% (modSpec,chn,adc))
in keep
or (
"%sch%ig%i"% (modName[:3],chn,adc))
in keep
or (
"%sch%ig%i"% (modName[:2],chn,adc))
in keep:
617 if "x" in strval
or "X" in strval:
619 elif typeName==
'Flt':
628 calibDrawer.setData(chn,adc,n,val)
630 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s", rosW,modW,chn,adc, n, val)
632 val = calibDrawer.getData(chn,adc,n)
634 log.debug(
"%i/%2i/%2i/%i: DEF data[%i] = %s", rosW,modW,chn,adc, n, val)
636 log.debug(
"%i/%2i/%2i/%i: OLD data[%i] = %s", rosW,modW,chn,adc, n, val)
637 for n
in range(mval,kval+mval):
638 val = calibDrawer.getData(chn,adc,n)
639 if n>=flt.getObjSizeUint32():
640 log.debug(
"%i/%2i/%2i/%i: DEF data[%i] = %s", rosW,modW,chn,adc, n, val)
642 log.debug(
"%i/%2i/%2i/%i: OLD data[%i] = %s", rosW,modW,chn,adc, n, val)
643 if (zero
or allzero)
and newDrawer:
644 blobWriters[io].zeroBlob(rosW,modW)
645 if rosW==0
and modW==0:
647 blobVersion = flt.getObjVersion()
648 calibDrawer = blobWriters[io].getDrawer(rosW,modW)
649 calibDrawer.init(defConst,1,blobVersion)
651 nvalUpdated[io]=nvnew
652 log.info(
"%d/%d old channels*gains/values have been read from database", nold,nvold)
653 log.info(
"%d/%d new channels*gains/values have been read from input ascii file", nnew,nvnew)
654 if nold>nnew
or nvold>(nvnew-nvnewdef):
655 log.info(
"%d/%d old channels*gains/values remain unchanged", nold-nnew,nvold-nvnew+nvnewdef)
656 if nold<nnew
or nvold<(nvnew-nvnewdef):
657 log.info(
"%d/%d new channels*gains/values have been added to database", nnew-nold,nvnew-nvold-nvnewdef)
659 log.info(
"%d/%d new channels*gains/values with default values have been added to database", ndef,nvdef)
662if (mval!=0
or Comment
is not None)
and (len(comment)>0
or len(txtFile)>0):
667 for io,since
in enumerate(iovList):
669 untilMod = iovUntil[io]
670 untilCmt = iovUntilCMT[io]
671 appendCmt = (untilCmt < (TileCalibTools.MAXRUN,TileCalibTools.MAXLBK))
or iov
679 if len(moduleList)!=1:
682 elif untilCmt>untilMod:
686 log.info(
"Updating IOV %s => %s => %s",
str(io),
str(since), comments[io] )
688 log.info(
"Updating IOV %s",
str(since) )
691 if Comment
is not None:
694 comm =
"UNDO " + comm
697 if (comment
is None)
or (comment ==
"None"):
700 elif comment ==
"keep":
702 author = commentsSplit[io]
706 if since[1]==0
and begin[1]==0:
707 comm=
"Update for run %i - undoing changes done for run %i from file %s" % (since[0],begin[0],txtFile)
709 comm=
"Update for run,lumi %i,%i - undoing changes done for %i,%i from file %s" % (since[0],since[1],begin[0],begin[1],txtFile)
712 comm=
"Update for run %i from file %s" % (since[0],txtFile)
714 comm=
"Update for run,lumi %i,%i from file %s" % (since[0],since[1],txtFile)
718 comm =
"UNDO " + comm
719 if (iov
and appendCmt)
or (
not iov
and adjust):
720 comm +=
" // " + comments[io]
721 if not undoCmt
and iov
and nvalUpdated[io]==0:
722 author = commentsSplit[io]
725 blobWriters[io].setComment(author,comm)
728 if untilCmt!=untilMod:
729 cmtOnly = (since
in iovListCMT
and since
not in iovListMOD)
730 if not cmtOnly
and untilMod>since:
731 blobWriters[io].register(since,untilMod,outfolderTag,1)
733 blobWriters[io].register(since,untilCmt,outfolderTag,-1)
735 blobWriters[io].register(since,untilMod,outfolderTag)
738 if (comment
is None)
or (comment ==
"None"):
739 blobWriter2.setComment(
"None",
"None")
741 if run2>begin[0]
and lumi2==0
and begin[1]==0:
742 comment=
"Update for run %i - undoing changes done for run %i from file %s" % (run2,begin[0],txtFile)
744 comment=
"Update for run,lumi %i,%i - undoing changes done for %i,%i from file %s" % (run2,lumi2,begin[0],begin[1],txtFile)
745 blobWriter2.setComment(user,comment)
746 blobWriter2.register((run2,lumi2), until, outfolderTag)
747 elif run2>=0
and (run2<begin[0]
or (run2==begin[0]
and lumi2<begin[1])
and lumi2!=0):
748 log.warning(
"(run2,lumi2)=(%i,%i) is smaller than (run,lumi)=(%i,%i) - will not create second IOV", run2,lumi2,begin[0],begin[1])
750 log.warning(
"Nothing to update")
static std::string getClassName(TileCalibType::TYPE type)
Returns the class name.
static unsigned int max_gain()
Python compatibility function.
static std::string getDrawerString(unsigned int ros, unsigned int drawer)
Return the drawer name, e.g.
static unsigned int max_chan()
Python compatibility function.
static unsigned int getMaxDrawer(unsigned int ros)
Returns the maximal channel number for a given drawer.