ATLAS Offline Software
Loading...
Searching...
No Matches
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
9from PyCool import cool
10from 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
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
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
47def 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
143def 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
181if __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")
__init__(self, solC, solSetC, torC, torSetC, fnt)
getFieldForRun(run, quiet=False, lumiblock=None)