ATLAS Offline Software
MagFieldUtils.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4 # MagFieldUtils.py
5 # Routines to read magnetic field information from COOL
6 # Richard Hawkings 25/9/08
7 
8 
9 from PyCool import cool
10 from CoolConvUtilities.AtlCoolLib import indirectOpen
11 
12 #Cache per run/LB (avoid multiple DB lookup)
13 _timeForLB=dict()
14 _fieldForLB=dict()
15 
17  "Wrapper class to hold magnetic field current info from DCS data and the filename tag for the SOR"
18  def __init__(self,solC,solSetC,torC,torSetC,fnt):
19  "Initialise given values for solenoid & toroid acual and set currents and filename tag"
20  self._solC=solC
21  self._solSetC=solSetC
22  self._torC=torC
23  self._torSetC=torSetC
24  self._fileNameTag=fnt
25 
26  def solenoidCurrent(self):
27  "Return the solenoid current"
28  return self._solC
29 
30  def solenoidSetCurrent(self):
31  "Return the requested solenoid current (set point)"
32  return self._solSetC
33 
34  def toroidCurrent(self):
35  "Return the toroid current"
36  return self._torC
37 
38  def toroidSetCurrent(self):
39  "Return the requested toroid current (set point)"
40  return self._torSetC
41 
42  def fileNameTag(self):
43  "Return the Filename tag for this run"
44  return self._fileNameTag
45 
46 
47 def getFieldForRun(run,quiet=False,lumiblock=None):
48  "Get the magnetic field currents (MagFieldDCSInfo) for a given run"
49  # access the TDAQ schema to translate run number into timestamp
50  # and get the filename tag
51 
52  runiov=(run << 32)+(lumiblock or 0)
53  if runiov in _fieldForLB:
54  return _fieldForLB[runiov]
55 
56  newdb=(run>=236107)
57  if not quiet:
58  print ("Reading magnetic field for run %i, CONDBR2 %s" % (run,newdb))
59  # setup appropriate connection and folder parameters
60  if newdb:
61  dbname='CONDBR2'
62  sorfolder='/TDAQ/RunCtrl/SOR'
63  fntname='T0ProjectTag'
64  else:
65  dbname='COMP200'
66  sorfolder='/TDAQ/RunCtrl/SOR_Params'
67  fntname='FilenameTag'
68 
69  tdaqDB=indirectOpen('COOLONL_TDAQ/%s' % dbname)
70  if (tdaqDB is None):
71  print ("MagFieldUtils.getFieldForRun ERROR: Cannot connect to COOLONL_TDAQ/%s" % dbname)
72  return None
73  sortime=0
74  try:
75  tdaqfolder=tdaqDB.getFolder(sorfolder)
76  runiov=run << 32
77  obj=tdaqfolder.findObject(runiov,0)
78  payload=obj.payload()
79  sortime=payload['SORTime']
80  fnt=payload[fntname]
81  except Exception as e:
82  print ("MagFieldUtils.getFieldForRun ERROR accessing folder %s" % sorfolder)
83  print (e)
84  tdaqDB.closeDatabase()
85 
86  # if lumiblock is specifed, actually want the start time of the LB
87  if lumiblock is not None:
88  if not quiet:
89  print ("Reading specific timestamp for lumiblock %i" % lumiblock)
90 
91  lbtime=getTimeForLB(run,lumiblock)
92  if (lbtime==0 and lumiblock>1):
93  # sometimes fails as last LB is missing in LBLB - try previous
94  print ("MagFieldUtils.getFieldForRun WARNING: Cannot find LB %i, trying %i" % (lumiblock,lumiblock-1))
95  lbtime=getTimeForLB(run,lumiblock-1)
96  if (lbtime==0):
97  print ("MagFieldUtils.getFieldForRun WARNING: Cannot find LB %i, fall back on SOR time" % lumiblock)
98  if (lbtime>0):
99  # use this time instead of SORtime
100  if not quiet:
101  print ("Lumiblock starts %i seconds from start of run" % int((lbtime-sortime)/1.E9))
102  sortime=lbtime
103  else:
104  print ("MagFieldUtils.getFieldForRun ERROR accessing /TRIGGER/LUMI/LBLB")
105  print ("Fall back on SOR time from %s" % sorfolder)
106  lbtime=sortime
107 
108  # if we do not have a valid time, exit
109  if (sortime==0): return None
110 
111  # now having got the start of run timestamp, lookup the field info in DCS
112  dcsDB=indirectOpen('COOLOFL_DCS/%s' % dbname)
113  if (dcsDB is None):
114  print ("MagFieldUtils.getFieldForRun ERROR: Cannot connect to COOLOFL_DCS/%s" % dbname)
115  return None
116  data=None
117  try:
118  # map of expected channel names to slots in data[] variable
119  # follows original order from run1/COMP200
120  # has changed in CONDBR2, but use of named channels recovers this
121  currentmap={'CentralSol_Current':0,'CentralSol_SCurrent':1,
122  'Toroids_Current':2,'Toroids_SCurrent':3}
123  dcsfolder=dcsDB.getFolder('/EXT/DCS/MAGNETS/SENSORDATA')
124  objs=dcsfolder.findObjects(sortime,cool.ChannelSelection.all())
125  data=[-1.,-1.,-1.,-1.]
126  for obj in objs:
127  chan=obj.channelId()
128  channame=dcsfolder.channelName(chan)
129  if channame in currentmap.keys():
130  data[currentmap[channame]]=obj.payload()['value']
131  except Exception as e:
132  print ("MagFieldUtils.getFieldForRun ERROR accessing /EXT/DCS/MAGNETS/SENSORDATA")
133  print (e)
134  dcsDB.closeDatabase()
135  # if problem accessing folder, exit
136  if data is None:
137  return None
138  # return a MagFIeldDCSInfo object containing the result
139  retval=MagFieldDCSInfo(data[0],data[1],data[2],data[3],fnt)
140  _fieldForLB[runiov]=retval
141  return retval
142 
143 def getTimeForLB(run,LB):
144  "Return the time a specific run/LB, given the folder, or 0 for bad/no data"
145  if LB is None:
146  LB=0
147 
148  runiov=(run << 32)+LB
149 
150  if runiov in _timeForLB:
151  print ("getTimeForLB: Returning cached time for run %i, LumiBlock %i " % (run,LB))
152  return _timeForLB[runiov]
153 
154  if (run>=236107):
155  dbname="CONDBR2"
156  else:
157  dbname="COMP200"
158 
159  #print ("Querying DB for time of run %i LB %i" % (run,LB))
160 
161  try:
162  trigDB=indirectOpen('COOLONL_TRIGGER/%s' % dbname)
163  if (trigDB is None):
164  print ("MagFieldUtils.getTimeForLB ERROR: Cannot connect to COOLONL_TDAQ/%s" % dbname)
165  return 0
166 
167  lblbfolder=trigDB.getFolder('/TRIGGER/LUMI/LBLB')
168  obj=lblbfolder.findObject(runiov,0)
169  payload=obj.payload()
170  lbtime=payload['StartTime']
171  _timeForLB[runiov]=lbtime
172  trigDB.closeDatabase()
173  return lbtime
174  except Exception as e:
175  print ("MagFieldUtils.getTimeForLB WARNING: accessing /TRIGGER/LUMI/LBLB for run %i, LB %i" % (run,LB))
176  print (e)
177  return 0
178 
179 
180 # command line driver for convenience
181 if __name__=='__main__':
182  import sys
183  if len(sys.argv)<2:
184  print ("Syntax",sys.argv[0],'<run>')
185  sys.exit(-1)
186  run=int(sys.argv[1])
187  lumiblock=None
188  if len(sys.argv)>2:
189  lumiblock=int(sys.argv[2])
190  magfield=getFieldForRun(run,lumiblock=lumiblock)
191  print ("Magnetic field information for run %i" % run)
192  if (magfield is not None):
193  print ("Solenoid current %8.2f (requested %8.2f)" % (magfield.solenoidCurrent(),magfield.solenoidSetCurrent()))
194  print ("Toroid current %8.2f (requested %8.2f)" % (magfield.toroidCurrent(),magfield.toroidSetCurrent()))
195  print ("Filename Tag: %s" % (magfield.fileNameTag()))
196  else:
197  print ("Not available")
python.MagFieldUtils.getFieldForRun
def getFieldForRun(run, quiet=False, lumiblock=None)
Definition: MagFieldUtils.py:47
python.MagFieldUtils.MagFieldDCSInfo._torC
_torC
Definition: MagFieldUtils.py:22
python.MagFieldUtils.MagFieldDCSInfo
Definition: MagFieldUtils.py:16
python.MagFieldUtils.MagFieldDCSInfo._solC
_solC
Definition: MagFieldUtils.py:20
python.MagFieldUtils.MagFieldDCSInfo.__init__
def __init__(self, solC, solSetC, torC, torSetC, fnt)
Definition: MagFieldUtils.py:18
python.MagFieldUtils.MagFieldDCSInfo.fileNameTag
def fileNameTag(self)
Definition: MagFieldUtils.py:42
python.MagFieldUtils.MagFieldDCSInfo._torSetC
_torSetC
Definition: MagFieldUtils.py:23
python.MagFieldUtils.MagFieldDCSInfo.solenoidCurrent
def solenoidCurrent(self)
Definition: MagFieldUtils.py:26
python.MagFieldUtils.MagFieldDCSInfo._solSetC
_solSetC
Definition: MagFieldUtils.py:21
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
python.MagFieldUtils.MagFieldDCSInfo._fileNameTag
_fileNameTag
Definition: MagFieldUtils.py:24
python.MagFieldUtils.MagFieldDCSInfo.solenoidSetCurrent
def solenoidSetCurrent(self)
Definition: MagFieldUtils.py:30
python.MagFieldUtils.MagFieldDCSInfo.toroidSetCurrent
def toroidSetCurrent(self)
Definition: MagFieldUtils.py:38
python.MagFieldUtils.getTimeForLB
def getTimeForLB(run, LB)
Definition: MagFieldUtils.py:143
python.AtlCoolLib.indirectOpen
def indirectOpen(coolstr, readOnly=True, debug=False)
Definition: AtlCoolLib.py:129
python.MagFieldUtils.MagFieldDCSInfo.toroidCurrent
def toroidCurrent(self)
Definition: MagFieldUtils.py:34