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 =
'tileCalib.json'
69 outSchema =
'tileCalib.json'
70 folderPath =
"/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 (
"-R",
"--run2"):
153 elif o
in (
"-L",
"--lumi2"):
155 elif o
in (
"-b",
"--begin"):
158 elif o
in (
"-e",
"--end"):
161 elif o
in (
"-A",
"--adjust"):
163 elif o
in (
"-D",
"--module"):
164 moduleList += a.split(
",")
165 elif o
in (
"-x",
"--txtfile"):
167 elif o
in (
"-m",
"--comment"):
169 elif o
in (
"-M",
"--Comment"):
172 elif o
in (
"-U",
"--user"):
174 elif o
in (
"-p",
"--prefix"):
176 elif o
in (
"-k",
"--keep"):
178 elif o
in (
"-h",
"--help"):
182 raise RuntimeError(
"unhandeled option")
187 RuntimeError(
"wrong module list for swap option")
189 from TileCalibBlobPython
import TileBchTools
193 moduleSwap[m1]=TileBchTools.TileBchMgr.decodeModule(
None,m2)
197 if not len(outSchema):
201 if not len(inSchema):
203 update = update
or (inSchema==outSchema)
205 if outfolderPath
is None:
206 outfolderPath=folderPath
207 elif tag==
'UPD5' and outfolderPath!=folderPath:
208 print (
'--tag="UPD5" option is not compatible with --outfolderPath option')
215 from TileCalibBlobPython
import TileCalibCrest
216 from TileCalibBlobPython
import TileCalibTools
217 from TileCalibBlobObjs.Classes
import TileCalibUtils, TileCalibType
219 if iov
and end >= TileCalibTools.MAXRUN:
220 end = TileCalibTools.MAXRUN
221 lumi2 = TileCalibTools.MAXLBK
222 until = (TileCalibTools.MAXRUN,TileCalibTools.MAXLBK)
224 from TileCalibBlobPython.TileCalibLogger
import getLogger
228 log.setLevel(logging.INFO)
230 log.setLevel(logging.DEBUG)
234 if outfolderPath==folderPath
and outtag==tag:
235 outfolderTag = folderTag
237 outfolderTag = outtag
238 log.info(
"Initializing folder %s with tag %s", folderPath, folderTag)
246 blobReader = TileCalibCrest.TileBlobReaderCrest(inSchema,folderPath, folderTag, run, lumi,
252 log.info(
"Looking for IOVs" )
253 if moduleList!=[
'CMT']:
254 for ros
in range(rosmin,5):
257 if len(moduleList)>0
and modName
not in moduleList
and 'ALL' not in moduleList:
260 iovMod = blobReader.getIOVsWithinRange(ros,mod)
263 if 'ALL' in moduleList:
264 moduleList.remove(
'ALL')
266 for ros
in range(rosmin,5):
268 if 'CMT' in moduleList:
270 iovListCMT = blobReader.getIOVsWithinRange(-1,1000)
275 moduleList.remove(
'CMT')
279 if item1[0]!=item2[0]:
280 return item1[0]-item2[0]
282 return item1[1]-item2[1]
284 iovList=
sorted(iovList,key=functools.cmp_to_key(compare))
289 ib=bisect.bisect(iovList,since)-1
292 if iovList[ib] != since:
295 log.info(
"Moving beginning of first IOV with new constants from (%d,%d) to (%d,%d)", beg,lumi,since[0],since[1])
298 log.info(
"Creating new IOV starting from (%d,%d) with new constants", beg,lumi)
305 log.info(
"Next IOV without new constants starts from (%d,%d)", until[0],until[1])
308 ie=bisect.bisect_left(iovList,until)
312 if iovList[ie] != until:
315 log.info(
"Moving end of last IOV from (%d,%d) to (%d,%d)", end,lumi2,until[0],until[1])
317 log.info(
"Keeping end of last IOV at (%d,%d) - new IOV is shorter than IOV in input DB", end,lumi2)
321 iovList = iovList[ib:ie]
322 iovUntil = iovList[1:] + [until]
327 log.info(
"IOVs: %s",
str(iovList))
329 if len(iovListMOD)>0
and len(iovListCMT)>0:
334 for io,since
in enumerate(iovList):
335 p = bisect.bisect(iovListCMT,since)
336 if p<len(iovListCMT):
337 iovUntilCMT += [iovListCMT[p]]
338 if iovUntil[io] != iovListCMT[p]:
339 log.info(
"End of iov %s in comments record is %s",
str(since),
str(iovListCMT[p]))
342 iovUntilCMT += [since]
348 iovUntilCMT = iovUntil
350 log.info(
"%d IOVs in total, end of last IOV is %s", ie-ib,
str(until))
358 run=TileCalibTools.getPromptCalibRunNumber()
359 log.warning(
"Run number is not specified, using minimal run number in calibration loop %d", run )
361 run=TileCalibTools.getLastRunNumber()
362 log.warning(
"Run number is not specified, using current run number %d", run )
364 log.error(
"Bad run number" )
370 iovUntilCMT = [until]
371 if "begin" not in dir():
375 if run2>begin[0]
or (run2==begin[0]
and lumi2>begin[1]):
381 log.info(
"Initializing for run %d, lumiblock %d", run,lumi)
394 flt = blobReader.getDrawer(r, d, since,
False,
False)
396 blobT=flt.getObjType()
397 blobV=flt.getObjVersion()
398 mchan=flt.getNChans()
399 mgain=flt.getNGains()
400 mval=flt.getObjSizeUint32()
401 log.info(
"Blob type: %d version: %d Nchannels: %d Ngains: %d Nval: %d", blobT,blobV,mchan,mgain,mval)
418 blobWriter2 = TileCalibCrest.TileBlobWriterCrest(outSchema,outfolderPath,typeName,(
True if len(outtag)
else False))
424 for since
in iovList:
425 comm=blobReader.getComment(since)
426 log.info(
"Comment: %s", comm)
430 commentsSplit+=[blobReader.getComment(since)]
431 blobWriters += [TileCalibCrest.TileBlobWriterCrest(outSchema,outfolderPath,typeName,(
True if len(outtag)
else False))]
437 defConst = cppyy.gbl.std.vector(
'std::vector<float>')()
438 default = cppyy.gbl.std.vector(
'float')()
441 defConst = cppyy.gbl.std.vector(
'std::vector<int>')()
442 default = cppyy.gbl.std.vector(
'int')()
445 for n
in range(nval
if nval>0
else mval):
446 default.push_back(defVal)
448 for ng
in range(ngain
if ngain>0
else mgain):
449 defConst.push_back(default)
451 blobParser = TileCalibTools.TileASCIIParser2(txtFile,prefix,readGain)
455 for io,since
in enumerate(iovList):
457 if since==iovUntil[io]:
460 log.info(
"Updating IOV %s",
str(since) )
471 for ros
in range(rosmin,5):
474 if iov
and since!=begin
and (since
not in iovAll[irm]):
477 if modName
in [
'EBA39',
'EBA40',
'EBA41',
'EBA42',
'EBA55',
'EBA56',
'EBA57',
'EBA58',
478 'EBC39',
'EBC40',
'EBC41',
'EBC42',
'EBC55',
'EBC56',
'EBC57',
'EBC58' ]:
480 elif modName
in [
'EBA15',
'EBC18']:
482 elif modName
in [
'EBC29',
'EBC32',
'EBC34',
'EBC37']:
484 elif modName
in [
'EBA07',
'EBA25',
'EBA44',
'EBA53',
485 'EBC07',
'EBC25',
'EBC44',
'EBC53',
486 'EBC28',
'EBC31',
'EBC35',
'EBC38' ]:
488 elif modName
in [
'EBA08',
'EBA24',
'EBA43',
'EBA54',
489 'EBC08',
'EBC24',
'EBC43',
'EBC54' ]:
494 flt1 = blobReader.getDrawer(ros, mod, since,
False,
False)
496 oldNchan = flt1.getNChans()
497 oldNgain = flt1.getNGains()
498 oldVsize = flt1.getObjSizeUint32()
506 (rosR,modR,modNameR) = (ros,mod,modName)
507 (rosW,modW,modNameW) = (ros,mod,modName)
508 if swap
and modName
in moduleSwap:
509 (rosW,modW) = moduleSwap[modName]
511 log.warning(
"Swap: read %s write %s", modName,modNameW)
512 for chn
in range(nchan):
514 for adc
in range(ngain):
515 data = blobParser.getData(rosR,modR,chn,adc,since)
516 if not len(data)
and allzero:
518 if not len(data)
and (
not all
or (
not flt1
and not rosmin)):
520 log.warning(
"%i/%2i/%2i/%i: No value found in file", rosR,modR,chn,adc)
525 blobWriters[io].zeroBlob(rosW,modW)
527 calibDrawer = blobWriters[io].getDrawer(rosW,modW)
528 if not calibDrawer.getNObjs():
529 log.info(
"Initializing drawer %s", modNameW)
530 flt = blobReader.getDrawer(rosR, modR, since)
532 mval = flt.getObjSizeUint32()
534 for n
in range(mval):
535 default.push_back(defVal)
537 for ng
in range(ngain):
538 defConst.push_back(default)
541 kval = mval
if mval < flt.getObjSizeUint32()
else flt.getObjSizeUint32()
543 blobVersion = flt.getObjVersion()
544 calibDrawer.init(defConst,nchan,blobVersion)
546 calibDrawer2 = blobWriter2.getDrawer(rosW,modW)
547 calibDrawer2.init(defConst,nchan,blobVersion)
548 for ch
in range(nchan):
549 for ad
in range(ngain):
551 for n
in range(0,kval):
553 val=flt.getData(ch,ad,n)
554 log.debug(
"%i/%2i/%2i/%i: old data[%i] = %f", rosR,modR,ch,ad, n, val)
555 calibDrawer.setData(ch,ad,n,val)
557 calibDrawer2.setData(ch,ad,n,val)
558 for n
in range(kval,nval):
560 val=calibDrawer.getData(ch,ad,n)
561 log.debug(
"%i/%2i/%2i/%i: def data[%i] = %f", rosR,modR,ch,ad, n, val)
565 log.warning(
"%i/%2i/%2i/%i: No value found in file", rosR,modR,chn,adc)
569 mval = flt.getObjSizeUint32()
575 if chn>=oldNchan
or adc>=oldNgain:
578 for n
in range(mval):
581 if strval.startswith(
"*"):
582 coef=
float(strval[1:])
583 val = calibDrawer.getData(chn,adc,n)*coef
584 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s scale old value by %s", rosW,modW,chn,adc, n, val, coef)
585 elif strval.startswith(
"++")
or strval.startswith(
"+-") :
586 coef=
float(strval[1:])
587 val = calibDrawer.getData(chn,adc,n)+coef
588 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s shift old value by %s", rosW,modW,chn,adc, n, val, coef)
590 val = calibDrawer.getData(chn,adc,n)
591 if val==0.0
or val==-1.0
or val==1.0:
592 val = calibDrawer.getData(chn,1-adc,n)
594 val = calibDrawer.getData(chn,1-adc,n)
595 elif strval==
"lg" and adc==1:
596 val = calibDrawer.getData(chn,0,n)
597 elif strval==
"hg" and adc==0:
598 val = calibDrawer.getData(chn,1,n)
599 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 \
600 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 \
601 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:
604 if "x" in strval
or "X" in strval:
606 elif typeName==
'Flt':
615 calibDrawer.setData(chn,adc,n,val)
617 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s", rosW,modW,chn,adc, n, val)
619 val = calibDrawer.getData(chn,adc,n)
621 log.debug(
"%i/%2i/%2i/%i: DEF data[%i] = %s", rosW,modW,chn,adc, n, val)
623 log.debug(
"%i/%2i/%2i/%i: OLD data[%i] = %s", rosW,modW,chn,adc, n, val)
624 for n
in range(mval,kval+mval):
625 val = calibDrawer.getData(chn,adc,n)
626 if n>=flt.getObjSizeUint32():
627 log.debug(
"%i/%2i/%2i/%i: DEF data[%i] = %s", rosW,modW,chn,adc, n, val)
629 log.debug(
"%i/%2i/%2i/%i: OLD data[%i] = %s", rosW,modW,chn,adc, n, val)
630 if (zero
or allzero)
and newDrawer:
631 blobWriters[io].zeroBlob(rosW,modW)
632 if rosW==0
and modW==0:
634 blobVersion = flt.getObjVersion()
635 calibDrawer = blobWriters[io].getDrawer(rosW,modW)
636 calibDrawer.init(defConst,1,blobVersion)
638 nvalUpdated[io]=nvnew
639 log.info(
"%d/%d old channels*gains/values have been read from database", nold,nvold)
640 log.info(
"%d/%d new channels*gains/values have been read from input ascii file", nnew,nvnew)
641 if nold>nnew
or nvold>(nvnew-nvnewdef):
642 log.info(
"%d/%d old channels*gains/values remain unchanged", nold-nnew,nvold-nvnew+nvnewdef)
643 if nold<nnew
or nvold<(nvnew-nvnewdef):
644 log.info(
"%d/%d new channels*gains/values have been added to database", nnew-nold,nvnew-nvold-nvnewdef)
646 log.info(
"%d/%d new channels*gains/values with default values have been added to database", ndef,nvdef)
649 if (mval!=0
or Comment
is not None)
and (len(comment)>0
or len(txtFile)>0):
654 for io,since
in enumerate(iovList):
656 untilMod = iovUntil[io]
657 untilCmt = iovUntilCMT[io]
658 appendCmt = (untilCmt < (TileCalibTools.MAXRUN,TileCalibTools.MAXLBK))
or iov
666 if len(moduleList)!=1:
669 elif untilCmt>untilMod:
673 log.info(
"Updating IOV %s => %s => %s",
str(io),
str(since), comments[io] )
675 log.info(
"Updating IOV %s",
str(since) )
678 if Comment
is not None:
681 comm =
"UNDO " + comm
684 if (comment
is None)
or (comment ==
"None"):
690 if since[1]==0
and begin[1]==0:
691 comm=
"Update for run %i - undoing changes done for run %i from file %s" % (since[0],begin[0],txtFile)
693 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)
696 comm=
"Update for run %i from file %s" % (since[0],txtFile)
698 comm=
"Update for run,lumi %i,%i from file %s" % (since[0],since[1],txtFile)
702 comm =
"UNDO " + comm
703 if iov
and appendCmt:
704 comm +=
" // " + comments[io]
705 if not undoCmt
and iov
and (nvalUpdated[io]==0
or comment==
"keep"):
706 author = commentsSplit[io]
709 blobWriters[io].setComment(author,comm)
712 if untilCmt!=untilMod:
713 cmtOnly = (since
in iovListCMT
and since
not in iovListMOD)
714 if not cmtOnly
and untilMod>since:
715 blobWriters[io].
register(since,outfolderTag)
717 blobWriters[io].
register(since,outfolderTag)
719 blobWriters[io].
register(since,outfolderTag)
722 if (comment
is None)
or (comment ==
"None"):
723 blobWriter2.setComment(
"None",
"None")
725 if run2>begin[0]
and lumi2==0
and begin[1]==0:
726 comment=
"Update for run %i - undoing changes done for run %i from file %s" % (run2,begin[0],txtFile)
728 comment=
"Update for run,lumi %i,%i - undoing changes done for %i,%i from file %s" % (run2,lumi2,begin[0],begin[1],txtFile)
729 blobWriter2.setComment(user,comment)
730 blobWriter2.register((run2,lumi2), until, outfolderTag)
731 elif run2>=0
and (run2<begin[0]
or (run2==begin[0]
and lumi2<begin[1])
and lumi2!=0):
732 log.warning(
"(run2,lumi2)=(%i,%i) is smaller than (run,lumi)=(%i,%i) - will not create second IOV", run2,lumi2,begin[0],begin[1])
734 log.warning(
"Nothing to update")