ATLAS Offline Software
Loading...
Searching...
No Matches
cmd-l1calo-conditions.py
Go to the documentation of this file.
1#!/usr/bin/env python
2# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3
4folderPath = "/TRIGGER/L1Calo/V1/Calibration/"
5
6import argparse
7import os
8import coral
9import json
10import pandas as pd
11from statistics import median
12from coldpie import cool
13import hashlib
14from itertools import chain
15
16from AthenaConfiguration import TestDefaults
17
18
19parser = argparse.ArgumentParser(description='Check what conditions are defined for MC',formatter_class=argparse.ArgumentDefaultsHelpFormatter)
20parser.add_argument("--db",nargs='+',default=["COOLOFL_TRIGGER/OFLP200"],help="specify sqlite files to check local")
21parser.add_argument("--globalTag",nargs='+',default=[TestDefaults.defaultConditionsTags.RUN4_MC],help="what globaltag to use. if use sqlite file will become blank")
22
23args = parser.parse_args()
24
25
26
27from AthenaConfiguration.RunToTimestampData import RunToTimestampDict
28
29# ignore all runs <= 313000 ... these are MC16 and earlier ... we don't care for these
30RunToTimestampDict = {k: v for k, v in RunToTimestampDict.items() if k > 313000}
31
32# build a commentsDict
33def load_comments(filename):
34 comments = {}
35 import re
36 from pathlib import Path
37 pattern = re.compile(
38 r'^\s*(\d+)\s*:\s*\d+\s*,?\s*#\s*(.*)$'
39 )
40
41 for line in Path(filename).read_text().splitlines():
42 m = pattern.match(line)
43 if m:
44 run_number = int(m.group(1))
45 comment = m.group(2).strip()
46 comments[run_number] = comment
47
48 return comments
49
50from AthenaConfiguration import RunToTimestampData
51comments = load_comments(RunToTimestampData.__file__)
52
53# extra runs and comments
54RunToTimestampDict[350000] = 1625100000; comments[350000] = "MC21 pp (RUN-4; mu = 0)"
55RunToTimestampDict[350060] = 1625110000; comments[350060] = "MC21 pp (RUN-4; mu = 60)"
56RunToTimestampDict[350140] = 1625120000; comments[350140] = "MC21 pp (RUN-4; mu = 140)"
57RunToTimestampDict[350200] = 1625130000; comments[350200] = "MC21 pp (RUN-4; mu = 200)"
58RunToTimestampDict[510000] = 1763227800; comments[510000] = "MC23 for 2025 heavy ion (PbPb) run"
59RunToTimestampDict[520900] = 1779789600; comments[520900] = "MC23 for 2026 heavy ion (PbPb) run"
60
61RunToTimestampDict[495000] = 1747346400; comments[495000] = "MC23g 2025-2026"
62
63
64dbSvc = cool.DatabaseSvcFactory.databaseService()
65
66
67summaries = {} # will be a dict of dicts .. first key is folder name, second is hash, value is: iov-list,summary
68
69allGlobalTags = set()
70
71for dbName in args.db:
72 globalTagList = list(args.globalTag)
73
74 if os.path.exists(dbName):
75 # we assume the DB is OFLP200 in the sqlite file. Use coolDBDiscovery script to check??
76 dbName = f"sqlite://;schema={dbName};dbname=OFLP200"
77 globalTagList = ["sqlite"]
78 print(dbName)
79
80 db = dbSvc.openDatabase(dbName)
81
82 globalTags = db.getFolderSet("/").listTags()
83 for globalTag in globalTagList:
84
85 if globalTag != "sqlite" and globalTag not in globalTags:
86 exit(f"GlobalTag {args.globalTag} missing")
87
88 allGlobalTags.add(globalTag)
89
90 for folder in db.listAllNodes():
91 if not folder.startswith(folderPath): continue
92 folder = db.getFolder(folder)
93 folderName = folder.fullPath().split("/")[-1]
94 if folderName not in summaries: summaries[folderName] = {}
95 try:
96 ftag = folder.resolveTag(globalTag) if globalTag!="sqlite" else ""
97 except Exception:
98 ftag = None
99 if ftag is not None:
100 print(folder.fullPath(),":",ftag)
101
102 objs = list(folder.browseObjects(0,9223372036854775807,cool.ChannelSelection.all(),ftag))
103 iovs = {}
104 for o in objs:
105 timePair = (globalTag,int(o.since()*1e-9),int(o.until()*1e-9)) # include globalTag in key
106 if timePair not in iovs: iovs[timePair] = {}
107 channelId = o.channelId()
108 record = {}
109 for s in o.payload().specification(): # loop over fields
110 # also s.storageType() returns an int (enum) of type, but we just use type(..)
111 b = o.payload().field(s.name()).data()
112 if type(b)== coral.Blob:
113 # interpret as json
114 record.update(json.loads(b.read(b.size())))
115 else:
116 record[s.name()] = b
117 iovs[timePair][channelId] = record
118
119 # go through IoVs, creating hash of payload and store in summaries
120 # use hash values to identify equivalent calibrations
121 for k1, d1 in iovs.items():
122 hashVal = hashlib.sha256(json.dumps(d1, sort_keys=True).encode()).hexdigest()
123 if hashVal in summaries[folderName]:
124 # this payload already exists ... add iov to list
125 summaries[folderName][hashVal][0] += [k1]
126 else:
127 # create a summary
128 df = pd.DataFrame.from_dict(d1, orient="index")
129 summary = {}
130 for col in df.columns:
131 s = df[col].dropna()
132 if len(s) == 0:
133 continue
134 if isinstance(s.iat[0], list):
135 values = list(chain.from_iterable(s))
136 else:
137 values = s.tolist()
138 sumStr = f"{min(values)}|{median(values)}|{max(values)}" if min(values)!= max(values) else f"{min(values)}"
139 summary[col] = {"summary":sumStr}
140
141 summary = pd.DataFrame(summary).T
142
143 summaries[folderName][hashVal] = [[k1], summary]
144
145
146
147
148for folder,fSummaries in summaries.items():
149 if len(fSummaries)==0: continue
150 print(folder,":")
151 allSummaries = {}
152 for i,s in fSummaries.items():
153 allSummaries[i[:5]] = s[1]
154 result = pd.concat(
155 {name: df["summary"] for name, df in allSummaries.items()},
156 axis=1,
157 )
158 print(result)
159 print("********")
160
161# go through run numbers, determine which "calibration" it has for each of the folders
162records = []
163for k,v in RunToTimestampDict.items():
164 record = {}
165 record["Campaign"] = str(k) + ":" + comments[k]
166 for folder,fSummaries in summaries.items():
167 setNum = []
168 for globalTag in sorted(list(allGlobalTags)):
169 for h,s in fSummaries.items():
170 for tag,since,until in s[0]:
171 if tag==globalTag and since<=v and until>v:
172 setNum += [h[:5]]
173 record[folder] = "|".join(setNum)
174 records += [record]
175
176df = pd.DataFrame(records).set_index("Campaign")
177df = df.sort_values(by=df.columns.tolist())
178
179print("\n Summary Table:")
180print(sorted(list(allGlobalTags)))
181
182text = df.to_string()
183lines = text.splitlines()
184
185# Header is the first two lines if the index has a name, otherwise the first line.
186header = lines[:2]
187rows = lines[2:]
188
189print("\n".join(header))
190
191last = None
192
193for i, (_, row) in enumerate(df.iterrows()):
194 if i > 0:
195 prev = df.iloc[i - 1]
196 if not (row == prev).all():
197 print("-" * len(lines[0]))
198 print(rows[i])
199
200
void print(char *figname, TCanvas *c1)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
STL class.
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179