Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
TileCalibCrest.py
Go to the documentation of this file.
1 #!/bin/env python
2 
3 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4 # TileCalibCrest.py
5 # Sanya Solodkov <Sanya.Solodkov@cern.ch>, 2025-02-04
6 #
7 
8 """
9 Python helper module for managing CREST DB connections and TileCalibBlobs.
10 """
11 
12 import os, cppyy, base64, json
13 
14 from PyCool import cool # noqa: F401
15 Blob = cppyy.gbl.coral.Blob
16 
17 from pycrest.api.crest_api import CrestApi
18 
19 from TileCalibBlobObjs.Classes import TileCalibUtils, TileCalibDrawerCmt, \
20  TileCalibDrawerInt, TileCalibDrawerOfc, TileCalibDrawerBch, \
21  TileCalibDrawerFlt, TileCalibType
22 from TileCalibBlobPython import TileCalibTools
23 
24 #=== get a logger
25 from TileCalibBlobPython.TileCalibLogger import TileCalibLogger, getLogger
26 log = getLogger("TileCalibCrest")
27 
28 
29 #======================================================================
30 #===
31 #=== Global helper functions
32 #===
33 #======================================================================
34 
35 #
36 #______________________________________________________________________
37 #=== useful constants
38 MINRUN = 0
39 MINLBK = 0
40 MAXRUN = (1<<31)-1
41 MAXLBK = (1<<32)-1
42 MAXRUNLUMI = (MAXRUN<<32)+MAXLBK
43 # empty Tile channel for storing laser partition variation. DO NOT CHANGE.
44 LASPARTCHAN = 43
45 
46 
47 class TileBlobReaderCrest(TileCalibLogger):
48  """
49  TileCalibBlobReader is a helper class, managing the details of CREST interactions for
50  the user of TileCalibBlobs.
51  """
52 
53  #____________________________________________________________________
54  def __init__(self, db, folder='', tag='', run=None, lumi=0, modmin=0, modmax=275):
55  """
56  Input:
57  - db : server connection string or file name
58  - folder: full folder path
59  - tag : The folder tag, e.g. \"UPD4-24\" or full tag
60  - run : Run number (if known)
61  - lumi : Lumi block number
62  - modmin: Minimal module (COOL channel number)
63  - modmax: Maximal module (COOL channel number)
64  """
65  #=== initialize base class
66  TileCalibLogger.__init__(self,"TileBlobReader")
67 
68  self.__db = db
69  self.__folder = folder
70  self.__tag = tag
71 
72  self.__iovList = []
73  self.__iov = (-1,0)
74  self.__commentBlob = None
75  self.__drawerBlob = [None]*276
76  self.__comment = None
77  self.__drawer = [None]*276
78  self.__modmin = modmin
79  self.__modmax = modmax+1
80 
81  #=== try to open db
82  self.__remote = (("http://" in db) or ("https://" in db) or ("CREST" in db))
83  if self.__remote:
84  if 'http' not in self.__db:
85  self.__db = os.getenv(db,os.getenv('CREST_HOST',os.getenv('CREST_SERVER_PATH','http://crest-j23.cern.ch:8080/api-v5.0')))
86  self.log().info('Host %s' , (self.__db))
87  self.__api_instance = CrestApi(host=self.__db)
88  socks = os.getenv('CREST_SOCKS', 'False')
89  if socks == 'True': self.__api_instance.socks()
90  self.__tag = self.getFolderTag(folder,None,tag)
91  if run is not None and lumi is not None:
92  log.info("Initializing for run %d, lumiblock %d", run,lumi)
93  self.__getIov((run,lumi),True)
94  else:
95  self.log().info('File %s' , (self.__db))
96  self.__iovList.append(((MINRUN,MINLBK),(MAXRUN, MAXLBK)))
97  self.__iov = self.__runlumi2iov(self.__iovList[-1])
98  try:
99  with open(self.__db, 'r') as the_file:
100  jdata = json.load(the_file)
101  for chan in range(self.__modmin,self.__modmax):
102  self.__create_drawer(jdata[str(chan)][0],chan)
103  self.__create_comment(jdata['1000'][0])
104  except Exception as e:
105  self.log().critical( e )
106  raise
107 
108  #____________________________________________________________________
109  def getFolderTag(self, folder, prefix, globalTag):
110  if globalTag=='CURRENT' or globalTag=='UPD4' or globalTag=='':
111  globalTag=TileCalibTools.getAliasFromFile('Current')
112  log.info("Resolved CURRENT globalTag to \'%s\'", globalTag)
113  elif globalTag=='CURRENTES' or globalTag=='UPD1':
114  globalTag=TileCalibTools.getAliasFromFile('CurrentES')
115  log.info("Resolved CURRENT ES globalTag to \'%s\'", globalTag)
116  elif globalTag=='NEXT':
117  globalTag=TileCalibTools.getAliasFromFile('Next')
118  log.info("Resolved NEXT globalTag to \'%s\'", globalTag)
119  elif globalTag=='NEXTES':
120  globalTag=TileCalibTools.getAliasFromFile('NextES')
121  log.info("Resolved NEXT ES globalTag to \'%s\'", globalTag)
122  globalTag=globalTag.replace('*','')
123  if prefix is None:
124  prefix = ''
125  for f in folder.split('/'):
126  prefix+=f.capitalize()
127  else:
128  prefix=prefix.strip('-').split('-')[0]
129  if prefix.startswith('Calo'):
130  prefix='CALO'+prefix[4:]
131  if 'UPD1' in globalTag or 'UPD4' in globalTag or 'COND' not in globalTag:
132  if prefix != '':
133  tag=prefix+'-'+globalTag
134  self.log().info("Resolved localTag \'%s\' to folderTag \'%s\'", globalTag,tag)
135  elif folder!='' and not (globalTag.startswith('Tile') or globalTag.startswith('CALO')):
136  tag = TileCalibUtils.getFullTag(folder, globalTag)
137  if tag.startswith('Calo'):
138  tag='CALO'+tag[4:]
139  self.log().info("Resolved localTag \'%s\' to folderTag \'%s\'", globalTag,tag)
140  else:
141  tag=globalTag
142  self.log().info("Use localTag \'%s\' as is", tag)
143  else:
144  tag=None
145  tags=self.__api_instance.find_global_tag_map(globalTag)
146  if tags['size']==0:
147  raise Exception( "globalTag %s not found" % (globalTag) )
148  else:
149  for i in range(tags['size']):
150  t=tags['resources'][i]['tag_name']
151  l=tags['resources'][i]['label']
152  if (prefix!='' and t.startswith(prefix)) or l==folder:
153  tag=t
154  self.log().info("Resolved globalTag \'%s\' to folderTag \'%s\'", globalTag,tag)
155  #taginfo = self.__api_instance.find_tag(name=tag)
156  #print(taginfo)
157  return tag
158 
159  #____________________________________________________________________
160  def getIovs(self,since,until):
161  run_lumi1=str((since[0]<<32)+since[1]+1)
162  run_lumi2=str((until[0]<<32)+until[1]+1)
163  MAXRUNLUMI1=str(MAXRUNLUMI+1)
164  iovs1=self.__api_instance.select_iovs(self.__tag,"0",run_lumi1,sort='id.since:DESC,id.insertionTime:DESC',size=1,snapshot=0)
165  iovs2=self.__api_instance.select_iovs(self.__tag,run_lumi2,MAXRUNLUMI1,sort='id.since:ASC,id.insertionTime:DESC',size=1,snapshot=0)
166  since1=0 if iovs1['size']==0 else iovs1['resources'][0]['since']
167  until1=MAXRUNLUMI if iovs2['size']==0 else iovs2['resources'][0]['since']
168  iovs=self.__api_instance.select_iovs(self.__tag,str(since1),str(until1),sort='id.since:ASC,id.insertionTime:DESC',size=999999,snapshot=0)
169  iovList=[]
170  if iovs['size']==0:
171  raise Exception( "IOV for tag %s IOV [%s,%s] - (%s,%s) not found" % (self.__tag,since[0],since[1],until[0],until[1]) )
172  else:
173  for i in range(iovs['size']):
174  iov=iovs['resources'][i]
175  runS=iov['since']>>32
176  lumiS=iov['since']&0xFFFFFFFF
177  iovList.append((runS,lumiS))
178  return iovList
179 
180  #____________________________________________________________________
181  def __getIov(self,runlumi,dbg=False):
182  run_lumi1=str((runlumi[0]<<32)+runlumi[1]+1)
183  MAXRUNLUMI1=str(MAXRUNLUMI+1)
184  iovs1=self.__api_instance.select_iovs(self.__tag,"0",run_lumi1,sort='id.since:DESC,id.insertionTime:DESC',size=1,snapshot=0)
185  iovs2=self.__api_instance.select_iovs(self.__tag,run_lumi1,MAXRUNLUMI1,sort='id.since:ASC,id.insertionTime:DESC',size=1,snapshot=0)
186  if iovs1['size']==0:
187  raise Exception( "IOV for tag %s run,lumi (%s,%s) not found" % (self.__tag,runlumi[0],runlumi[1]) )
188  else:
189  iov=iovs1['resources'][0]
190  since=iov['since']
191  runS=since>>32
192  lumiS=since&0xFFFFFFFF
193  until=MAXRUNLUMI if iovs2['size']==0 else iovs2['resources'][0]['since']
194  runU=until>>32
195  lumiU=until&0xFFFFFFFF
196  hash=iov['payload_hash']
197  if dbg:
198  #self.log().info('Run,Lumi (%d,%d)' , runlumi)
199  self.log().info('IOV [%d,%d] - (%d,%d)' , runS,lumiS,runU,lumiU)
200  self.log().info('Insertion time %s' , iov['insertion_time'])
201  self.log().info('Hash %s' , hash)
202  payload = self.__api_instance.get_payload(hash=hash).decode('utf-8')
203  jdata=json.loads(payload)
204  #with open("payload.json", 'w') as the_file:
205  # the_file.write(payload)
206  # the_file.write('\n')
207  #with open("dump.json", 'w') as the_file:
208  # json.dump(jdata,the_file)
209  # the_file.write('\n')
210  self.__iovList.append(((runS,lumiS),(runU, lumiU)))
211  self.__iov = self.__runlumi2iov(self.__iovList[-1])
212  for chan in range(self.__modmin,self.__modmax):
213  try:
214  blob=jdata[str(chan)][0]
215  except Exception:
216  blob=None
217  self.__create_drawer(blob,chan)
218  try:
219  blob=jdata['1000'][0]
220  except Exception:
221  blob=None
222  self.__create_comment(blob)
223  return
224 
225  #____________________________________________________________________
226  def __runlumi2iov(self,runlumi):
227  since = (runlumi[0][0]<<32) + runlumi[0][1]
228  until = (runlumi[1][0]<<32) + runlumi[1][1]
229  return (since,until)
230 
231  #____________________________________________________________________
232  def __checkIov(self,runlumi):
233  point = (runlumi[0]<<32) + runlumi[1]
234  inrange = point>=self.__iov[0] and point<self.__iov[1]
235  return inrange
236 
237  #____________________________________________________________________
238  def __make_blob(self,string):
239  b = Blob()
240  b.write(string)
241  b.seek(0)
242  return b
243 
244  #____________________________________________________________________
245  def __create_comment(self,b64string):
246  if b64string is None or len(b64string)==0:
247  self.__commentBlob = None
248  self.__comment = None
249  else:
250  blob1 = base64.decodebytes(bytes(b64string,'ascii'))
251  self.__commentBlob = self.__make_blob(blob1)
253  return
254 
255  #____________________________________________________________________
256  def __create_drawer(self,b64string,chan):
257  if b64string is None or len(b64string)==0:
258  self.__drawerBlob[chan] = None
259  self.__drawer[chan] = None
260  return
261  blob1 = base64.decodebytes(bytes(b64string,'ascii'))
262  self.__drawerBlob[chan] = self.__make_blob(blob1)
264  typeName = TileCalibType.getClassName(cmt.getObjType())
265  del cmt
266  #=== create calibDrawer depending on type
267  if typeName=='TileCalibDrawerFlt':
268  self.__drawer[chan] = TileCalibDrawerFlt.getInstance(self.__drawerBlob[chan])
269  self.log().debug( "typeName = Flt " )
270  elif typeName=='TileCalibDrawerInt':
271  self.__drawer[chan] = TileCalibDrawerInt.getInstance(self.__drawerBlob[chan])
272  self.log().debug( "typeName = Int " )
273  elif typeName=='TileCalibDrawerBch':
274  self.__drawer[chan] = TileCalibDrawerBch.getInstance(self.__drawerBlob[chan])
275  self.log().debug( "typeName = Bch " )
276  elif typeName=='TileCalibDrawerOfc':
277  self.__drawer[chan] = TileCalibDrawerOfc.getInstance(self.__drawerBlob[chan])
278  self.log().debug( "typeName = Ofc " )
279  else:
280  raise Exception( "Invalid blob type requested: %s" % typeName )
281  return
282 
283  #____________________________________________________________________
284  def getDrawer(self,ros, mod, runlumi=None, dbg=False, useDefault=True):
285 
286  if self.__remote and runlumi is not None and not self.__checkIov(runlumi):
287  self.__getIov(runlumi,dbg)
288 
289  if ros<0:
290  chanNum = mod
291  else:
292  chanNum = TileCalibUtils.getDrawerIdx(ros,mod)
293 
294  if (chanNum>=0 and chanNum<len(self.__drawer)):
295  drawer=self.__drawer[chanNum]
296  if not useDefault and drawer is None:
297  return 0
298  while drawer is None:
299  #=== no default at all?
300  if ros==0 and drawer==0:
301  raise Exception('No default available')
302  #=== follow default policy
303  ros,drawer = self.getDefault(ros,drawer)
304  chanNum = TileCalibUtils.getDrawerIdx(ros,drawer)
305  drawer=self.__drawer[chanNum]
306  return drawer
307  elif (chanNum == 1000):
308  return self.__comment
309  else:
310  raise Exception( "Invalid drawer requested: %s %s" % (ros,mod) )
311 
312  #____________________________________________________________________
313  def getComment(self,runlumi=None):
314 
315  if self.__remote and runlumi is not None and not self.__checkIov(runlumi):
316  self.__getIov(runlumi)
317  if self.__comment is not None:
318  return self.__comment.getFullComment()
319  else:
320  return "<no comment found>"
321 
322  #____________________________________________________________________
323  def getDefault(self, ros, drawer):
324  """
325  Returns a default drawer number (among first 20 COOL channels) for any drawer in any partition
326  """
327  if ros==0:
328  if drawer<=4 or drawer==12 or drawer>=20:
329  drawer1=0
330  elif drawer<12:
331  drawer1=4
332  else:
333  drawer1=12
334  elif ros==1 or ros==2:
335  drawer1=4
336  elif ros==3:
337  OffsetEBA = [ 0, 0, 0, 0, 0, 0, 3, 2, #// Merged E+1: EBA07; Outer MBTS: EBA08
338  0, 0, 0, 0, 7, 6, 5, 7, #// D+4: EBA13, EBA16; Special D+4: EBA14; Special D+40: EBA15
339  7, 6, 6, 7, 0, 0, 0, 2, #// D+4: EBA17, EBA20; Special D+4: EBA18, EBA19; Outer MBTS: EBA24
340  3, 0, 0, 0, 0, 0, 0, 0, #// Merged E+1: EBA25
341  0, 0, 0, 0, 0, 0, 1, 1, #// Inner MBTS + special C+10: EBA39, EBA40
342  1, 1, 2, 3, 0, 0, 0, 0, #// Inner MBTS + special C+10: EBA41, EBA42; Outer MBTS: EBA43; Merged E+1: EBA44
343  0, 0, 0, 0, 3, 2, 1, 1, #// Merged E+1: EBA53; Outer MBTS: EBA54; Inner MBTS + special C+10: EBA55, EBA56
344  1, 1, 0, 0, 0, 0, 0, 0] #// Inner MBTS + special C+10: EBA57, EBA58
345  drawer1 = 12 + OffsetEBA[drawer]
346  elif ros==4:
347  OffsetEBC = [ 0, 0, 0, 0, 0, 0, 3, 2, #// Merged E-1: EBC07; Outer MBTS: EBC08
348  0, 0, 0, 0, 7, 6, 6, 7, # // D-4: EBC13, EBC16; Special D-4: EBC14, EBC15;
349  7, 5, 6, 7, 0, 0, 0, 2, #// D-4: EBC17, EBC20; Special D-40 EBC18; Special D-4: EBC19; Outer MBTS: EBC24
350  3, 0, 0, 3, 4, 0, 3, 4, #// Merged E-1: EBC25, EBC28, EBC31; E-4': EBC29, EBC32
351  0, 4, 3, 0, 4, 3, 1, 1, #// E-4': EBC34, EBC37; Merged E-1: EBC35, EBC38; Inner MBTS + special C-10: EBC39, EBC40
352  1, 1, 2, 3, 0, 0, 0, 0, #// Inner MBTS + special C-10: EBC41, EBC42; Outer MBTS: EBC43; Merged E-1: EBC44
353  0, 0, 0, 0, 3, 2, 1, 1, #// Merged E-1: EBC53; Outer MBTS: EBC54; Inner MBTS + special C-10: EBC55, EBC56
354  1, 1, 0, 0, 0, 0, 0, 0] #// Inner MBTS + special C-10: EBC57, EBC58
355  drawer1 = 12 + OffsetEBC[drawer]
356  else:
357  drawer1=0
358 
359  return (0,drawer1)
grepfile.info
info
Definition: grepfile.py:38
AtlasMcWeight::decode
double decode(number_type binnedWeight)
Convert weight from unsigned to double.
Definition: AtlasMcWeight.cxx:32
python.TileCalibCrest.TileBlobReaderCrest.__checkIov
def __checkIov(self, runlumi)
Definition: TileCalibCrest.py:232
TileCalibDrawerBch::getInstance
static const TileCalibDrawerBch * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerBch.
Definition: TileCalibDrawerBch.cxx:28
python.TileCalibCrest.TileBlobReaderCrest.getDefault
def getDefault(self, ros, drawer)
Definition: TileCalibCrest.py:323
TileCalibType::getClassName
static std::string getClassName(TileCalibType::TYPE type)
Returns the class name.
Definition: TileCalibType.cxx:10
python.TileCalibCrest.TileBlobReaderCrest.getComment
def getComment(self, runlumi=None)
Definition: TileCalibCrest.py:313
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.TileCalibCrest.TileBlobReaderCrest.__iovList
__iovList
Definition: TileCalibCrest.py:72
python.TileCalibCrest.TileBlobReaderCrest.__db
__db
Definition: TileCalibCrest.py:68
python.TileCalibCrest.TileBlobReaderCrest.__tag
__tag
Definition: TileCalibCrest.py:70
TileCalibDrawerInt::getInstance
static const TileCalibDrawerInt * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerBch.
Definition: TileCalibDrawerInt.cxx:27
TileCalibDrawerFlt::getInstance
static const TileCalibDrawerFlt * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerFlt.
Definition: TileCalibDrawerFlt.cxx:13
python.TileCalibCrest.TileBlobReaderCrest.__comment
__comment
Definition: TileCalibCrest.py:76
python.TileCalibCrest.TileBlobReaderCrest.__drawerBlob
__drawerBlob
Definition: TileCalibCrest.py:75
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.TileCalibCrest.TileBlobReaderCrest.__modmin
__modmin
Definition: TileCalibCrest.py:78
python.TileCalibCrest.TileBlobReaderCrest.__create_comment
def __create_comment(self, b64string)
Definition: TileCalibCrest.py:245
python.TileCalibCrest.TileBlobReaderCrest.__drawer
__drawer
Definition: TileCalibCrest.py:77
python.TileCalibCrest.TileBlobReaderCrest.__modmax
__modmax
Definition: TileCalibCrest.py:79
python.TileCalibCrest.TileBlobReaderCrest.__getIov
def __getIov(self, runlumi, dbg=False)
Definition: TileCalibCrest.py:181
python.TileCalibCrest.TileBlobReaderCrest.getIovs
def getIovs(self, since, until)
Definition: TileCalibCrest.py:160
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
python.TileCalibCrest.TileBlobReaderCrest.__iov
__iov
Definition: TileCalibCrest.py:73
python.TileCalibCrest.TileBlobReaderCrest.__commentBlob
__commentBlob
Definition: TileCalibCrest.py:74
python.TileCalibCrest.TileBlobReaderCrest.__api_instance
__api_instance
Definition: TileCalibCrest.py:87
python.TileCalibCrest.TileBlobReaderCrest.__init__
def __init__(self, db, folder='', tag='', run=None, lumi=0, modmin=0, modmax=275)
Definition: TileCalibCrest.py:54
python.TileCalibCrest.TileBlobReaderCrest.__runlumi2iov
def __runlumi2iov(self, runlumi)
Definition: TileCalibCrest.py:226
Trk::open
@ open
Definition: BinningType.h:40
python.TileCalibCrest.TileBlobReaderCrest.__remote
__remote
Definition: TileCalibCrest.py:82
python.TileCalibCrest.TileBlobReaderCrest.__make_blob
def __make_blob(self, string)
Definition: TileCalibCrest.py:238
TileCalibDrawerOfc::getInstance
static TileCalibDrawerOfc * getInstance(coral::Blob &blob, uint16_t objVersion, uint32_t nSamples, int32_t nPhases, uint16_t nChans, uint16_t nGains, const std::string &author="", const std::string &comment="", uint64_t timeStamp=0)
Returns a pointer to a non-const TileCalibDrawerOfc.
Definition: TileCalibDrawerOfc.cxx:14
python.TileCalibCrest.TileBlobReaderCrest.getDrawer
def getDrawer(self, ros, mod, runlumi=None, dbg=False, useDefault=True)
Definition: TileCalibCrest.py:284
TileCalibDrawerCmt::getInstance
static const TileCalibDrawerCmt * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerCmt.
Definition: TileCalibDrawerCmt.cxx:24
python.TileCalibCrest.TileBlobReaderCrest.__folder
__folder
Definition: TileCalibCrest.py:69
python.TileCalibCrest.Blob
Blob
Definition: TileCalibCrest.py:15
str
Definition: BTagTrackIpAccessor.cxx:11
TileCalibUtils::getDrawerIdx
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
Definition: TileCalibUtils.cxx:60
python.TileCalibCrest.TileBlobReaderCrest.__create_drawer
def __create_drawer(self, b64string, chan)
Definition: TileCalibCrest.py:256
python.TileCalibCrest.TileBlobReaderCrest
Definition: TileCalibCrest.py:47
python.TileCalibCrest.TileBlobReaderCrest.getFolderTag
def getFolderTag(self, folder, prefix, globalTag)
Definition: TileCalibCrest.py:109
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
python.CaloCondLogger.getLogger
def getLogger(name="CaloCond")
Definition: CaloCondLogger.py:16
TileCalibUtils::getFullTag
static std::string getFullTag(const std::string &folder, const std::string &tag)
Returns the full tag string, composed of camelized folder name and tag part.
Definition: TileCalibUtils.cxx:33