17import getopt,sys,os,bisect
18os.environ[
'TERM'] =
'linux'
21 print (
"Usage: ",sys.argv[0],
" [OPTION] ... ")
22 print (
"Update TileCal calibration constants in CREST")
24 print (
"-h, --help shows this help")
25 print (
"-f, --folder= specify folder to use f.i. /TILE/OFL02/CALIB/CIS/LIN or /TILE/OFL02/TIME/CHANNELOFFSET/GAP/LAS")
26 print (
"-F, --outfolder= specify the name of output folder if different from input folder")
27 print (
"-t, --tag= specify tag to use, f.i. RUN2-HLT-UPD1-00 or RUN2-UPD4-00")
28 print (
"-T, --outtag= specify output tag if different from input tag")
29 print (
"-r, --run= specify run number, default is 0")
30 print (
"-R, --run2= specify run number for new IOV where correction is undone")
31 print (
"-l, --lumi= specify lumi block number, default is 0")
32 print (
"-L, --lumi2= specify lumi block number for new IOV where correction is undone")
33 print (
"-b, --begin= specify run number of first iov in multi-iov mode, by default uses very first iov")
34 print (
"-e, --end= specify run number of last iov in multi-iov mode, by default uses latest iov")
35 print (
"-A, --adjust in multi-iov mode adjust iov boundaries to nearest iov available in DB, default is False")
36 print (
"-D, --module= specify module to use in multi-IOV update, default is all")
37 print (
"-c, --channel if present, means that one constant per channel is expected (i.e. no gain field)")
38 print (
"-d, --default if present, means that default values stored in AUX01-AUX20 will NOT be saved")
39 print (
"-a, --all if present, means that NOT all drawers are saved, but only those which were updated")
40 print (
"-z, --zero if present, means that zero-sized blob is written for missing drawers")
41 print (
"-Z, --allzero if present, means that zero-sized blob is created for all drawers which are not present in input file")
42 print (
"-C, --nchannel= specify number of channels to store to DB, default is 0 - means the same as in input DB")
43 print (
"-G, --ngain= specify number of gains to store to DB, default is 0 - means the same as in input DB")
44 print (
"-n, --nval= specify number of values to store to DB, default is 0 - means all")
45 print (
"-v, --version= specify blob version, by default version from input DB is used" )
46 print (
"-x, --txtfile= specify the text file with the new constants for reading")
47 print (
"-m, --comment= specify comment which should be written to DB, in multi-iov mode it is appended to old comment")
48 print (
"-M, --Comment= specify comment which should be written to DB, in mutli-iov mode it overwrites old comment")
49 print (
"-U, --user= specify username for comment")
50 print (
"-p, --prefix= specify prefix which is expected on every line in input file, default - no prefix")
51 print (
"-k, --keep= field numbers or channel numbers to ignore, e.g. '0,2,3,EBch0,EBch1,EBch12,EBch13,EBspD4ch18,EBspD4ch19,EBspC10ch4,EBspC10ch5' ")
52 print (
"-i, --inschema= specify name of input JSON file or CREST_SERVER_PATH")
53 print (
"-o, --outschema= specify name of output JSON file, default is tileCalib.json")
54 print (
"-s, --schema= the same as --o, --outschema")
55 print (
"-w, --swap= specify pair of modules which will be swapped in multi-IOV update, e.g. swap=EBA61,EBA63")
57letters =
"hr:l:R:L:b:e:AD:s:i:o:t:T:f:F:C:G:n:v:x:m:M:U:p:dcazZw:k:"
58keywords = [
"help",
"run=",
"lumi=",
"run2=",
"lumi2=",
"begin=",
"end=",
"adjust",
"module=",
"schema=",
"inschema=",
"outschema=",
"tag=",
"outtag=",
"folder=",
"outfolder=",
"nchannel=",
"ngain=",
"nval=",
"version=",
"txtfile=",
"comment=",
"Comment=",
"user=",
"prefix=",
"default",
"channel",
"all",
"zero",
"allzero",
"swap=",
"keep="]
61 opts, extraparams = getopt.getopt(sys.argv[1:],letters,keywords)
62except getopt.GetoptError
as err:
73outSchema =
'tileCalib.json'
74folderPath =
"/TILE/OFL02/TIME/CHANNELOFFSET/GAP/LAS"
110 if o
in (
"-f",
"--folder"):
112 elif o
in (
"-F",
"--outfolder"):
114 elif o
in (
"-t",
"--tag"):
116 elif o
in (
"-T",
"--outtag"):
118 elif o
in (
"-s",
"--schema"):
120 elif o
in (
"-i",
"--inschema"):
122 elif o
in (
"-o",
"--outschema"):
124 elif o
in (
"-n",
"--nval"):
126 elif o
in (
"-G",
"--ngain"):
128 elif o
in (
"-C",
"--nchannel"):
130 elif o
in (
"-v",
"--version"):
132 elif o
in (
"-d",
"--default"):
134 elif o
in (
"-c",
"--channel"):
136 elif o
in (
"-a",
"--all"):
138 elif o
in (
"-z",
"--zero"):
140 elif o
in (
"-Z",
"--allzero"):
142 elif o
in (
"-w",
"--swap"):
144 elif o
in (
"-r",
"--run"):
146 elif o
in (
"-l",
"--lumi"):
148 elif o
in (
"-R",
"--run2"):
150 elif o
in (
"-L",
"--lumi2"):
152 elif o
in (
"-b",
"--begin"):
155 elif o
in (
"-e",
"--end"):
158 elif o
in (
"-A",
"--adjust"):
160 elif o
in (
"-D",
"--module"):
161 moduleList += a.split(
",")
162 elif o
in (
"-x",
"--txtfile"):
164 elif o
in (
"-m",
"--comment"):
166 elif o
in (
"-M",
"--Comment"):
169 elif o
in (
"-U",
"--user"):
171 elif o
in (
"-p",
"--prefix"):
173 elif o
in (
"-k",
"--keep"):
175 elif o
in (
"-h",
"--help"):
179 raise RuntimeError(
"unhandeled option")
184 RuntimeError(
"wrong module list for swap option")
186 from TileCalibBlobPython
import TileBchCrest
190 moduleSwap[m1]=TileBchCrest.TileBchMgr.decodeModule(
None,m2)
194if outfolderPath
is None:
195 outfolderPath=folderPath
196elif tag==
'UPD5' and outfolderPath!=folderPath:
197 print (
'--tag="UPD5" option is not compatible with --outfolderPath option')
206from TileCalibBlobPython
import TileCalibCrest
207from TileCalibBlobPython
import TileCalibTools
208from TileCalibBlobObjs.Classes
import TileCalibUtils, TileCalibType
210if iov
and end >= TileCalibCrest.MAXRUN:
211 end = TileCalibCrest.MAXRUN
212 lumi2 = TileCalibCrest.MAXLBK
213until = (TileCalibCrest.MAXRUN,TileCalibCrest.MAXLBK)
215from TileCalibBlobPython.TileCalibLogger
import getLogger
216log = getLogger(
"WriteCalibToCrest")
219 log.setLevel(logging.INFO)
221 log.setLevel(logging.DEBUG)
225log.info(
"Initializing folder %s with tag %s", folderPath, folderTag)
238 inRun=TileCalibTools.getPromptCalibRunNumber()
240 inRun=TileCalibTools.getLastRunNumber()
242 log.error(
"Bad run number" )
244blobReader = TileCalibCrest.TileBlobReaderCrest(inSchema,folderPath, folderTag, inRun, inLumi,
248 folderTag = blobReader.getFolderTag(outfolderPath,
None,
'UPD4')
249 tag2=folderTag.split(
'-')
250 tag2[len(tag2)-1]=
"%02d"%(int(tag2[len(tag2)-1])+1)
251 outfolderTag=
"-".join(tag2)
253 outfolderTag = blobReader.getFolderTag(outfolderPath,
None,outtag)
258 log.info(
"Looking for IOVs" )
259 iovMod = blobReader.getIovs()
260 if moduleList!=[
'CMT']:
261 for ros
in range(rosmin,5):
264 if len(moduleList)>0
and modName
not in moduleList
and 'ALL' not in moduleList:
269 if 'ALL' in moduleList:
270 moduleList.remove(
'ALL')
272 for ros
in range(rosmin,5):
274 if 'CMT' in moduleList:
281 moduleList.remove(
'CMT')
285 if item1[0]!=item2[0]:
286 return item1[0]-item2[0]
288 return item1[1]-item2[1]
289 iovList=list(
set(iovList))
290 iovList=sorted(iovList,key=functools.cmp_to_key(compare))
295 ib=bisect.bisect(iovList,since)-1
298 if iovList[ib] != since:
301 log.info(
"Moving beginning of first IOV with new constants from (%d,%d) to (%d,%d)", beg,lumi,since[0],since[1])
304 log.info(
"Creating new IOV starting from (%d,%d) with new constants", beg,lumi)
311 log.info(
"Next IOV without new constants starts from (%d,%d)", until[0],until[1])
314 ie=bisect.bisect_left(iovList,until)
318 if iovList[ie] != until:
321 log.info(
"Moving end of last IOV from (%d,%d) to (%d,%d)", end,lumi2,until[0],until[1])
323 log.info(
"Keeping end of last IOV at (%d,%d) - new IOV is shorter than IOV in input DB", end,lumi2)
327 iovList = iovList[ib:ie]
328 iovUntil = iovList[1:] + [until]
333 log.info(
"IOVs: %s", str(iovList))
335 if len(iovListMOD)>0
and len(iovListCMT)>0:
340 for io,since
in enumerate(iovList):
341 p = bisect.bisect(iovListCMT,since)
342 if p<len(iovListCMT):
343 iovUntilCMT += [iovListCMT[p]]
344 if iovUntil[io] != iovListCMT[p]:
345 log.info(
"End of iov %s in comments record is %s", str(since),str(iovListCMT[p]))
348 iovUntilCMT += [since]
354 iovUntilCMT = iovUntil
356 log.info(
"%d IOVs in total, end of last IOV is %s", ie-ib,str(until))
364 run=TileCalibTools.getPromptCalibRunNumber()
365 log.warning(
"Run number is not specified, using minimal run number in calibration loop %d", run )
367 run=TileCalibTools.getLastRunNumber()
368 log.warning(
"Run number is not specified, using current run number %d", run )
370 log.error(
"Bad run number" )
376 iovUntilCMT = [until]
377 if "begin" not in dir():
381 if run2>begin[0]
or (run2==begin[0]
and lumi2>begin[1]):
387 log.info(
"Initializing for run %d, lumiblock %d", run,lumi)
400 flt = blobReader.getDrawer(r, d, since,
False,
False)
402 blobT=flt.getObjType()
403 blobV=flt.getObjVersion()
404 mchan=flt.getNChans()
405 mgain=flt.getNGains()
406 mval=flt.getObjSizeUint32()
407 log.info(
"Blob type: %d version: %d Nchannels: %d Ngains: %d Nval: %d", blobT,blobV,mchan,mgain,mval)
424 blobWriter2 = TileCalibCrest.TileBlobWriterCrest(outSchema,outfolderPath,typeName)
431 comm=blobReader.getComment(since)
432 log.info(
"Comment: %s", comm)
436 commentsSplit+=[blobReader.getComment(since)]
437 blobWriters += [TileCalibCrest.TileBlobWriterCrest(outSchema,outfolderPath,typeName)]
443 defConst = cppyy.gbl.std.vector(
'std::vector<float>')()
444 default = cppyy.gbl.std.vector(
'float')()
447 defConst = cppyy.gbl.std.vector(
'std::vector<int>')()
448 default = cppyy.gbl.std.vector(
'int')()
451 for n
in range(nval
if nval>0
else mval):
452 default.push_back(defVal)
454 for ng
in range(ngain
if ngain>0
else mgain):
455 defConst.push_back(default)
457 blobParser = TileCalibTools.TileASCIIParser2(txtFile,prefix,readGain)
461 for io,since
in enumerate(iovList):
463 if since==iovUntil[io]:
466 log.info(
"Updating IOV %s", str(since) )
477 for ros
in range(rosmin,5):
480 if iov
and since!=begin
and (since
not in iovAll[irm]):
483 if modName
in [
'EBA39',
'EBA40',
'EBA41',
'EBA42',
'EBA55',
'EBA56',
'EBA57',
'EBA58',
484 'EBC39',
'EBC40',
'EBC41',
'EBC42',
'EBC55',
'EBC56',
'EBC57',
'EBC58' ]:
486 elif modName
in [
'EBA15',
'EBC18']:
488 elif modName
in [
'EBC29',
'EBC32',
'EBC34',
'EBC37']:
490 elif modName
in [
'EBA07',
'EBA25',
'EBA44',
'EBA53',
491 'EBC07',
'EBC25',
'EBC44',
'EBC53',
492 'EBC28',
'EBC31',
'EBC35',
'EBC38' ]:
494 elif modName
in [
'EBA08',
'EBA24',
'EBA43',
'EBA54',
495 'EBC08',
'EBC24',
'EBC43',
'EBC54' ]:
500 flt1 = blobReader.getDrawer(ros, mod, since,
False,
False)
502 oldNchan = flt1.getNChans()
503 oldNgain = flt1.getNGains()
504 oldVsize = flt1.getObjSizeUint32()
512 (rosR,modR,modNameR) = (ros,mod,modName)
513 (rosW,modW,modNameW) = (ros,mod,modName)
514 if swap
and modName
in moduleSwap:
515 (rosW,modW) = moduleSwap[modName]
517 log.warning(
"Swap: read %s write %s", modName,modNameW)
518 for chn
in range(nchan):
520 for adc
in range(ngain):
521 data = blobParser.getData(rosR,modR,chn,adc,since)
522 if not len(data)
and allzero:
524 if not len(data)
and (
not all
or (
not flt1
and not rosmin)):
526 log.warning(
"%i/%2i/%2i/%i: No value found in file", rosR,modR,chn,adc)
531 blobWriters[io].zeroBlob(rosW,modW)
533 calibDrawer = blobWriters[io].getDrawer(rosW,modW)
534 if not calibDrawer.getNObjs():
535 log.info(
"Initializing drawer %s", modNameW)
536 flt = blobReader.getDrawer(rosR, modR, since)
538 mval = flt.getObjSizeUint32()
540 for n
in range(mval):
541 default.push_back(defVal)
543 for ng
in range(ngain):
544 defConst.push_back(default)
547 kval = mval
if mval < flt.getObjSizeUint32()
else flt.getObjSizeUint32()
549 blobVersion = flt.getObjVersion()
550 calibDrawer.init(defConst,nchan,blobVersion)
552 calibDrawer2 = blobWriter2.getDrawer(rosW,modW)
553 calibDrawer2.init(defConst,nchan,blobVersion)
554 for ch
in range(nchan):
555 for ad
in range(ngain):
557 for n
in range(0,kval):
559 val=flt.getData(ch,ad,n)
560 log.debug(
"%i/%2i/%2i/%i: old data[%i] = %f", rosR,modR,ch,ad, n, val)
561 calibDrawer.setData(ch,ad,n,val)
563 calibDrawer2.setData(ch,ad,n,val)
564 for n
in range(kval,nval):
566 val=calibDrawer.getData(ch,ad,n)
567 log.debug(
"%i/%2i/%2i/%i: def data[%i] = %f", rosR,modR,ch,ad, n, val)
571 log.warning(
"%i/%2i/%2i/%i: No value found in file", rosR,modR,chn,adc)
575 mval = flt.getObjSizeUint32()
581 if chn>=oldNchan
or adc>=oldNgain:
584 for n
in range(mval):
587 if strval.startswith(
"*"):
588 coef=float(strval[1:])
589 val = calibDrawer.getData(chn,adc,n)*coef
590 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s scale old value by %s", rosW,modW,chn,adc, n, val, coef)
591 elif strval.startswith(
"++")
or strval.startswith(
"+-") :
592 coef=float(strval[1:])
593 val = calibDrawer.getData(chn,adc,n)+coef
594 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s shift old value by %s", rosW,modW,chn,adc, n, val, coef)
596 val = calibDrawer.getData(chn,adc,n)
597 if val==0.0
or val==-1.0
or val==1.0:
598 val = calibDrawer.getData(chn,1-adc,n)
600 val = calibDrawer.getData(chn,1-adc,n)
601 elif strval==
"lg" and adc==1:
602 val = calibDrawer.getData(chn,0,n)
603 elif strval==
"hg" and adc==0:
604 val = calibDrawer.getData(chn,1,n)
605 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 \
606 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 \
607 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:
610 if "x" in strval
or "X" in strval:
612 elif typeName==
'Flt':
621 calibDrawer.setData(chn,adc,n,val)
623 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s", rosW,modW,chn,adc, n, val)
625 val = calibDrawer.getData(chn,adc,n)
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 for n
in range(mval,kval+mval):
631 val = calibDrawer.getData(chn,adc,n)
632 if n>=flt.getObjSizeUint32():
633 log.debug(
"%i/%2i/%2i/%i: DEF data[%i] = %s", rosW,modW,chn,adc, n, val)
635 log.debug(
"%i/%2i/%2i/%i: OLD data[%i] = %s", rosW,modW,chn,adc, n, val)
636 if (zero
or allzero)
and newDrawer:
637 blobWriters[io].zeroBlob(rosW,modW)
638 if rosW==0
and modW==0:
640 blobVersion = flt.getObjVersion()
641 calibDrawer = blobWriters[io].getDrawer(rosW,modW)
642 calibDrawer.init(defConst,1,blobVersion)
644 nvalUpdated[io]=nvnew
645 log.info(
"%d/%d old channels*gains/values have been read from database", nold,nvold)
646 log.info(
"%d/%d new channels*gains/values have been read from input ascii file", nnew,nvnew)
647 if nold>nnew
or nvold>(nvnew-nvnewdef):
648 log.info(
"%d/%d old channels*gains/values remain unchanged", nold-nnew,nvold-nvnew+nvnewdef)
649 if nold<nnew
or nvold<(nvnew-nvnewdef):
650 log.info(
"%d/%d new channels*gains/values have been added to database", nnew-nold,nvnew-nvold-nvnewdef)
652 log.info(
"%d/%d new channels*gains/values with default values have been added to database", ndef,nvdef)
655if (mval!=0
or Comment
is not None)
and (len(comment)>0
or len(txtFile)>0):
660 for io,since
in enumerate(iovList):
662 untilMod = iovUntil[io]
663 untilCmt = iovUntilCMT[io]
664 appendCmt = (untilCmt < (TileCalibCrest.MAXRUN,TileCalibCrest.MAXLBK))
or iov
672 if len(moduleList)!=1:
675 elif untilCmt>untilMod:
679 log.info(
"Updating IOV %s => %s => %s", str(io), str(since), comments[io] )
681 log.info(
"Updating IOV %s", str(since) )
684 if Comment
is not None:
687 comm =
"UNDO " + comm
690 if (comment
is None)
or (comment ==
"None"):
696 if since[1]==0
and begin[1]==0:
697 comm=
"Update for run %i - undoing changes done for run %i from file %s" % (since[0],begin[0],txtFile)
699 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)
702 comm=
"Update for run %i from file %s" % (since[0],txtFile)
704 comm=
"Update for run,lumi %i,%i from file %s" % (since[0],since[1],txtFile)
708 comm =
"UNDO " + comm
709 if iov
and appendCmt:
710 comm +=
" // " + comments[io]
711 if not undoCmt
and iov
and (nvalUpdated[io]==0
or comment==
"keep"):
712 author = commentsSplit[io]
715 blobWriters[io].setComment(author,comm)
718 if untilCmt!=untilMod:
719 cmtOnly = (since
in iovListCMT
and since
not in iovListMOD)
720 if not cmtOnly
and untilMod>since:
721 blobWriters[io].register(since,outfolderTag)
723 blobWriters[io].register(since,outfolderTag)
725 blobWriters[io].register(since,outfolderTag)
728 if (comment
is None)
or (comment ==
"None"):
729 blobWriter2.setComment(
"None",
"None")
731 if run2>begin[0]
and lumi2==0
and begin[1]==0:
732 comment=
"Update for run %i - undoing changes done for run %i from file %s" % (run2,begin[0],txtFile)
734 comment=
"Update for run,lumi %i,%i - undoing changes done for %i,%i from file %s" % (run2,lumi2,begin[0],begin[1],txtFile)
735 blobWriter2.setComment(user,comment)
736 blobWriter2.register((run2,lumi2), outfolderTag)
737 elif run2>=0
and (run2<begin[0]
or (run2==begin[0]
and lumi2<begin[1])
and lumi2!=0):
738 log.warning(
"(run2,lumi2)=(%i,%i) is smaller than (run,lumi)=(%i,%i) - will not create second IOV", run2,lumi2,begin[0],begin[1])
740 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 getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
static unsigned int getMaxDrawer(unsigned int ros)
Returns the maximal channel number for a given drawer.