9 import getopt,sys,os,bisect
10 os.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 (
"-R, --run2= specify run number for new IOV where correction is undone")
23 print (
"-l, --lumi= specify lumi block number, default is 0")
24 print (
"-L, --lumi2= specify lumi block number for new IOV where correction is undone")
25 print (
"-b, --begin= specify run number of first iov in multi-iov mode, by default uses very first iov")
26 print (
"-e, --end= specify run number of last iov in multi-iov mode, by default uses latest iov")
27 print (
"-A, --adjust in multi-iov mode adjust iov boundaries to nearest iov available in DB, default is False")
28 print (
"-D, --module= specify module to use in multi-IOV update, default is all")
29 print (
"-c, --channel if present, means that one constant per channel is expected (i.e. no gain field)")
30 print (
"-d, --default if present, means that also default values stored in AUX01-AUX20 should be updated")
31 print (
"-a, --all if present, means that all drawers are saved, otherwise only those which were updated")
32 print (
"-z, --zero if present, means that zero-sized blob is written for missing drawers")
33 print (
"-Z, --allzero if present, means that zero-sized blob is created for all drawers which are not present in input file")
34 print (
"-C, --nchannel= specify number of channels to store to DB, default is 0 - means the same as in input DB")
35 print (
"-G, --ngain= specify number of gains to store to DB, default is 0 - means the same as in input DB")
36 print (
"-n, --nval= specify number of values to store to DB, default is 0 - means all")
37 print (
"-v, --version= specify blob version, by default version from input DB is used" )
38 print (
"-x, --txtfile= specify the text file with the new constants for reading")
39 print (
"-m, --comment= specify comment which should be written to DB, in multi-iov mode it is appended to old comment")
40 print (
"-M, --Comment= specify comment which should be written to DB, in mutli-iov mode it overwrites old comment")
41 print (
"-U, --user= specify username for comment")
42 print (
"-p, --prefix= specify prefix which is expected on every line in input file, default - no prefix")
43 print (
"-k, --keep= field numbers or channel numbers to ignore, e.g. '0,2,3,EBch0,EBch1,EBch12,EBch13,EBspD4ch18,EBspD4ch19,EBspC10ch4,EBspC10ch5' ")
44 print (
"-i, --inschema= specify the input schema to use, default is 'COOLOFL_TILE/CONDBR2'")
45 print (
"-o, --outschema= specify the output schema to use, default is 'sqlite://;schema=tileSqlite.db;dbname=CONDBR2'")
46 print (
"-s, --schema= specify input/output schema to use when both input and output schemas are the same")
47 print (
"-S, --server= specify server - ORACLE or FRONTIER, default is FRONTIER")
48 print (
"-u --update set this flag if output sqlite file should be updated, otherwise it'll be recreated")
49 print (
"-w, --swap= specify pair of modules which will be swapped in multi-IOV update, e.g. swap=EBA61,EBA63")
51 letters =
"hr:l:R:L:b:e:AD:S:s:i:o:t:T:f:F:C:G:n:v:x:m:M:U:p:dcazZuw:k:"
52 keywords = [
"help",
"run=",
"lumi=",
"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="]
55 opts, extraparams = getopt.getopt(sys.argv[1:],letters,keywords)
56 except getopt.GetoptError
as err:
67 schema =
'sqlite://;schema=tileSqlite.db;dbname=CONDBR2'
68 inSchema =
'COOLOFL_TILE/CONDBR2'
69 outSchema =
'sqlite://;schema=tileSqlite.db;dbname=CONDBR2'
70 folderPath =
"/TILE/OFL02/TIME/CHANNELOFFSET/GAP/LAS"
103 if o
in (
"-f",
"--folder"):
105 elif o
in (
"-F",
"--outfolder"):
107 elif o
in (
"-t",
"--tag"):
109 elif o
in (
"-T",
"--outtag"):
111 elif o
in (
"-S",
"--server"):
113 elif o
in (
"-s",
"--schema"):
117 elif o
in (
"-i",
"--inschema"):
119 elif o
in (
"-o",
"--outschema"):
121 elif o
in (
"-n",
"--nval"):
123 elif o
in (
"-G",
"--ngain"):
125 elif o
in (
"-C",
"--nchannel"):
127 elif o
in (
"-v",
"--version"):
129 elif o
in (
"-d",
"--default"):
131 elif o
in (
"-c",
"--channel"):
133 elif o
in (
"-a",
"--all"):
135 elif o
in (
"-z",
"--zero"):
137 elif o
in (
"-Z",
"--allzero"):
139 elif o
in (
"-u",
"--update"):
141 elif o
in (
"-w",
"--swap"):
143 elif o
in (
"-r",
"--run"):
145 elif o
in (
"-l",
"--lumi"):
147 elif o
in (
"-R",
"--run2"):
149 elif o
in (
"-L",
"--lumi2"):
151 elif o
in (
"-b",
"--begin"):
154 elif o
in (
"-e",
"--end"):
157 elif o
in (
"-A",
"--adjust"):
159 elif o
in (
"-D",
"--module"):
160 moduleList += a.split(
",")
161 elif o
in (
"-x",
"--txtfile"):
163 elif o
in (
"-m",
"--comment"):
165 elif o
in (
"-M",
"--Comment"):
168 elif o
in (
"-U",
"--user"):
170 elif o
in (
"-p",
"--prefix"):
172 elif o
in (
"-k",
"--keep"):
174 elif o
in (
"-h",
"--help"):
178 raise RuntimeError(
"unhandeled option")
183 RuntimeError(
"wrong module list for swap option")
185 from TileCalibBlobPython
import TileBchTools
189 moduleSwap[m1]=TileBchTools.TileBchMgr.decodeModule(
None,m2)
193 if not len(outSchema):
197 if not len(inSchema):
199 update = update
or (inSchema==outSchema)
201 if outfolderPath
is None:
202 outfolderPath=folderPath
203 elif tag==
'UPD5' and outfolderPath!=folderPath:
204 print (
'--tag="UPD5" option is not compatible with --outfolderPath option')
211 from TileCalibBlobPython
import TileCalibTools
212 from TileCalibBlobObjs.Classes
import TileCalibUtils, TileCalibType
214 if iov
and end >= TileCalibTools.MAXRUN:
215 end = TileCalibTools.MAXRUN
216 lumi2 = TileCalibTools.MAXLBK
217 until = (TileCalibTools.MAXRUN,TileCalibTools.MAXLBK)
219 from TileCalibBlobPython.TileCalibLogger
import getLogger
223 log.setLevel(logging.INFO)
225 log.setLevel(logging.DEBUG)
228 dbr = TileCalibTools.openDbConn(inSchema,server)
229 dbw = TileCalibTools.openDbConn(outSchema,(
'UPDATE' if update
else 'RECREATE'))
233 outfolderPath=folderPath
234 folderTag = TileCalibTools.getFolderTag(dbr, folderPath, tag )
235 tag2=folderTag.split(
'-')
236 tag2[len(tag2)-1]=
"%02d"%(
int(tag2[len(tag2)-1])+1)
239 folderTag = TileCalibTools.getFolderTag(dbr, folderPath, tag )
240 if outfolderPath==folderPath
and outtag==tag:
241 outfolderTag = folderTag
243 outfolderTag = TileCalibTools.getFolderTag(dbr, outfolderPath, outtag )
244 log.info(
"Initializing folder %s with tag %s", folderPath, folderTag)
252 blobReader = TileCalibTools.TileBlobReader(dbr,folderPath, folderTag)
256 log.info(
"Looking for IOVs" )
257 if moduleList!=[
'CMT']:
258 for ros
in range(rosmin,5):
261 if len(moduleList)>0
and modName
not in moduleList
and 'ALL' not in moduleList:
264 iovMod = blobReader.getIOVsWithinRange(ros,mod)
267 if 'ALL' in moduleList:
268 moduleList.remove(
'ALL')
270 for ros
in range(rosmin,5):
272 if 'CMT' in moduleList:
274 iovListCMT = blobReader.getIOVsWithinRange(-1,1000)
279 moduleList.remove(
'CMT')
283 if item1[0]!=item2[0]:
284 return item1[0]-item2[0]
286 return item1[1]-item2[1]
288 iovList=
sorted(iovList,key=functools.cmp_to_key(compare))
293 ib=bisect.bisect(iovList,since)-1
296 if iovList[ib] != since:
299 log.info(
"Moving beginning of first IOV with new constants from (%d,%d) to (%d,%d)", beg,lumi,since[0],since[1])
302 log.info(
"Creating new IOV starting from (%d,%d) with new constants", beg,lumi)
309 log.info(
"Next IOV without new constants starts from (%d,%d)", until[0],until[1])
312 ie=bisect.bisect_left(iovList,until)
316 if iovList[ie] != until:
319 log.info(
"Moving end of last IOV from (%d,%d) to (%d,%d)", end,lumi2,until[0],until[1])
321 log.info(
"Keeping end of last IOV at (%d,%d) - new IOV is shorter than IOV in input DB", end,lumi2)
325 iovList = iovList[ib:ie]
326 iovUntil = iovList[1:] + [until]
331 log.info(
"IOVs: %s",
str(iovList))
333 if len(iovListMOD)>0
and len(iovListCMT)>0:
338 for io,since
in enumerate(iovList):
339 p = bisect.bisect(iovListCMT,since)
340 if p<len(iovListCMT):
341 iovUntilCMT += [iovListCMT[p]]
342 if iovUntil[io] != iovListCMT[p]:
343 log.info(
"End of iov %s in comments record is %s",
str(since),
str(iovListCMT[p]))
346 iovUntilCMT += [since]
352 iovUntilCMT = iovUntil
354 log.info(
"%d IOVs in total, end of last IOV is %s", ie-ib,
str(until))
362 run=TileCalibTools.getPromptCalibRunNumber()
363 log.warning(
"Run number is not specified, using minimal run number in calibration loop %d", run )
365 run=TileCalibTools.getLastRunNumber()
366 log.warning(
"Run number is not specified, using current run number %d", run )
368 log.error(
"Bad run number" )
374 iovUntilCMT = [until]
375 if "begin" not in dir():
379 if run2>begin[0]
or (run2==begin[0]
and lumi2>begin[1]):
385 log.info(
"Initializing for run %d, lumiblock %d", run,lumi)
398 flt = blobReader.getDrawer(r, d, since,
False,
False)
400 blobT=flt.getObjType()
401 blobV=flt.getObjVersion()
402 mchan=flt.getNChans()
403 mgain=flt.getNGains()
404 mval=flt.getObjSizeUint32()
405 log.info(
"Blob type: %d version: %d Nchannels: %d Ngains: %d Nval: %d", blobT,blobV,mchan,mgain,mval)
422 blobWriter2 = TileCalibTools.TileBlobWriter(dbw,outfolderPath,typeName,(
True if len(outtag)
else False))
428 for since
in iovList:
429 comm=blobReader.getComment(since)
430 log.info(
"Comment: %s", comm)
433 commentsSplit+=[blobReader.getComment(since,
True)]
434 blobWriters += [TileCalibTools.TileBlobWriter(dbw,outfolderPath,typeName,(
True if len(outtag)
else False))]
440 defConst = cppyy.gbl.std.vector(
'std::vector<float>')()
441 default = cppyy.gbl.std.vector(
'float')()
444 defConst = cppyy.gbl.std.vector(
'std::vector<int>')()
445 default = cppyy.gbl.std.vector(
'int')()
448 for n
in range(nval
if nval>0
else mval):
449 default.push_back(defVal)
451 for ng
in range(ngain
if ngain>0
else mgain):
452 defConst.push_back(default)
454 blobParser = TileCalibTools.TileASCIIParser2(txtFile,prefix,readGain)
458 for io,since
in enumerate(iovList):
460 if since==iovUntil[io]:
463 log.info(
"Updating IOV %s",
str(since) )
474 for ros
in range(rosmin,5):
477 if iov
and since!=begin
and (since
not in iovAll[irm]):
480 if modName
in [
'EBA39',
'EBA40',
'EBA41',
'EBA42',
'EBA55',
'EBA56',
'EBA57',
'EBA58',
481 'EBC39',
'EBC40',
'EBC41',
'EBC42',
'EBC55',
'EBC56',
'EBC57',
'EBC58' ]:
483 elif modName
in [
'EBA15',
'EBC18']:
485 elif modName
in [
'EBC29',
'EBC32',
'EBC34',
'EBC37']:
487 elif modName
in [
'EBA07',
'EBA25',
'EBA44',
'EBA53',
488 'EBC07',
'EBC25',
'EBC44',
'EBC53',
489 'EBC28',
'EBC31',
'EBC35',
'EBC38' ]:
491 elif modName
in [
'EBA08',
'EBA24',
'EBA43',
'EBA54',
492 'EBC08',
'EBC24',
'EBC43',
'EBC54' ]:
497 flt1 = blobReader.getDrawer(ros, mod, since,
False,
False)
499 oldNchan = flt1.getNChans()
500 oldNgain = flt1.getNGains()
501 oldVsize = flt1.getObjSizeUint32()
509 (rosR,modR,modNameR) = (ros,mod,modName)
510 (rosW,modW,modNameW) = (ros,mod,modName)
511 if swap
and modName
in moduleSwap:
512 (rosW,modW) = moduleSwap[modName]
514 log.warning(
"Swap: read %s write %s", modName,modNameW)
515 for chn
in range(nchan):
517 for adc
in range(ngain):
518 data = blobParser.getData(rosR,modR,chn,adc,since)
519 if not len(data)
and allzero:
521 if not len(data)
and (
not all
or (
not flt1
and not rosmin)):
523 log.warning(
"%i/%2i/%2i/%i: No value found in file", rosR,modR,chn,adc)
528 blobWriters[io].zeroBlob(rosW,modW)
530 calibDrawer = blobWriters[io].getDrawer(rosW,modW)
531 if not calibDrawer.getNObjs():
532 log.info(
"Initializing drawer %s", modNameW)
533 flt = blobReader.getDrawer(rosR, modR, since)
535 mval = flt.getObjSizeUint32()
537 for n
in range(mval):
538 default.push_back(defVal)
540 for ng
in range(ngain):
541 defConst.push_back(default)
544 kval = mval
if mval < flt.getObjSizeUint32()
else flt.getObjSizeUint32()
546 blobVersion = flt.getObjVersion()
547 calibDrawer.init(defConst,nchan,blobVersion)
549 calibDrawer2 = blobWriter2.getDrawer(rosW,modW)
550 calibDrawer2.init(defConst,nchan,blobVersion)
551 for ch
in range(nchan):
552 for ad
in range(ngain):
554 for n
in range(0,kval):
556 val=flt.getData(ch,ad,n)
557 log.debug(
"%i/%2i/%2i/%i: old data[%i] = %f", rosR,modR,ch,ad, n, val)
558 calibDrawer.setData(ch,ad,n,val)
560 calibDrawer2.setData(ch,ad,n,val)
561 for n
in range(kval,nval):
563 val=calibDrawer.getData(ch,ad,n)
564 log.debug(
"%i/%2i/%2i/%i: def data[%i] = %f", rosR,modR,ch,ad, n, val)
568 log.warning(
"%i/%2i/%2i/%i: No value found in file", rosR,modR,chn,adc)
572 mval = flt.getObjSizeUint32()
578 if chn>=oldNchan
or adc>=oldNgain:
581 for n
in range(mval):
584 if strval.startswith(
"*"):
585 coef=
float(strval[1:])
586 val = calibDrawer.getData(chn,adc,n)*coef
587 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s scale old value by %s", rosW,modW,chn,adc, n, val, coef)
588 elif strval.startswith(
"++")
or strval.startswith(
"+-") :
589 coef=
float(strval[1:])
590 val = calibDrawer.getData(chn,adc,n)+coef
591 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s shift old value by %s", rosW,modW,chn,adc, n, val, coef)
593 val = calibDrawer.getData(chn,adc,n)
594 if val==0.0
or val==-1.0
or val==1.0:
595 val = calibDrawer.getData(chn,1-adc,n)
597 val = calibDrawer.getData(chn,1-adc,n)
598 elif strval==
"lg" and adc==1:
599 val = calibDrawer.getData(chn,0,n)
600 elif strval==
"hg" and adc==0:
601 val = calibDrawer.getData(chn,1,n)
602 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 \
603 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 \
604 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:
607 if "x" in strval
or "X" in strval:
609 elif typeName==
'Flt':
618 calibDrawer.setData(chn,adc,n,val)
620 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s", rosW,modW,chn,adc, n, val)
622 val = calibDrawer.getData(chn,adc,n)
624 log.debug(
"%i/%2i/%2i/%i: DEF data[%i] = %s", rosW,modW,chn,adc, n, val)
626 log.debug(
"%i/%2i/%2i/%i: OLD data[%i] = %s", rosW,modW,chn,adc, n, val)
627 for n
in range(mval,kval+mval):
628 val = calibDrawer.getData(chn,adc,n)
629 if n>=flt.getObjSizeUint32():
630 log.debug(
"%i/%2i/%2i/%i: DEF data[%i] = %s", rosW,modW,chn,adc, n, val)
632 log.debug(
"%i/%2i/%2i/%i: OLD data[%i] = %s", rosW,modW,chn,adc, n, val)
633 if (zero
or allzero)
and newDrawer:
634 blobWriters[io].zeroBlob(rosW,modW)
635 if rosW==0
and modW==0:
637 blobVersion = flt.getObjVersion()
638 calibDrawer = blobWriters[io].getDrawer(rosW,modW)
639 calibDrawer.init(defConst,1,blobVersion)
641 nvalUpdated[io]=nvnew
642 log.info(
"%d/%d old channels*gains/values have been read from database", nold,nvold)
643 log.info(
"%d/%d new channels*gains/values have been read from input ascii file", nnew,nvnew)
644 if nold>nnew
or nvold>(nvnew-nvnewdef):
645 log.info(
"%d/%d old channels*gains/values remain unchanged", nold-nnew,nvold-nvnew+nvnewdef)
646 if nold<nnew
or nvold<(nvnew-nvnewdef):
647 log.info(
"%d/%d new channels*gains/values have been added to database", nnew-nold,nvnew-nvold-nvnewdef)
649 log.info(
"%d/%d new channels*gains/values with default values have been added to database", ndef,nvdef)
652 if (mval!=0
or Comment
is not None)
and (len(comment)>0
or len(txtFile)>0):
657 for io,since
in enumerate(iovList):
659 untilMod = iovUntil[io]
660 untilCmt = iovUntilCMT[io]
661 appendCmt = (untilCmt < (TileCalibTools.MAXRUN,TileCalibTools.MAXLBK))
or iov
669 if len(moduleList)!=1:
672 elif untilCmt>untilMod:
676 log.info(
"Updating IOV %s => %s => %s",
str(io),
str(since), comments[io] )
678 log.info(
"Updating IOV %s",
str(since) )
681 if Comment
is not None:
684 comm =
"UNDO " + comm
687 if (comment
is None)
or (comment ==
"None"):
693 if since[1]==0
and begin[1]==0:
694 comm=
"Update for run %i - undoing changes done for run %i from file %s" % (since[0],begin[0],txtFile)
696 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)
699 comm=
"Update for run %i from file %s" % (since[0],txtFile)
701 comm=
"Update for run,lumi %i,%i from file %s" % (since[0],since[1],txtFile)
705 comm =
"UNDO " + comm
706 if iov
and appendCmt:
707 comm +=
" // " + comments[io]
708 if not undoCmt
and iov
and (nvalUpdated[io]==0
or comment==
"keep"):
709 author = commentsSplit[io]
712 blobWriters[io].setComment(author,comm)
715 if untilCmt!=untilMod:
716 cmtOnly = (since
in iovListCMT
and since
not in iovListMOD)
717 if not cmtOnly
and untilMod>since:
718 blobWriters[io].
register(since,untilMod,outfolderTag,1)
720 blobWriters[io].
register(since,untilCmt,outfolderTag,-1)
722 blobWriters[io].
register(since,untilMod,outfolderTag)
725 if (comment
is None)
or (comment ==
"None"):
726 blobWriter2.setComment(
"None",
"None")
728 if run2>begin[0]
and lumi2==0
and begin[1]==0:
729 comment=
"Update for run %i - undoing changes done for run %i from file %s" % (run2,begin[0],txtFile)
731 comment=
"Update for run,lumi %i,%i - undoing changes done for %i,%i from file %s" % (run2,lumi2,begin[0],begin[1],txtFile)
732 blobWriter2.setComment(user,comment)
733 blobWriter2.register((run2,lumi2), until, outfolderTag)
734 elif run2>=0
and (run2<begin[0]
or (run2==begin[0]
and lumi2<begin[1])
and lumi2!=0):
735 log.warning(
"(run2,lumi2)=(%i,%i) is smaller than (run,lumi)=(%i,%i) - will not create second IOV", run2,lumi2,begin[0],begin[1])
737 log.warning(
"Nothing to update")