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