ATLAS Offline Software
Loading...
Searching...
No Matches
CopyBlobFromCool.py
Go to the documentation of this file.
1#!/bin/env python
2
3# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
4#
5# File: CopyBlobFromCool.py
6# Sanya Solodkov <Sanya.Solodkov@cern.ch>, 2025-02-04
7#
8# Purpose: Read blobs from COOL and write them to JSON file
9#
10
11import getopt,sys,os,json
12os.environ['TERM'] = 'linux'
13
14def usage():
15 print ("Usage: ",sys.argv[0]," [OPTION] ... ")
16 print ("Read TileCal blobs from COOL and convert them to JSON format for CREST")
17 print ("")
18 print ("-h, --help shows this help")
19 print ("-s, --schema= specify schema to use, like 'COOLOFL_TILE/CONDBR2', or sqlite file name like 'tileSqlite.db'")
20 print ("-S, --server= specify server - ORACLE or FRONTIER, default is FRONTIER")
21 print ("-d, --dbname= specify the database name e.g. CONDBR2, used together with sqlite file name")
22 print ("-f, --folder= specify folder to use e.g. /TILE/OFL02/STATUS/ADC")
23 print ("-t, --tag= specify tag to use, f.i. UPD1 or UPD4 or tag suffix like RUN2-UPD4-04")
24 print ("-r, --run= specify run number, by default uses latest iov")
25 print ("-l, --lumi= specify lumi block number, default is 0")
26 print ("-c, --channel= specify COOL channel, by default COOL channels 0-275 and 1000 are used")
27 print ("-f, --full if sqlite file doesn't contain everything, try to find missing COOL channels in Oracle DB")
28 print ("-o, --output= specify the prefix for output json file")
29
30letters = "hS:s:d:t:f:r:l:c:o:f"
31keywords = ["help","server=","schema=","dbname=","tag=","folder=","run=","lumi=","channel=","output=","full"]
32
33try:
34 opts, extraparams = getopt.getopt(sys.argv[1:],letters,keywords)
35except getopt.GetoptError as err:
36 print (str(err))
37 usage()
38 sys.exit(2)
39
40# defaults
41run = 2147483647
42lumi = 0
43server = ''
44schema = 'COOLOFL_TILE/CONDBR2'
45folderPath = '/TILE/OFL02/CALIB/CIS/LIN'
46dbName = 'CONDBR2'
47tag = 'UPD4'
48channels = list(range(276)) + [1000]
49output = ""
50full = False
51
52for o, a in opts:
53 a = a.strip()
54 if o in ("-s","--schema"):
55 schema = a
56 elif o in ("-S","--server"):
57 server = a
58 elif o in ("-d","--dbname"):
59 dbName = a
60 elif o in ("-f","--folder"):
61 folderPath = a
62 elif o in ("-t","--tag"):
63 tag = a
64 elif o in ("-r","--run"):
65 run = int(a)
66 elif o in ("-l","--lumi"):
67 lumi = int(a)
68 elif o in ("-c","--channel"):
69 channels = [int(a)]
70 elif o in ("-o","--output"):
71 output = a
72 elif o in ("-f","--full"):
73 full = True
74 elif o in ("-h","--help"):
75 usage()
76 sys.exit(2)
77 else:
78 usage()
79 sys.exit(2)
80
81import base64
82import cppyy
83from PyCool import cool
84from TileCalibBlobPython import TileCalibTools
85from TileCalibBlobObjs.Classes import TileCalibDrawerCmt
86
87Blob = cppyy.gbl.coral.Blob
88
89def make_blob(string):
90 b = Blob()
91 b.write(string)
92 b.seek(0)
93 return b
94
95from TileCalibBlobPython.TileCalibLogger import getLogger
96log = getLogger("CopyBlob")
97import logging
98logLevel=logging.DEBUG
99log.setLevel(logLevel)
100
101#=== Read from COOL server:
102
103if os.path.isfile(schema):
104 schema = 'sqlite://;schema='+schema+';dbname='+dbName
105else:
106 log.info("File %s was not found, assuming it's full schema string" , schema)
107
108db = TileCalibTools.openDbConn(schema,server)
109if tag.upper().startswith("TILE") or tag.upper().startswith("CALO") or tag.upper().startswith("LAR"):
110 folderTag = tag
111else:
112 folderTag = TileCalibTools.getFolderTag(db if 'CONDBR2' in schema else schema, folderPath, tag)
113log.info("Initializing folder %s with tag %s", folderPath, folderTag)
114
115folder = db.getFolder(folderPath)
116
117log.info( "\n" )
118
119payloadSpec = cool.RecordSpecification()
120payloadSpec.extend( 'TileCalibBlob', cool.StorageType.Blob64k )
121folderMode = cool.FolderVersioning.MULTI_VERSION
122folderSpec = cool.FolderSpecification(folderMode, payloadSpec)
123
124#=== loop over all COOL channels
125obj = None
126suff = ""
127since = (run<<32)+lumi
128maxSince = 0
129jdata={}
130missingChannels = []
131if full and 'sqlite' in schema:
132 maxIter = 2
133else:
134 maxIter = 1
135for iter in range(maxIter):
136 if missingChannels:
137 dbOra = TileCalibTools.openDbOracle(server, schema, folderPath)
138 folder = dbOra.getFolder(folderPath)
139 channels = missingChannels
140 missingChannels = []
141 for chan in channels:
142 try:
143 obj = folder.findObject( since, chan, folderTag )
144 objsince = obj.since()
145 objuntil = obj.until()
146 (sinceRun,sinceLum) = (objsince>>32,objsince&0xFFFFFFFF)
147 (untilRun,untilLum) = (objuntil>>32,objuntil&0xFFFFFFFF)
148 if (objsince>maxSince):
149 maxSince=objsince
150 coralblob = obj.payload()[0]
151 blob = coralblob.read()
152 b64string = str(base64.b64encode(blob),'ascii')
153 jdata[chan] = [b64string]
154 if chan==1000:
156 fullcmt = cmt.getFullComment()
157 log.info(fullcmt+"\n")
158 # back conversion - just for test
159 blob1 = base64.decodebytes(bytes(b64string,'ascii'))
160 coralblob = make_blob(blob1)
162 fullcmt1 = cmt1.getFullComment()
163 if(fullcmt!=fullcmt1): log.error(fullcmt1+"\n")
164 except Exception:
165 if iter==1:
166 log.warning( "Warning: can not read COOL channel %d from Oracle" , chan)
167 else:
168 if maxIter==2:
169 log.info( "Info: COOL channel %d is missing in input DB, it will be taken from Oracle" , chan)
170 else:
171 log.warning( "Warning: can not read COOL channel %d from input DB" , chan)
172 missingChannels.append(chan)
173 if len(missingChannels)==0:
174 break
175if iter>0:
176 jdata = dict(sorted(jdata.items(), key=lambda item: int(item[0])))
177
178if output=="":
179 if folderTag and folderTag!="HEAD":
180 output = folderTag
181 else:
182 output = folderPath.replace("/","")+"-HEAD"
183if "." not in output:
184 (sinceRun,sinceLumi) = (maxSince>>32,maxSince&0xFFFFFFFF)
185 suff = "." + str(sinceRun) + "." + str(sinceLumi) + ".json"
186 ofile = output + suff
187else:
188 ofile = output
189with open(ofile, 'w') as the_file:
190 json.dump(jdata, the_file, separators=(',', ':'), sort_keys=True)
191
192print("see file",ofile)
193
194#=== close DB
195db.closeDatabase()
if(pathvar)
void print(char *figname, TCanvas *c1)
static const TileCalibDrawerCmt * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerCmt.