11 __author__=
"Walter Lampl <walter.lampl@cern.ch>"
12 __doc__ =
" An athena-like algorithm to interactivly convert LAr Identifiers and print the bad channel status"
15 from AthenaPython.PyAthena
import StatusCode
16 import AthenaPython.PyAthena
as PyAthena
20 from ROOT
import HWIdentifier, Identifier, IdentifierHash, LArBadChannel, LArBadChanBitPacking
22 from ctypes
import c_uint
28 This class is an Athena algorithm although it doesn't quite behave like one.
29 It's purpose is to interactivly convert LAr Online/Offline identifiers and
30 prints the bad channel status and optionally some calibration constants for
31 the given channel identifier.
34 def __init__(self, name="LArCellConditionsAlg", **kw):
37 super(LArCellConditionsAlg,self).
__init__(**kw)
55 self.
_detStore = PyAthena.py_svc(
'StoreGateSvc/DetectorStore')
57 self.
msg.
error(
"Failed to get DetectorStore")
58 return StatusCode.Failure
60 self.
_condStore = PyAthena.py_svc(
'StoreGateSvc/ConditionStore')
62 self.
msg.
error(
"Failed to get ConditionStore")
63 return StatusCode.Failure
68 self.
msg.
error(
"Failed to get LArOnlineID")
69 return StatusCode.Failure
74 self.
msg.
error(
"Failed to get CaloCell_ID")
75 return StatusCode.Failure
80 for n
in (
"lowNoiseHG",
"highNoiseHG",
"unstableNoiseHG",
"lowNoiseMG",
"highNoiseMG",
"unstableNoiseMG",
"lowNoiseLG",
"highNoiseLG",
"unstableNoiseLG",
"sporadicBurstNoise"):
86 for n
in (
"deadReadout",
"deadPhys",
"almostDead"):
103 return StatusCode.Success
114 eid=ROOT.Gaudi.Hive.currentContext().eventID()
120 print(
"ERROR, failed to get LArCabling")
121 return StatusCode.Failure
128 print(
"ERROR, failed to get LArBadChannels")
129 return StatusCode.Failure
136 print (
"WARNING: Failed to retrieve Pedestal from DetStore")
138 traceback.print_exc()
145 print (
"WARNING: Failed to retrieve MphysOverMcal from DetStore")
147 traceback.print_exc()
152 self.
larRamp=condCont.find(eid)
154 print (
"WARNING: Failed to retrieve LArRamp from DetStore")
156 traceback.print_exc()
163 print (
"WARNING: Failed to retrieve LArDAC2uA from DetStore")
165 traceback.print_exc()
172 print (
"WARNING: Failed to retrieve LAruA2MeV from DetStore")
174 traceback.print_exc()
181 print (
"WARNING: Failed to retrieve LArHVScaleCorr from DetStore")
183 traceback.print_exc()
190 print (
"WARNING: Failed to retrieve LArDPSThresholds from DetStore")
192 traceback.print_exc()
198 condCont=self.
_condStore.
retrieve(
"CondCont<CaloDetDescrManager>",
"CaloDetDescrManager")
201 print(
"Failed to retrieve CaloDDM")
202 return StatusCode.Failure
208 return StatusCode.Success
221 if len(rep)==0
or rep==
"QUIT" or rep==
"EXIT" or rep==
".Q":
break
224 if rep.startswith(
"SEARCH"):
225 inp=rep_in[6:].strip()
226 starttime=time.time()
228 print(
"seach time %.1f sec" % (time.time()-starttime))
242 print(t.get_identifier32().get_compact(),
" IsLAr (online)")
244 print(t.get_identifier32().getCompact(),
" isLAr (offline)")
252 if rep.startswith(
"ON"):
256 if chid
is not None and self.
onlineID.is_lar(chid):
258 if id
is None: id=self.
noid
261 print(
"ERROR: Could not interpret input.")
265 if rep.startswith(
"OF"):
269 if id
is not None and self.
offlineID.is_lar(id):
270 chid=self.
larCabling.createSignalChannelID(id)
273 print(
"ERROR: Could not interpret input.")
279 if chid
is not None and self.
onlineID.is_lar(chid):
283 if id
is not None and self.
offlineID.is_lar(id):
284 chid=self.
larCabling.createSignalChannelID(id)
286 if chid
is None or id
is None:
287 print(
"ERROR: Could not interpret input.")
294 return StatusCode.Success
303 theDDE=self.
caloDDM.get_element(id)
304 print(
"raw Eta= %.3f, Phi=%.3f r=%.3f" % (theDDE.eta_raw(),theDDE.phi_raw(),theDDE.r_raw()))
305 print(
"raw x=%.3f, y=%.3f, z=%.3f" % (theDDE.x(),theDDE.y(),theDDE.z_raw()))
306 except Exception
as e:
313 print(
"DAC2uA: None",end=
"")
318 print(
" uA2MeV: None",end=
"")
323 print(
" HVScaleCorr: None")
325 for gain,gainname
in ((0,
"HG"),(1,
"MG"),(2,
"LG")):
326 print(gainname,end=
"")
334 print (
" Ped: %.3f " % ped,end=
"")
335 print (
" PedRMS: %.3f" % pedRMS,end=
"")
338 ramp=self.
larRamp.ADC2DAC(chid,gain)
340 print(
" Ramp: %.3f" % ramp[1],end=
"")
342 print(
" Ramp: Empty",end=
"")
344 print(
" Ramp: None",end=
"")
348 print (
" MphysOverMcal: %.5f" % mpmc,end=
"")
350 print (
" MphysOverMcal: None",end=
"")
356 trgSumTrh=self.
larDSPThr.trigSumThr(chid)
357 print(
"DSP Thresholds: tQ:%f, samples:%f, trigSum:%f" % (tQThr,samThr,trgSumTrh))
359 print(
"DSP Thresholds: None")
364 return StatusCode.Success
368 if file
is not None: file.write(out+
"\n")
372 c=
input(
"Press 'q' to quit, 'a' for all ...")
373 if c.upper().startswith(
"Q"):
375 if c.upper().startswith(
"A"):
383 rep=
input(
"Enter Id >")
393 onlName=
str(chid.get_identifier32().get_compact())+
" "
400 ftname=self.
onlineID.feedthrough_name(chid)
412 onlName+=
"FT "+
str(ft)+
"("+ftname+
")/Slot "+
str(slot)+
"/Chan "+
str(chan)
415 calibLines=self.
larCabling.calibSlotLine(chid)
416 if (len(calibLines)):
418 for calib_chid
in calibLines:
427 oflName=
str(id.get_identifier32().get_compact()) +
" "
430 oflName +=
"[disconnected]"
461 oflName+=
"Lay "+
str(layer)+
"/Reg "+
str(region)+
"/Eta "+
str(eta)+
"/Phi "+
str(phi) +
"]"
462 return onlName+
" = "+oflName
468 upInput=input.upper().strip()
469 if upInput.startswith(
'0X'):
472 id_int=
int(upInput,16)
474 self.
_oflErrStr=
"Can't interpret hexadecimal identifier, got " + upInput
478 self.
_oflErrStr=
"Not a LAR identifier: " + upInput
481 elif upInput.isdigit():
483 id_int=
int(upInput,10)
485 self.
_oflErrStr=
"Can't interpret decimal identifier, got "+upInput
490 self.
_oflErrStr=
"Not a LAR identifier: " + upInput
494 tbl=str.maketrans(
r",:;/\#",
" ")
496 for f
in upInput.translate(tbl).
split():
500 self.
_oflErrStr=
"Not enough fields to build offline id"
504 if fields[0].startswith(
"EMB"):
507 elif fields[0].startswith(
"EMECOW"):
510 elif fields[0].startswith(
"EMECIW"):
513 elif fields[0].startswith(
"HE"):
516 elif fields[0].startswith(
"F"):
520 self.
_oflErrStr=
"Can't interpret subcalo field, got "+fields[0]
528 self.
_oflErrStr=
"Can't interpret input: Expected 5 or 6 sub-fields, found "+
str(len(fields))
531 if sidefield.endswith(
"A")
or sidefield.endswith(
"P")
or sidefield.endswith(
"POS")
or sidefield ==
'1':
533 elif sidefield.endswith(
"C")
or sidefield.endswith(
"N")
or sidefield.endswith(
"NEG")
or sidefield ==
'0':
536 self.
_oflErrStr=
"Can't interpret field for detector side, got "+ sidefield
542 if fields[-4].isdigit():
543 layer=
int(fields[-4])
546 if (ls==
"PS" or ls.startswith(
"PRES")): layer=0
547 elif (ls==
"FRONT" or ls.startswith(
"STRIP")): layer=1
548 elif ls.startswith(
"MID"): layer=2
549 elif ls==
"BACK": layer=3
551 self.
_oflErrStr=
"Can't interpet textual value for layer, got " + ls
554 region=
int(fields[-3])
558 self.
_oflErrStr=
"Not-numerical input for region, eta or phi"
566 self.
_oflErrStr=
"Failed to build offline region identifier. Layer/region values inconsistent?"
572 if (eta<etamin
or eta>etamax):
573 self.
_oflErrStr=
"Eta must be between %i and %i for this region, got %i" % (etamin,etamax,eta)
578 if (phi<phimin
or phi>phimax):
579 self.
_oflErrStr=
"Phi must be between %i and %i for this region, got %i" % (phimin,phimax,phi)
587 self.
_oflErrStr=
"Failed to build offline identifier. One or more values out-of-range?"
597 upInput=input.upper().strip()
598 if upInput.startswith(
'0X'):
601 id_int=
int(upInput,16)
603 self.
_onlErrStr=
"Can't interpret hexadecimal online identifier, got "+input
606 if (id_int < 0x38000000
or id_int > 0x3bc68000):
607 self.
_onlErrStr=
"Outside of numerical range of online identifiers"
611 id=HWIdentifier(id_int<<32)
613 self.
_onlErrStr=
"Not a LAR identifier:" + input
616 elif upInput.isdigit():
618 id_int=
int(upInput,10)
620 self.
_onlErrStr=
"Can't interpret decimal online identifier, got "+input
623 if (id_int < 0x38000000
or id_int > 0x3bc68000):
624 self.
_onlErrStr=
"Outside of numerical range of online identifiers"
627 id=HWIdentifier(id_int<<32)
629 self.
_onlErrStr=
"Not a LAR identifier:" + input
633 tbl=str.maketrans(
r",:;/\#",
" ")
635 for f
in upInput.translate(tbl).
split():
646 self.
_onlErrStr=
"Expected 4 or 5 fields, found "+
str(len(fields))
649 if "BARREL".
find(fields[0][0:6])==0:
651 elif "ENDCAP".
find(fields[0][0:6])==0:
653 elif "EC".
find(fields[0][0:2])==0:
656 self.
_onlErrStr=
"Can't interpret field for Barrel/Endcap, got "+fields[0]
659 if sideField.endswith(
"A")
or sideField==
"1" or sideField.startswith(
"P"):
661 elif sideField.endswith(
"C")
or sideField==
"0" or sideField.startswith(
"N"):
664 self.
_onlErrStr=
"Can't interpret field for detector side, got " + sideField
671 self.
_onlErrStr=
"Not-numerical input for FT slot or channel"
676 self.
_onlErrStr=
"Barrel feedthrough number must be between 0 and 31, got "+
str(slot)
680 self.
_onlErrStr=
"Endcap feedthrough number must be between 0 and 24, got "+
str(slot)
683 if slot<1
or slot>15:
684 self.
_onlErrStr=
"Slot number must be between 1 and 15, got "+
str(slot)
687 if chan<0
or chan>127:
688 self.
_onlErrStr=
"Channel number must be between 0 and 127, got "+
str(chan)
695 id=self.
onlineID.channel_Id(bec,side,ft,slot,chan)
697 self.
_onlErrStr=
"Failed to build online identifier. One or more values out-of-range?"
717 tbl=str.maketrans(
",:;#=",
" ")
719 for t
in input.translate(tbl).
split():
721 if (len(tokens)>0)
and not tokens[-1].isalpha()
and not t[0].isalpha():
726 def interpretToken(input):
727 pos=input[1:].
find(
"+-")
729 pos=input[1:].
find(
"-")
741 e1=
float(input[:pos])
743 print(
"Expected numerical value, got",input[:pos] )
746 if uplow
is not None:
748 e2=
float(input[pos+1:])
750 print(
"Expected numerical value after '+-', got",input[pos+1:])
759 ret=[e1-0.025,e1+0.025]
764 while (i<len(tokens)):
765 if tokens[i].
upper()==
"OUT" and i+1<len(tokens):
768 elif tokens[i].
upper()==
"ETA" and i+1<len(tokens):
769 eta=interpretToken(tokens[i+1])
771 elif tokens[i].
upper()==
"LAYER" and i+1<len(tokens):
772 layer=interpretToken(tokens[i+1])
774 elif tokens[i].
upper()==
"PHI" and i+1<len(tokens):
775 phi=interpretToken(tokens[i+1])
777 elif tokens[i].
upper()==
"FT" and i+1<len(tokens):
778 ft=interpretToken(tokens[i+1])
780 elif tokens[i].
upper()==
"SLOT" and i+1<len(tokens):
781 slot=interpretToken(tokens[i+1])
783 elif tokens[i].
upper()==
"BAD":
785 elif tokens[i].
upper()==
"NOISE" or tokens[i].
upper()==
"NOISY":
787 elif tokens[i].
upper()==
"DEAD":
789 elif tokens[i].
upper().startswith(
"BAR"):
791 elif tokens[i].
upper().startswith(
"END"):
793 elif tokens[i].
upper()==
"EM":
795 elif tokens[i].
upper()==
"HEC":
797 elif tokens[i].
upper()==
"FCAL":
799 elif tokens[i].
upper()==
"A" or tokens[i]==
"P":
801 elif tokens[i].
upper()==
"C" or tokens[i]==
"N":
803 elif tokens[i].
upper()==
"CL" and tokens[i+1].isdigit():
809 bctypes |= 1<<stat[1]
811 print(
"Unknown Keyword",tokens[i] )
814 print(
"Searching for cells with ",end=
"")
815 if eta
is not None:
print(
" %.3f <= eta <= %.3f" % (eta[0],eta[1]),end=
"")
816 if phi
is not None:
print(
" %.3f <= phi <= %.3f" % (phi[0],phi[1]),end=
"")
817 if layer
is not None:
print(
" %.0f <= layer <= %.0f" % (layer[0],layer[1]),end=
"")
819 if bec==0:
print(
" Barrel",end=
"")
820 if bec==1:
print(
" Endcap",end=
"")
822 if side==1:
print(
" A Side",end=
"")
823 if side==0:
print(
" C Side",end=
"")
825 if ft
is not None:
print(
" %.0f <= FT <= %.0f" % (ft[0],ft[1]),end=
"")
826 if slot
is not None:
print(
" %.0f <= Slot <= %.0f" % (slot[0],slot[1]),end=
"")
829 print (
" "+self.
bc_packing.stringStatus(LArBadChannel(bctypes)),end=
"")
831 if phi
is None and eta
is None and bctypes==0
and ft
is None and side
is None and bec
is None and slot
is None and layer
and subcalo
is None:
832 print (
"No search criteria set!")
836 if cl
is not None:
print(
" CL:",cl,end=
"")
841 print(
"ERROR: GeoModel not activated, run with -g option")
844 if outname
is not None:
846 outfile=
open(outname,
"w")
848 print (
"ERROR failed to open file",outname)
850 traceback.print_exc()
856 for idH
in range(182468):
857 idHash=IdentifierHash(idH)
858 chid=self.
larCabling.createSignalChannelIDFromHash(idHash)
864 bcw=bcstat.packedData()
865 if bcw & bctypes == 0:
continue
869 if bec
is not None and bec!=self.
onlineID.barrel_ec(chid):
continue
870 if side
is not None and side!=self.
onlineID.pos_neg(chid):
continue
871 if ft
is not None and (self.
onlineID.feedthrough(chid)<ft[0]
or self.
onlineID.feedthrough(chid)>ft[1]):
continue
872 if slot
is not None and (self.
onlineID.slot(chid)<slot[0]
or self.
onlineID.slot(chid)>slot[1]):
continue
876 calibLines=self.
larCabling.calibSlotLine(chid)
878 for foundCLs
in calibLines:
883 if not keep:
continue
886 print (
"Failed to get calib line:")
888 traceback.print_exc()
893 if eta
is not None or phi
is not None:
894 theDDE=self.
caloDDM.get_element(idHash)
897 if eta
is not None and (e<eta[0]
or e>eta[1]):
continue
898 if phi
is not None and (p<phi[0]
or p>phi[1]):
continue
899 ep=
" eta=%.3f phi=%.3f " % (e,p)
902 if subcalo
is not None and subcalo!=self.
offlineID.sub_calo(id):
continue
903 if layer
is not None and (self.
offlineID.sampling(id)<layer[0]
or self.
offlineID.sampling(id)>layer[1]):
continue
908 if outfile
is not None: outfile.close()
912 print(
"First mode of operation:")
913 print(
"Enter a channel identifier (online or offline). Allowed forms are:")
914 print(
" Decimal or hexadecimal compact identifier, eg. 'online 0x39000000'")
915 print(
" Expanded identifer like")
916 print(
" 'online Bar C 1 1 1' (Barrel C FT 1, Slot 1 channel 1)")
917 print(
" 'offline FCAL A 1 0 1 1' (FCAL A, Layer 1, Region 0, Eta 1 Phi 1)")
918 print(
" Offline ids must start with one of the following subdetectors names:")
919 print(
" EMB, EMECIW, EMECOW, HEC, FCAL")
920 print(
" Online ids must start with either 'BAR' or 'END'")
921 print(
" If the prefix 'online' or 'offline' is omitted both are tried.")
922 print(
"\nSecond mode of operation:")
923 print(
"Search <keyword> <keyword> ..")
924 print(
" Keywords are: 'barrel', 'endcap', A', 'C', or any bad-channel type")
925 print(
" Keywords with arguments are: 'eta', 'phi', 'layer', 'FT', 'Slot' and 'CL'")
926 print(
"\nType 'quit' to terminate'")