ATLAS Offline Software
Loading...
Searching...
No Matches
ReadCellNoiseFromCrestCompare.py
Go to the documentation of this file.
1#!/bin/env python
2# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3#
4# ReadCellNoiseFromCrestCompare.py
5# (Based on ReadCellNoiseFromCoolCompare.py, adapted for CREST)
6# Ekaterina Ramakoti 2026-05-21
7#
8
9import sys,os
10os.environ['TERM'] = 'linux'
11
12#------------------------------- parse arguments and change defaults
13import argparse
14
15parser = argparse.ArgumentParser(
16 prog='ReadCellNoiseFromCrestCompare.py',
17 description='Dumps noise constants from online or offline folders/tags in CREST and compares two sources',
18 formatter_class=argparse.RawDescriptionHelpFormatter,
19 epilog="""
20Notes:
21- Conditions are compared using logical AND: both --maxdiff AND --maxdiffpercent
22 thresholds must be exceeded (both have to be TRUE) to print a difference
23- If *2 parameters (run2, lumi2, folder2, tag2, schema2) are not given,
24 values from primary parameters are used automatically
25- Use --cell, --gain, --index with -1 to process all values
26
27Usage:
28 # Compare two tags from same folder
29 %(prog)s -f /TILE/OFL02/NOISE/CELL -t UPD4 -t2 UPD1 -r 497970
30
31 # Compare specific cell/gain with thresholds
32 %(prog)s -f /TILE/OFL02/NOISE/CELL -t UPD4 -r 500000 -r2 400000 -c 123 -g 0 --maxdiff 0.001 --maxdiffpercent 5.0
33
34 # Wide format, brief output, all cells, full tag name without folder name
35 %(prog)s -t TileOfl02NoiseCell-RUN2-UPD4-36 -w -b -r 497970 -r2 345678
36 """
37)
38
39# primary source parameters
40parser.add_argument('-s', '--schema', default='CREST',
41 help='CREST server path or schema (default: CREST from env)')
42parser.add_argument('-f', '--folder', default='/TILE/OFL02/NOISE/CELL',
43 help='Status folder to use, e.g., /TILE/OFL02/NOISE/CELL')
44parser.add_argument('-t', '--tag', default='UPD4',
45 help='Tag to use, e.g., UPD4 or tag suffix like 14TeV-N200_dT50-01')
46parser.add_argument('-r', '--run', type=int, default=2147483647,
47 help='Run number (default: 2147483647, uses latest IOV)')
48parser.add_argument('-l', '--lumi', type=int, default=0,
49 help='Luminosity block number (default: 0)')
50
51# secondary parameters (*2) - default to primary values if not specified
52parser.add_argument('-s2', '--schema2', default='none',
53 help='Second schema for comparison (default: same as --schema)')
54parser.add_argument('-f2', '--folder2', default='none',
55 help='Second folder for comparison (default: same as --folder)')
56parser.add_argument('-t2', '--tag2', default='none',
57 help='Second tag for comparison (default: same as --tag)')
58parser.add_argument('-r2', '--run2', type=int, default=0,
59 help='Second run number (default: same as --run)')
60parser.add_argument('-l2', '--lumi2', type=int, default=-1,
61 help='Second lumi block (default: same as --lumi)')
62
63# threshold parameters
64parser.add_argument('-m', '--maxdiff', type=float, default=-1.0,
65 help='Absolute maximal difference to compare constants (default: -1.0 = dump all)')
66parser.add_argument('-m2', '--maxdiffpercent', type=float, default=-1.0,
67 help='Maximal difference in percent to compare constants (default: -1.0 = dump all)')
68
69# others parameters
70parser.add_argument('-n', '--channel', type=int, default=48,
71 help='COOL channel to read (default: 48 for Tile)')
72parser.add_argument('-c', '--cell', type=int, default=-1,
73 help='Cell hash 0-5183 (default: -1 = all cells)')
74parser.add_argument('-g', '--gain', type=int, default=-1,
75 help='Gain 0-3 (default: -1 = all gains)')
76parser.add_argument('-i', '--index', type=int, default=-1,
77 help='Parameter index 0-4 (default: -1 = all parameters)')
78parser.add_argument('-z', '--zero', type=float, default=5e-7,
79 help='Zero threshold: treat DB values below this as zeros (default: 5e-7)')
80parser.add_argument('-w', '--wide', action='store_true', default=False,
81 help='Wide format: print all values per cell in one line')
82parser.add_argument('-b', '--brief', action='store_true', default=False,
83 help='Brief output: print only numbers without character names')
84parser.add_argument('-d', '--double', action='store_true', default=False,
85 help='Print values with double precision')
86parser.add_argument('--stdout', '-o', action='store_true',
87 help='Print differences to standard output (in addition to file)')
88
89args = parser.parse_args()
90
91# apply default logic for *2 parameters (can be modified from command line)
92run = args.run
93run2 = args.run2 if args.run2 != 0 else run
94lumi = args.lumi
95lumi2 = args.lumi2 if args.lumi2 >= 0 else lumi
96schema = args.schema
97schema2 = args.schema2 if args.schema2 != "none" else schema
98folderPath = args.folder
99folderPath2 = args.folder2 if args.folder2 != "none" else folderPath
100tag = args.tag
101tag2 = args.tag2 if args.tag2 != "none" else tag
102maxdiff = args.maxdiff
103maxdiffpercent = args.maxdiffpercent
104chan = args.channel
105cell = args.cell
106gain = args.gain
107index = args.index
108zthr = args.zero
109multi = not args.wide # --wide sets multi=False
110brief = args.brief
111doubl = args.double
112print_to_stdout = args.stdout
113
114tile=(chan==48)
115
116if tag.upper().startswith('TILE') or tag.upper().startswith('CALO') or tag.upper().startswith('LAR'):
117 folderPath=''
118if tag2.upper().startswith('TILE') or tag2.upper().startswith('CALO') or tag2.upper().startswith('LAR'):
119 folderPath2=''
120
121if (schema != 'CREST' and os.path.isfile(schema)):
122 tag=''
123 folderPath=''
124if (schema2 != 'CREST' and os.path.isfile(schema2)):
125 tag2=''
126 folderPath2=''
127
128print("\n" + "="*65)
129print(" ReadCellNoiseFromCrestCompare - Configuration")
130print("="*65)
131print(f" {'Run/Lumi:':<14} 1st: run={run:<10} lumi={lumi:<6}")
132print(f" {' ':<14} 2nd: run={run2:<10} lumi={lumi2:<6}")
133print(f" {'Folder:':<14} {folderPath}")
134print(f" {'Folder2:':<14} {folderPath2}")
135print(f" {'Tag:':<14} {tag}")
136print(f" {'Tag2:':<14} {tag2}")
137print(f" {'Schema:':<14} {schema}")
138print(f" {'Schema2:':<14} {schema2}")
139print(f" {'Channel:':<14} {chan}")
140print(f" {'Cell/Gain/Idx:':<14} {cell}/{gain}/{index}")
141print(f" {'Thresholds:':<14} maxdiff={maxdiff:<8} maxdiffpercent={maxdiffpercent}")
142print(f" {'Zero thr:':<14} {zthr:.2e}")
143print(f" {'Format:':<14} wide={args.wide}, brief={brief}, double={doubl}")
144print("="*65 + "\n")
145
146from CaloCondBlobAlgs import CaloCondLogger
147from TileCalibBlobPython import TileCalibCrest
148from TileCalibBlobPython import TileCellTools
149
150#=== get a logger
151log = CaloCondLogger.getLogger("ReadCellNoise")
152import logging
153log.setLevel(logging.DEBUG)
154
155if run>=400000:
156 cabling = 'RUN3'
157elif run>=342550:
158 cabling = 'RUN2a'
159elif run>=222222:
160 cabling = 'RUN2'
161else:
162 cabling = 'RUN1'
163# hashMgr=TileCellTools.TileCellHashMgr(cabling=cabling)
164hashMgrDef=TileCellTools.TileCellHashMgr(cabling=cabling)
165hashMgrA=TileCellTools.TileCellHashMgr("UpgradeA")
166hashMgrBC=TileCellTools.TileCellHashMgr("UpgradeBC")
167hashMgrABC=TileCellTools.TileCellHashMgr("UpgradeABC")
168
169#=== Initialize blob reader for sources
170tag_upper = tag.upper()
171tag1 = tag_upper.split('_')[1][:4] if '_' in tag_upper else tag_upper[:4]
172if tag1 == "TILE" or tag1 == "CALO" or tag1[:3] == "LAR" or tag.startswith("TILE") or tag.startswith("CALO") or tag.startswith("LAR"):
173 folderPath1=""
174else:
175 folderPath1=folderPath
176
177tag2_upper = tag2.upper()
178tag2_1 = tag2_upper.split('_')[1][:4] if '_' in tag2_upper else tag2_upper[:4]
179if tag2_1 == "TILE" or tag2_1 == "CALO" or tag2_1[:3] == "LAR" or tag2.startswith("TILE") or tag2.startswith("CALO") or tag2.startswith("LAR"):
180 folderPath2=""
181else:
182 folderPath2=folderPath2
183
184try:
185 log.info("Connecting to DB1: schema=%s, folder=%s, tag=%s, run=%s, lumi=%s",
186 schema, folderPath1, tag, run, lumi)
187 blobReader = TileCalibCrest.TileBlobReaderCrest(schema, folderPath1, tag, run, lumi)
188 folderTag = blobReader.getTag()
189 log.info("Comment1: %s", blobReader.getComment((run,lumi)))
190 log.info("Connecting to DB2: schema=%s, folder=%s, tag=%s, run=%s, lumi=%s",
191 schema2, folderPath2, tag2, run2, lumi2)
192 blobReader2 = TileCalibCrest.TileBlobReaderCrest(schema2, folderPath2, tag2, run2, lumi2)
193 folderTag2 = blobReader2.getTag()
194 log.info("Comment2: %s", blobReader2.getComment((run2,lumi2)))
195except Exception as e:
196 log.error("Initialization failed: %s", e)
197 sys.exit(1)
198
199#=== create CaloCondBlobFlt
200blobFlt = blobReader.getDrawer(-1,chan,None,False,False)
201if blobFlt is None:
202 log.critical("Could not locate a data blob in CREST payload for COOL channel %s", chan)
203 sys.exit(1)
204
205blobFlt2 = blobReader2.getDrawer(-1,chan,None,False,False)
206if blobFlt2 is None:
207 log.critical("Could not locate a data blob in CREST payload for COOL channel %s", chan)
208 sys.exit(1)
209
210#=== create the output file
211outputfile = 'output_crest.ascii'
212f = open(outputfile, 'w')
213
214f.write("Command line parameters used: \n %s \n\n" % sys.argv[1:])
215f.write("=== Source 1 ===\n")
216f.write("schema : %s\n" % schema)
217f.write("folder : %s\n" % folderPath1)
218f.write("tag : %s\n" % folderTag)
219f.write("run : %d\n" % run)
220f.write("lumi : %d\n" % lumi)
221f.write("channel : %d\n" % chan)
222f.write("comment : %s\n\n" % blobReader.getComment((run,lumi)))
223
224f.write("=== Source 2 ===\n")
225f.write("schema : %s\n" % schema2)
226f.write("folder : %s\n" % folderPath2)
227f.write("tag : %s\n" % folderTag2)
228f.write("run : %d\n" % run2)
229f.write("lumi : %d\n" % lumi2)
230f.write("channel : %d\n" % chan)
231f.write("comment : %s\n\n" % blobReader2.getComment((run2,lumi2)))
232
233f.write("=== Comparison parameters ===\n")
234f.write("maxdiff : %f\n" % maxdiff)
235f.write("maxdiffpercent : %f\n\n" % maxdiffpercent)
236f.write("zero threshold : %e\n\n" % zthr)
237
238
239#=== retrieve data from the blob
240#cell = 0 # 0..5183 - Tile hash
241#gain = 0 # 0..3 - four Tile cell gains: -11, -12, -15, -16
242#index = 0 # 0..4 - electronic or pile-up noise or 2-G noise parameters
243ncell=blobFlt.getNChans()
244ngain=blobFlt.getNGains()
245nval=blobFlt.getObjSizeUint32()
246
247if cell<0 or cell>=ncell:
248 cellmin=0
249 cellmax=ncell
250else:
251 cellmin=cell
252 cellmax=cell+1
253
254if gain<0 or gain>=ngain:
255 gainmin=0
256 gainmax=ngain
257else:
258 gainmin=gain
259 gainmax=gain+1
260
261if index<0 or index>=nval:
262 indexmin=0
263 indexmax=nval
264else:
265 indexmin=index
266 indexmax=index+1
267
268log.info("From DB: ncell: %d ngain %d index nval %d", ncell, ngain, nval)
269
270if brief or doubl:
271 name1 = ["","","0.0 "]
272 names = ["S0 ", "Pl ", "S1 ", "S2 ", "Ra "]
273 dm=" "
274else:
275 name1 = ["Noise cell ", "gain ","0.00 "]
276 names = [" RMS ", "pileup ", " RMS1 ", " RMS2 ", " Ratio "]
277 for i in range(len(names),indexmax):
278 names += ["c"+str(i)+" "]
279 dm="\t"
280
281# Use appropriate hashMgr based on cabling
282if ncell>hashMgrA.getHashMax():
283 hashMgr=hashMgrABC
284elif ncell>hashMgrBC.getHashMax():
285 hashMgr=hashMgrA
286elif ncell>hashMgrDef.getHashMax():
287 hashMgr=hashMgrBC
288else:
289 hashMgr=hashMgrDef
290log.info("Using %s CellMgr with hashMax %d", hashMgr.getGeometry(),hashMgr.getHashMax())
291
292for cell in range(cellmin,cellmax):
293 if tile and len(name1[0]):
294 name1[0] = "%s %6s hash " % hashMgr.getNames(cell)
295 for gain in range(gainmin,gainmax):
296 msg="%s%4d %s%d\t" % ( name1[0], cell, name1[1], gain)
297 l0=len(msg)
298 if multi:
299 dm="\n"+msg
300 for index in range(indexmin,indexmax):
301 v=blobFlt.getData(cell, gain, index)
302 v2=blobFlt2.getData(cell, gain, index)
303 dv12 = v - v2
304 if abs(dv12)<zthr:
305 dv12 = 0
306 if v2 == 0:
307 if v==0:
308 dp12=0
309 else:
310 dp12=100
311 else:
312 dp12=dv12*100./v2
313
314 if abs(dv12) > maxdiff and abs(dp12) > maxdiffpercent:
315 if doubl:
316 s1 = "{0:<14.9g}".format(v) if v<0 else "{0:<15.10g}".format(v)
317 s2 = "{0:<14.9g}".format(v2) if v2<0 else "{0:<15.10g}".format(v2)
318 s3 = "{0:<14.9g}".format(dv12) if dv12<0 else "{0:<15.10g}".format(dv12)
319 s4 = "{0:<14.9g}".format(dp12) if dp12<0 else "{0:<15.10g}".format(dp12)
320 msg += "%s v1 %s v2 %s diff %s diffpercent %s%s" % (names[index],s1.ljust(15),s2.ljust(15),s3.ljust(15),s4.ljust(15),dm)
321 else:
322 s1 = name1[2] if abs(v)<zthr else "%8.6f" % v if abs(v)<1 else "{0:<8.7g}".format(v).ljust(8)
323 s2 = name1[2] if abs(v2)<zthr else "%8.6f" % v2 if abs(v2)<1 else "{0:<8.7g}".format(v2).ljust(8)
324 s3 = name1[2] if abs(dv12)<zthr else "%8.6f" % dv12 if abs(dv12)<1 else "{0:<8.7g}".format(dv12).ljust(8)
325 s4 = name1[2] if abs(dp12)<zthr else "%8.6f" % dp12 if abs(dp12)<1 else "{0:<8.7g}".format(dp12).ljust(8)
326 msg += "%s v1 %s v2 %s diff %s diffpercent %s%s" % (names[index],s1[:8],s2[:8],s3[:8],s4[:8],dm)
327
328 if len(msg)>l0:
329 output_line = msg[:len(msg)-len(dm)]
330 f.write(output_line + "\n")
331 if print_to_stdout:
332 print(output_line)
333
334f.close()
335log.info("Output written to %s", outputfile)
void print(char *figname, TCanvas *c1)