3
from xml.sax import parseString
4
from xml.sax.handler import ContentHandler
6
from cdb._base import _CdbBase
7
from cdb._base import _get_string_from_date
8
from cdb._exceptions import CdbPermanentError
9
from cdb._exceptions import CdbTemporaryError
12
__all__ = ["Calibration"]
15
class Calibration(_CdbBase):
18
The Calibration class is used to retrieve calibration data.
20
For the detectors and trackers data is described by its location with reference
21
to to bank, board and channel. Old versions of the data are stored for
22
diagnostic purposes. Data can be retrieved for a given time using
23
get_calibration_for_date and for a given run using get_calibration_for_run.
28
def __init__(self, wsdl_dir="/cdb/calibration?wsdl"):
30
Construct a Calibration.
32
@param wsdl_dir: the path to the wsdl on the server. The default is
33
"/cdb/calibration?wsdl".
35
@exception CdbPermanentError: Unable to contact CDB server or invalid URL
38
super(Calibration, self).__init__(wsdl_dir)
39
self._calibration_handler = _CalibrationHandler()
43
\n\tset_url(string url) \
45
\n\tget_calibration_for_date(string device, datetime timestamp) \
46
\n\tget_calibration_for_run(string device, int run_number) \
47
\n\tget_current_calibration(string device) \
50
def set_url(self, url):
52
Set the client to use the given CDB server.
54
@param url: the URL of the CDB wsdl
56
@exception CdbTemporaryError: Unable to contact CDB server
57
@exception CdbPermanentError: Invalid URL
60
super(Calibration, self).set_url(url)
64
Get the status of the service.
66
@return a string containing the status of the service
68
@exception CdbTemporaryError: The problem maybe transient and retrying the
70
@exception CdbPermanentError: An unexpected internal error
73
return super(Calibration, self).get_status()
75
def get_calibration_for_date(self, device, timestamp):
77
Get the calibration data of the given device, where the name of the device may be
78
that of a detector or tracker, that was valid at the given timestamp.
80
@param device: a string containing the name of the detector or tracker
81
@param timestamp: a datetime in UTC
83
@return a list of dictionaries
85
@exception CdbTemporaryError: The problem maybe transient and retrying the
87
@exception CdbPermanentError: Maybe due to to bad data being passed in or an
88
unexpected internal error
91
timestamp = _get_string_from_date(timestamp)
92
xml = str(self._client.getCalibrationForDate(str(device), timestamp))
93
return self._parse_calibration_xml(xml)
95
def get_calibration_for_run(self, device, run_number):
97
Get the calibration data of the given device, where the name of the device may be
98
that of a detector or tracker, that was valid for the given run number.
100
@param device: a string containing the name of the detector or tracker
101
@param run_number: a long containing the number of a run
103
@return a list of dictionaries
105
@exception CdbTemporaryError: The problem maybe transient and retrying the
107
@exception CdbPermanentError: Maybe due to to bad data being passed in or an
108
unexpected internal error
111
xml = str(self._client.getCalibrationForRun(device, run_number))
112
return self._parse_calibration_xml(xml)
114
def get_current_calibration(self, device):
116
Get the calibration data of the given device, where the name of the device may be
117
that of a detector or tracker.
119
@param device: a string containing the name of the detector or tracker
121
@return a list of dictionaries
123
@exception CdbTemporaryError: The problem maybe transient and retrying the
125
@exception CdbPermanentError: Maybe due to to bad data being passed in or an
126
unexpected internal error
129
xml = str(self._client.getCurrentCalibration(device))
130
return self._parse_calibration_xml(xml)
132
def list_devices(self):
134
Get a list of known devices. These are the device names that are recognised by this API.
136
@return a list of device names
138
@exception CdbTemporaryError: The problem maybe transient and retrying the
140
@exception CdbPermanentError: Maybe due to to bad data being passed in or an
141
unexpected internal error
144
xml = str(self._client.listDevices())
145
return self._parse_calibration_xml(xml)
148
def _parse_calibration_xml(self, xml):
149
""" Parser for calibration data. """
150
parseString(xml, self._calibration_handler)
151
return self._calibration_handler.get_data()
154
class _CalibrationHandler(ContentHandler):
156
" ContentHandler for calibration data. "
159
ContentHandler.__init__(self)
160
self._device_type = ""
168
Get a list containing the parsed xml.
170
@return the list containing the parsed xml
175
def startElement(self, name, attrs): #pylint: disable-msg=C0103
176
""" Method required for ContentHandler. """
179
elif name == 'warning':
181
elif name == 'calibration':
183
self._device_type = str(attrs.get('type', ""))
184
elif name == 'device':
185
self._data.append(str(attrs.get('name', "")))
186
elif name == 'board':
187
self._board = int(attrs.get('number', ""))
189
self._bank = int(attrs.get('number', ""))
190
elif name == 'channel':
191
if self._device_type == "TRACKER":
192
self._add_tracker(attrs)
195
def characters(self, message):
196
""" Method required for ContentHandler. """
197
self._message = self._message + message
199
def endElement(self, name): #pylint: disable-msg=C0103
200
""" Method required for ContentHandler. """
202
raise CdbPermanentError(self._message)
203
elif name == 'warning':
204
raise CdbTemporaryError(self._message)
206
def _add_tracker(self, attrs):
207
""" Populate a dictionary with data from the xml. """
209
_cable_data["bank"] = self._board
210
_cable_data["board"] = self._bank
211
_cable_data["channel"] = int(attrs.get('number', ""))
212
_cable_data["adc_pedestal"] = int(attrs.get('adcPedestal', ""))
213
_cable_data["adc_gain"] = int(attrs.get('adcGain', ""))
214
_cable_data["tdc_pedestal"] = int(attrs.get('tdcPedestal', ""))
215
_cable_data["tdc_gain"] = int(attrs.get('tdcGain', ""))
216
self._data.append(_cable_data)
219
""" Reset self values. """
220
self._device_type = ""