10import getopt,sys,os,bisect
11os.environ[
'TERM'] =
'linux'
14 print (
"Usage: ",sys.argv[0],
" [OPTION] ... ")
15 print (
"Update TileCal calibration constants in CREST")
17 print (
"-h, --help shows this help")
18 print (
"-f, --folder= specify folder to use f.i. /TILE/OFL02/CALIB/CIS/LIN or /TILE/OFL02/TIME/CHANNELOFFSET/GAP/LAS")
19 print (
"-F, --outfolder= specify the name of output folder if different from input folder")
20 print (
"-t, --tag= specify tag to use, f.i. RUN2-HLT-UPD1-00 or RUN2-UPD4-00")
21 print (
"-T, --outtag= specify output tag if different from input tag")
22 print (
"-r, --run= specify run number, default is 0")
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 (
"-L, --lumi2= specify lumi block number for new IOV where correction is undone")
26 print (
"-b, --begin= specify run number of first iov in multi-iov mode, by default uses very first iov")
27 print (
"-e, --end= specify run number of last iov in multi-iov mode, by default uses latest iov")
28 print (
"-A, --adjust in multi-iov mode adjust iov boundaries to nearest iov available in DB, default is False")
29 print (
"-D, --module= specify module to use in multi-IOV update, default is all")
30 print (
"-c, --channel if present, means that one constant per channel is expected (i.e. no gain field)")
31 print (
"-d, --default if present, means that default values stored in AUX01-AUX20 will NOT be saved")
32 print (
"-a, --all if present, means that NOT all drawers are saved, but only those which were updated")
33 print (
"-z, --zero if present, means that zero-sized blob is written for missing drawers")
34 print (
"-Z, --allzero if present, means that zero-sized blob is created for all drawers which are not present in input file")
35 print (
"-C, --nchannel= specify number of channels to store to DB, default is 0 - means the same as in input DB")
36 print (
"-G, --ngain= specify number of gains to store to DB, default is 0 - means the same as in input DB")
37 print (
"-n, --nval= specify number of values to store to DB, default is 0 - means all")
38 print (
"-v, --version= specify blob version, by default version from input DB is used" )
39 print (
"-x, --txtfile= specify the text file with the new constants for reading")
40 print (
"-m, --comment= specify comment which should be written to DB, in multi-iov mode it is appended to old comment")
41 print (
"-M, --Comment= specify comment which should be written to DB, in mutli-iov mode it overwrites old comment")
42 print (
"-U, --user= specify username for comment")
43 print (
"-p, --prefix= specify prefix which is expected on every line in input file, default - no prefix")
44 print (
"-k, --keep= field numbers or channel numbers to ignore, e.g. '0,2,3,EBch0,EBch1,EBch12,EBch13,EBspD4ch18,EBspD4ch19,EBspC10ch4,EBspC10ch5' ")
45 print (
"-i, --inschema= specify name of input JSON file or CREST_SERVER_PATH")
46 print (
"-o, --outschema= specify name of output JSON file, default is tileCalib.json")
47 print (
"-s, --schema= specify input/output schema to use when both input and output schemas are the same")
50 print (
"-w, --swap= specify pair of modules which will be swapped in multi-IOV update, e.g. swap=EBA61,EBA63")
52letters =
"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:"
53keywords = [
"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="]
56 opts, extraparams = getopt.getopt(sys.argv[1:],letters,keywords)
57except getopt.GetoptError
as err:
68schema =
'tileCalib.json'
70outSchema =
'tileCalib.json'
71folderPath =
"/TILE/OFL02/TIME/CHANNELOFFSET/GAP/LAS"
108 if o
in (
"-f",
"--folder"):
110 elif o
in (
"-F",
"--outfolder"):
112 elif o
in (
"-t",
"--tag"):
114 elif o
in (
"-T",
"--outtag"):
116 elif o
in (
"-S",
"--server"):
118 elif o
in (
"-s",
"--schema"):
122 elif o
in (
"-i",
"--inschema"):
124 elif o
in (
"-o",
"--outschema"):
126 elif o
in (
"-n",
"--nval"):
128 elif o
in (
"-G",
"--ngain"):
130 elif o
in (
"-C",
"--nchannel"):
132 elif o
in (
"-v",
"--version"):
134 elif o
in (
"-d",
"--default"):
136 elif o
in (
"-c",
"--channel"):
138 elif o
in (
"-a",
"--all"):
140 elif o
in (
"-z",
"--zero"):
142 elif o
in (
"-Z",
"--allzero"):
144 elif o
in (
"-u",
"--update"):
146 elif o
in (
"-w",
"--swap"):
148 elif o
in (
"-r",
"--run"):
150 elif o
in (
"-l",
"--lumi"):
152 elif o
in (
"-R",
"--run2"):
154 elif o
in (
"-L",
"--lumi2"):
156 elif o
in (
"-b",
"--begin"):
159 elif o
in (
"-e",
"--end"):
162 elif o
in (
"-A",
"--adjust"):
164 elif o
in (
"-D",
"--module"):
165 moduleList += a.split(
",")
166 elif o
in (
"-x",
"--txtfile"):
168 elif o
in (
"-m",
"--comment"):
170 elif o
in (
"-M",
"--Comment"):
173 elif o
in (
"-U",
"--user"):
175 elif o
in (
"-p",
"--prefix"):
177 elif o
in (
"-k",
"--keep"):
179 elif o
in (
"-h",
"--help"):
183 raise RuntimeError(
"unhandeled option")
188 RuntimeError(
"wrong module list for swap option")
190 from TileCalibBlobPython
import TileBchCrest
194 moduleSwap[m1]=TileBchCrest.TileBchMgr.decodeModule(
None,m2)
198if not len(outSchema):
204update = update
or (inSchema==outSchema)
206if outfolderPath
is None:
207 outfolderPath=folderPath
208elif tag==
'UPD5' and outfolderPath!=folderPath:
209 print (
'--tag="UPD5" option is not compatible with --outfolderPath option')
218from TileCalibBlobPython
import TileCalibCrest
219from TileCalibBlobPython
import TileCalibTools
220from TileCalibBlobObjs.Classes
import TileCalibUtils, TileCalibType
222if iov
and end >= TileCalibCrest.MAXRUN:
223 end = TileCalibCrest.MAXRUN
224 lumi2 = TileCalibCrest.MAXLBK
225until = (TileCalibCrest.MAXRUN,TileCalibCrest.MAXLBK)
227from TileCalibBlobPython.TileCalibLogger
import getLogger
228log = getLogger(
"WriteCalibToCrest")
231 log.setLevel(logging.INFO)
233 log.setLevel(logging.DEBUG)
237log.info(
"Initializing folder %s with tag %s", folderPath, folderTag)
250 inRun=TileCalibTools.getPromptCalibRunNumber()
252 inRun=TileCalibTools.getLastRunNumber()
254 log.error(
"Bad run number" )
256blobReader = TileCalibCrest.TileBlobReaderCrest(inSchema,folderPath, folderTag, inRun, inLumi,
260 folderTag = blobReader.getFolderTag(outfolderPath,
None,
'UPD4')
261 tag2=folderTag.split(
'-')
262 tag2[len(tag2)-1]=
"%02d"%(int(tag2[len(tag2)-1])+1)
263 outfolderTag=
"-".join(tag2)
265 outfolderTag = blobReader.getFolderTag(outfolderPath,
None,outtag)
270 log.info(
"Looking for IOVs" )
271 iovMod = blobReader.getIovs()
272 if moduleList!=[
'CMT']:
273 for ros
in range(rosmin,5):
276 if len(moduleList)>0
and modName
not in moduleList
and 'ALL' not in moduleList:
281 if 'ALL' in moduleList:
282 moduleList.remove(
'ALL')
284 for ros
in range(rosmin,5):
286 if 'CMT' in moduleList:
293 moduleList.remove(
'CMT')
297 if item1[0]!=item2[0]:
298 return item1[0]-item2[0]
300 return item1[1]-item2[1]
301 iovList=list(
set(iovList))
302 iovList=sorted(iovList,key=functools.cmp_to_key(compare))
307 ib=bisect.bisect(iovList,since)-1
310 if iovList[ib] != since:
313 log.info(
"Moving beginning of first IOV with new constants from (%d,%d) to (%d,%d)", beg,lumi,since[0],since[1])
316 log.info(
"Creating new IOV starting from (%d,%d) with new constants", beg,lumi)
323 log.info(
"Next IOV without new constants starts from (%d,%d)", until[0],until[1])
326 ie=bisect.bisect_left(iovList,until)
330 if iovList[ie] != until:
333 log.info(
"Moving end of last IOV from (%d,%d) to (%d,%d)", end,lumi2,until[0],until[1])
335 log.info(
"Keeping end of last IOV at (%d,%d) - new IOV is shorter than IOV in input DB", end,lumi2)
339 iovList = iovList[ib:ie]
340 iovUntil = iovList[1:] + [until]
345 log.info(
"IOVs: %s", str(iovList))
347 if len(iovListMOD)>0
and len(iovListCMT)>0:
352 for io,since
in enumerate(iovList):
353 p = bisect.bisect(iovListCMT,since)
354 if p<len(iovListCMT):
355 iovUntilCMT += [iovListCMT[p]]
356 if iovUntil[io] != iovListCMT[p]:
357 log.info(
"End of iov %s in comments record is %s", str(since),str(iovListCMT[p]))
360 iovUntilCMT += [since]
366 iovUntilCMT = iovUntil
368 log.info(
"%d IOVs in total, end of last IOV is %s", ie-ib,str(until))
376 run=TileCalibTools.getPromptCalibRunNumber()
377 log.warning(
"Run number is not specified, using minimal run number in calibration loop %d", run )
379 run=TileCalibTools.getLastRunNumber()
380 log.warning(
"Run number is not specified, using current run number %d", run )
382 log.error(
"Bad run number" )
388 iovUntilCMT = [until]
389 if "begin" not in dir():
393 if run2>begin[0]
or (run2==begin[0]
and lumi2>begin[1]):
399 log.info(
"Initializing for run %d, lumiblock %d", run,lumi)
412 flt = blobReader.getDrawer(r, d, since,
False,
False)
414 blobT=flt.getObjType()
415 blobV=flt.getObjVersion()
416 mchan=flt.getNChans()
417 mgain=flt.getNGains()
418 mval=flt.getObjSizeUint32()
419 log.info(
"Blob type: %d version: %d Nchannels: %d Ngains: %d Nval: %d", blobT,blobV,mchan,mgain,mval)
436 blobWriter2 = TileCalibCrest.TileBlobWriterCrest(outSchema,outfolderPath,typeName,(
True if len(outtag)
else False))
443 comm=blobReader.getComment(since)
444 log.info(
"Comment: %s", comm)
448 commentsSplit+=[blobReader.getComment(since)]
449 blobWriters += [TileCalibCrest.TileBlobWriterCrest(outSchema,outfolderPath,typeName,(
True if len(outtag)
else False))]
455 defConst = cppyy.gbl.std.vector(
'std::vector<float>')()
456 default = cppyy.gbl.std.vector(
'float')()
459 defConst = cppyy.gbl.std.vector(
'std::vector<int>')()
460 default = cppyy.gbl.std.vector(
'int')()
463 for n
in range(nval
if nval>0
else mval):
464 default.push_back(defVal)
466 for ng
in range(ngain
if ngain>0
else mgain):
467 defConst.push_back(default)
469 blobParser = TileCalibTools.TileASCIIParser2(txtFile,prefix,readGain)
473 for io,since
in enumerate(iovList):
475 if since==iovUntil[io]:
478 log.info(
"Updating IOV %s", str(since) )
489 for ros
in range(rosmin,5):
492 if iov
and since!=begin
and (since
not in iovAll[irm]):
495 if modName
in [
'EBA39',
'EBA40',
'EBA41',
'EBA42',
'EBA55',
'EBA56',
'EBA57',
'EBA58',
496 'EBC39',
'EBC40',
'EBC41',
'EBC42',
'EBC55',
'EBC56',
'EBC57',
'EBC58' ]:
498 elif modName
in [
'EBA15',
'EBC18']:
500 elif modName
in [
'EBC29',
'EBC32',
'EBC34',
'EBC37']:
502 elif modName
in [
'EBA07',
'EBA25',
'EBA44',
'EBA53',
503 'EBC07',
'EBC25',
'EBC44',
'EBC53',
504 'EBC28',
'EBC31',
'EBC35',
'EBC38' ]:
506 elif modName
in [
'EBA08',
'EBA24',
'EBA43',
'EBA54',
507 'EBC08',
'EBC24',
'EBC43',
'EBC54' ]:
512 flt1 = blobReader.getDrawer(ros, mod, since,
False,
False)
514 oldNchan = flt1.getNChans()
515 oldNgain = flt1.getNGains()
516 oldVsize = flt1.getObjSizeUint32()
524 (rosR,modR,modNameR) = (ros,mod,modName)
525 (rosW,modW,modNameW) = (ros,mod,modName)
526 if swap
and modName
in moduleSwap:
527 (rosW,modW) = moduleSwap[modName]
529 log.warning(
"Swap: read %s write %s", modName,modNameW)
530 for chn
in range(nchan):
532 for adc
in range(ngain):
533 data = blobParser.getData(rosR,modR,chn,adc,since)
534 if not len(data)
and allzero:
536 if not len(data)
and (
not all
or (
not flt1
and not rosmin)):
538 log.warning(
"%i/%2i/%2i/%i: No value found in file", rosR,modR,chn,adc)
543 blobWriters[io].zeroBlob(rosW,modW)
545 calibDrawer = blobWriters[io].getDrawer(rosW,modW)
546 if not calibDrawer.getNObjs():
547 log.info(
"Initializing drawer %s", modNameW)
548 flt = blobReader.getDrawer(rosR, modR, since)
550 mval = flt.getObjSizeUint32()
552 for n
in range(mval):
553 default.push_back(defVal)
555 for ng
in range(ngain):
556 defConst.push_back(default)
559 kval = mval
if mval < flt.getObjSizeUint32()
else flt.getObjSizeUint32()
561 blobVersion = flt.getObjVersion()
562 calibDrawer.init(defConst,nchan,blobVersion)
564 calibDrawer2 = blobWriter2.getDrawer(rosW,modW)
565 calibDrawer2.init(defConst,nchan,blobVersion)
566 for ch
in range(nchan):
567 for ad
in range(ngain):
569 for n
in range(0,kval):
571 val=flt.getData(ch,ad,n)
572 log.debug(
"%i/%2i/%2i/%i: old data[%i] = %f", rosR,modR,ch,ad, n, val)
573 calibDrawer.setData(ch,ad,n,val)
575 calibDrawer2.setData(ch,ad,n,val)
576 for n
in range(kval,nval):
578 val=calibDrawer.getData(ch,ad,n)
579 log.debug(
"%i/%2i/%2i/%i: def data[%i] = %f", rosR,modR,ch,ad, n, val)
583 log.warning(
"%i/%2i/%2i/%i: No value found in file", rosR,modR,chn,adc)
587 mval = flt.getObjSizeUint32()
593 if chn>=oldNchan
or adc>=oldNgain:
596 for n
in range(mval):
599 if strval.startswith(
"*"):
600 coef=float(strval[1:])
601 val = calibDrawer.getData(chn,adc,n)*coef
602 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s scale old value by %s", rosW,modW,chn,adc, n, val, coef)
603 elif strval.startswith(
"++")
or strval.startswith(
"+-") :
604 coef=float(strval[1:])
605 val = calibDrawer.getData(chn,adc,n)+coef
606 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s shift old value by %s", rosW,modW,chn,adc, n, val, coef)
608 val = calibDrawer.getData(chn,adc,n)
609 if val==0.0
or val==-1.0
or val==1.0:
610 val = calibDrawer.getData(chn,1-adc,n)
612 val = calibDrawer.getData(chn,1-adc,n)
613 elif strval==
"lg" and adc==1:
614 val = calibDrawer.getData(chn,0,n)
615 elif strval==
"hg" and adc==0:
616 val = calibDrawer.getData(chn,1,n)
617 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 \
618 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 \
619 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:
622 if "x" in strval
or "X" in strval:
624 elif typeName==
'Flt':
633 calibDrawer.setData(chn,adc,n,val)
635 log.debug(
"%i/%2i/%2i/%i: new data[%i] = %s", rosW,modW,chn,adc, n, val)
637 val = calibDrawer.getData(chn,adc,n)
639 log.debug(
"%i/%2i/%2i/%i: DEF data[%i] = %s", rosW,modW,chn,adc, n, val)
641 log.debug(
"%i/%2i/%2i/%i: OLD data[%i] = %s", rosW,modW,chn,adc, n, val)
642 for n
in range(mval,kval+mval):
643 val = calibDrawer.getData(chn,adc,n)
644 if n>=flt.getObjSizeUint32():
645 log.debug(
"%i/%2i/%2i/%i: DEF data[%i] = %s", rosW,modW,chn,adc, n, val)
647 log.debug(
"%i/%2i/%2i/%i: OLD data[%i] = %s", rosW,modW,chn,adc, n, val)
648 if (zero
or allzero)
and newDrawer:
649 blobWriters[io].zeroBlob(rosW,modW)
650 if rosW==0
and modW==0:
652 blobVersion = flt.getObjVersion()
653 calibDrawer = blobWriters[io].getDrawer(rosW,modW)
654 calibDrawer.init(defConst,1,blobVersion)
656 nvalUpdated[io]=nvnew
657 log.info(
"%d/%d old channels*gains/values have been read from database", nold,nvold)
658 log.info(
"%d/%d new channels*gains/values have been read from input ascii file", nnew,nvnew)
659 if nold>nnew
or nvold>(nvnew-nvnewdef):
660 log.info(
"%d/%d old channels*gains/values remain unchanged", nold-nnew,nvold-nvnew+nvnewdef)
661 if nold<nnew
or nvold<(nvnew-nvnewdef):
662 log.info(
"%d/%d new channels*gains/values have been added to database", nnew-nold,nvnew-nvold-nvnewdef)
664 log.info(
"%d/%d new channels*gains/values with default values have been added to database", ndef,nvdef)
667if (mval!=0
or Comment
is not None)
and (len(comment)>0
or len(txtFile)>0):
672 for io,since
in enumerate(iovList):
674 untilMod = iovUntil[io]
675 untilCmt = iovUntilCMT[io]
676 appendCmt = (untilCmt < (TileCalibCrest.MAXRUN,TileCalibCrest.MAXLBK))
or iov
684 if len(moduleList)!=1:
687 elif untilCmt>untilMod:
691 log.info(
"Updating IOV %s => %s => %s", str(io), str(since), comments[io] )
693 log.info(
"Updating IOV %s", str(since) )
696 if Comment
is not None:
699 comm =
"UNDO " + comm
702 if (comment
is None)
or (comment ==
"None"):
708 if since[1]==0
and begin[1]==0:
709 comm=
"Update for run %i - undoing changes done for run %i from file %s" % (since[0],begin[0],txtFile)
711 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)
714 comm=
"Update for run %i from file %s" % (since[0],txtFile)
716 comm=
"Update for run,lumi %i,%i from file %s" % (since[0],since[1],txtFile)
720 comm =
"UNDO " + comm
721 if iov
and appendCmt:
722 comm +=
" // " + comments[io]
723 if not undoCmt
and iov
and (nvalUpdated[io]==0
or comment==
"keep"):
724 author = commentsSplit[io]
727 blobWriters[io].setComment(author,comm)
730 if untilCmt!=untilMod:
731 cmtOnly = (since
in iovListCMT
and since
not in iovListMOD)
732 if not cmtOnly
and untilMod>since:
733 blobWriters[io].
register(since,outfolderTag)
735 blobWriters[io].
register(since,outfolderTag)
737 blobWriters[io].
register(since,outfolderTag)
740 if (comment
is None)
or (comment ==
"None"):
741 blobWriter2.setComment(
"None",
"None")
743 if run2>begin[0]
and lumi2==0
and begin[1]==0:
744 comment=
"Update for run %i - undoing changes done for run %i from file %s" % (run2,begin[0],txtFile)
746 comment=
"Update for run,lumi %i,%i - undoing changes done for %i,%i from file %s" % (run2,lumi2,begin[0],begin[1],txtFile)
747 blobWriter2.setComment(user,comment)
748 blobWriter2.register((run2,lumi2), outfolderTag)
749 elif run2>=0
and (run2<begin[0]
or (run2==begin[0]
and lumi2<begin[1])
and lumi2!=0):
750 log.warning(
"(run2,lumi2)=(%i,%i) is smaller than (run,lumi)=(%i,%i) - will not create second IOV", run2,lumi2,begin[0],begin[1])
752 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.