]>
Commit | Line | Data |
---|---|---|
73abe331 | 1 | \documentclass[a4paper]{report} |
2 | ||
3 | \usepackage{graphicx} | |
4 | ||
5 | \begin{document} | |
6 | ||
7 | \title{\Huge Shuttle\\\normalsize Program for automatic data retrieval from DCS} | |
8 | ||
9 | \maketitle | |
10 | ||
11 | \tableofcontents | |
12 | ||
13 | \listoftables | |
14 | ||
15 | \listoffigures | |
16 | ||
17 | \sloppy | |
18 | ||
19 | \chapter{Shuttle - Program for automatic data retrieval from DCS} | |
20 | ||
21 | \section{Overview} | |
22 | \label{sec:Shuttle:Overview} | |
23 | ||
24 | In DCS data base is stored information for particular real world object (RWO) | |
25 | (sensors, valves etc.) as temperature, voltage, state etc. PVSS II is a SCADA | |
26 | (Supervisory Control and Data Acquisition) system used by DCS for control, monitoring | |
27 | and data acquisition. The abstract representation of any RWO is organized in | |
28 | DataPoints (DP). Every DP has particular type which can be a composite (tree-like) structure | |
29 | or primitive type as boolean, byte, integer, float. DP data is updated with certain refresh | |
30 | rate (usally less than 1Hz) forming a time series. As the data points which represent | |
31 | particular RWO are changed in time, additional attribute called 'alias' is assigned to them. | |
32 | Every alias corresponds to the same RWO all the time. | |
33 | ||
34 | When the value of some DP is changed, the new value and the timestamp is stored into the | |
35 | data base. These value/timestamp pairs form the value series for particular DP. As DCS | |
36 | data is collected independently on the experimental runs, part of the value series | |
37 | corresponds to time intervals which don't belong to any run. | |
38 | ||
39 | Every sub-detector has a set of 'aliases' which represent some parameters (temperature, | |
40 | pressure, voltage etc.) relevant to its calibration. The working schema of | |
41 | \emph{Shuttle} program is: collecting the data from DCS using AliDCSClient interface, | |
42 | running the appropriate sub-detector preprocessor (one per sub-detector, used for preliminary | |
43 | processing of the collected data) and storing the output of the preprocessor into the | |
44 | calibration data base. | |
45 | ||
46 | \section{General schema} | |
47 | ||
48 | \begin{figure} | |
49 | \begin{center} | |
50 | \includegraphics[width=0.9\textwidth]{pics/ShuttleSchema} | |
51 | \end{center} | |
52 | \caption{\emph{Shuttle} program general schema.} | |
53 | \label{shuttle:schema} | |
54 | \end{figure} | |
55 | ||
56 | On figure \ref{shuttle:schema} is presented the \emph{Shuttle} program general schema: | |
57 | \footnote{ | |
58 | All names which follow the pattern Ali$<$name$>$ are classes part of | |
59 | AliRoot framework. | |
60 | } | |
61 | ||
62 | \begin{description} | |
63 | \item[AliShuttle] The \emph{Shuttle} program manager, holds one AliShuttleConfig and | |
64 | one AliCDBStorage object instances. It is used to manage data retrieval from DCS | |
65 | \mbox{(through AliDCSClient)} and preliminary data processing. | |
66 | ||
67 | \item[AliShuttleConfig] Reads the configuration from LDAP server. | |
68 | ||
69 | \item[AliCDBPreProcessor] The interface for every sub-detector preprocessor. | |
70 | ||
71 | \item[AliCDBStorage] Interface to the calibration data base. Currently supports | |
72 | GRID and Local storage. | |
73 | ||
74 | \item[AliShuttleTrigger] Waits for notification from DAQ when particular | |
75 | experimental run is finished and runs AliShuttle. | |
76 | ||
77 | \item[AliDCSClient] Makes connection to AMANDA and communicates over AliDCSProtocol. | |
78 | ||
79 | \item[AMANDA]\footnote { | |
80 | AMANDA is an abbreviation of Ali MANager for Data Access. | |
81 | } | |
82 | Communication layer for data access to the historical data base | |
83 | provided by DCS. Implements AliDCSProtocol. Communicates with PVSS DM through | |
84 | the internal PVSS protocol. | |
85 | \item[PVSS DM] It's a data manager, part of PVSS SCADA system used to organize the | |
86 | interaction with the underlying data base (RDBMS, local files etc.). | |
87 | ||
88 | \end{description} | |
89 | ||
90 | \section{AliShuttle and AliCDBPreProcessor} | |
91 | \label{sec:shuttle:preprocessor} | |
92 | ||
93 | AliShuttle is the \emph{Shuttle} program manager, holds one AliShuttleConfig and | |
94 | one AliCDBStorage object instances. It is used to manage data retrieval from DCS | |
95 | \mbox{(through AliDCSClient)} and preliminary data processing. Only those sub-detectors | |
96 | for which there is a valid configuration are processed by AliShuttle. | |
97 | Two methods are used for triggering data retrieval and preprocessing: | |
98 | \begin{description} | |
99 | \item \mbox{void Process(Int\_t run, UInt\_t startTime, UInt\_t endTime)}\\ | |
100 | Retrieves data for particular run which lasted in time interval | |
101 | \mbox{startTime - endTime} for every sub-detector in the configuration. | |
102 | ||
103 | \item \mbox{void Process(Int\_t run, UInt\_t startTime, UInt\_t endTime, | |
104 | const char* detector)}\\ | |
105 | Retrieves data for particular run which lasted in time interval | |
106 | \mbox{startTime - endTime} for the specified detector. | |
107 | \end{description} | |
108 | ||
109 | Every subdetector can register to AliShuttle a specific preprocessor which implements | |
110 | \mbox{AliCDBPreProcessor} interface. The aim of this preprocessor is to process | |
111 | (fit, average etc.) the data retrieved from DCS and create and store a specific for | |
112 | the sub-detector needs objects (histograms, functions etc.) which can be used during the | |
113 | calibration process.\\ | |
114 | \mbox{AliCDBPreProcessor} is a subclass of TNamed and GetName() method is used by | |
115 | \mbox{AliShuttle} to identify the sub-detector preprocessor. | |
116 | ||
117 | It has one method which provides storage to the underlying AliCDBStorage object. | |
118 | \begin{description} | |
119 | \item \mbox{Bool\_t Store(const char* specType, TObject* object, | |
120 | AliCDBMetaData* metaData)}\\ | |
121 | Stores \emph{object} with \emph{metaData} and identifier \emph{specType}.\\ | |
122 | Returns kTRUE in case of success and kFALSE otherwise. | |
123 | \end{description} | |
124 | ||
125 | Following callback methods are used. | |
126 | \begin{description} | |
127 | \item \mbox{void Initialize(Int\_t run, UInt\_t startTime, UInt\_t endTime)}\\ | |
128 | This method is called at the beginning of data retrieval for the sub-detector. | |
129 | Parameters \emph{run}, \mbox{\emph{startTime}} and \mbox{\emph{endTime}} | |
130 | specify current experimental run number and the time interval it lasted. | |
131 | \item \mbox{void Finalize()}\\ | |
132 | This method is called at the end of data retrieval for the sub-detector. | |
133 | \item \mbox{void Process(const char* alias, TList\& valueSet, Bool\_t hasError)}\\ | |
134 | This method is called for every \emph{alias} in the relative to the sub-detector | |
135 | set specified in the configuration.\\ | |
136 | \emph{alias} specifies the current alias being processed.\\ | |
137 | \emph{valueSet} is a collection of AliDCSValue (see. AliDCSClient) representing | |
138 | the value series retrieved from DCS.\\ | |
139 | \emph{hasError} is an error flag indicating if some error (comunication error, | |
140 | data base error etc.) occurred during the data retrieval. | |
141 | ||
142 | \end{description} | |
143 | ||
144 | If there is a valid configuration for some sub-detector but there isn't corresponding | |
145 | registered preprocessor, AliShuttle stores \emph{valueSet} to the calibration data base | |
146 | by default. In this case two properties in meta data (AliCDBMetaData), contain the value | |
147 | series time interval ("StartTime" and "EndTime" properties contian StartTime and EndTime | |
148 | respectively stored in AliSimpleValue object). | |
149 | ||
150 | \section{AliShuttleConfig} | |
151 | ||
152 | AliShuttleConfig provides transparent API to the \emph{Shuttle} configuration. Currently, | |
153 | only LDAP is used to keep the configuration. Configuration consists entries (one per | |
154 | sub-detector) which comprise AMANDA server host and port and set of aliases that the specific | |
155 | sub-detector is interested in. | |
156 | ||
157 | \subsection{Configuration schema in LDAP} | |
158 | ||
159 | \begin{figure} | |
160 | \begin{center} | |
161 | \includegraphics[width=0.9\textwidth]{pics/ShuttleConfig} | |
162 | \end{center} | |
163 | \caption{\emph{Shuttle} configuration schema in LDAP.} | |
164 | \label{shuttle:config} | |
165 | \end{figure} | |
166 | ||
167 | On figure \ref{shuttle:config} is presented the LDAP configuration schema. | |
168 | Every leaf (TPC, ITS, PHOS etc.) represents the specific sub-detector configuration. | |
169 | These entries have objectclass \emph{shuttleConfig} which imposes the attributes | |
170 | \emph{ipHost}, \emph{ipServicePort} and \emph{alias} as compulsory. Only \emph{alias} | |
171 | attribute is MULTI-VALUE attribute. All sub-detectors' entries belong to one base entry. | |
172 | \footnote { | |
173 | Default base entry distinguished name is 'dn: dc=alice,dc=cern,dc=ch'. | |
174 | } | |
175 | ||
176 | LDAP access model is used to provide write access to particular sub-detector entry for | |
177 | the relevant supporting group and annonymous read access to the whole configuration. | |
178 | ||
179 | Here is an example of sub-detector entry in ldif format which can be written to LDAP server: | |
180 | ||
181 | \begin{quote} | |
182 | \#ITS config\\ | |
183 | dn: dt=ITS,dc=alice,dc=cern,dc=ch\\ | |
184 | objectClass: shuttleConfig\\ | |
185 | dt: ITS\\ | |
186 | ipHost: 192.168.39.23\\ | |
187 | ipServicePort: 4242\\ | |
188 | alias: HighVol01\\ | |
189 | alias: HighVol02\\ | |
190 | \end{quote} | |
191 | ||
192 | \subsection{Class overview} | |
193 | AliShuttleConfig reads the configuration from LDAP server on the object creation.\\ | |
194 | Following methods are used to access the configuration: | |
195 | \begin{description} | |
196 | \item \mbox{\emph{Bool\_t IsValid() const}}\\ | |
197 | Returns true if the configuration is properly read from LDAP server and false | |
198 | in otherwise. | |
199 | ||
200 | \item \mbox{\emph{const TList* GetDetectors() const}}\\ | |
201 | Returns collection of TObjString objects which represent detectors' name for | |
202 | which there is a valid configuration entry. | |
203 | ||
204 | \item \mbox{\emph{Bool\_t HasDetector(const char* detector) const}}\\ | |
205 | Returns true if there is a valid entry configuration for the specified detector. | |
206 | \item \mbox{\emph{const char* GetHost(const char* detector) const}}\\ | |
207 | Returns AMANDA server host for the specified detector. | |
208 | ||
209 | \item \mbox{\emph{const char* GetHost(const char* detector) const}}\\ | |
210 | Returns AMANDA server port number for the specified detector. | |
211 | ||
212 | \item \mbox{\emph{const TList* GetAliases(const char* detector) const}}\\ | |
213 | Returns collection of TObjString which represents the aliases for the specified | |
214 | detector. | |
215 | ||
216 | \end{description} | |
217 | ||
218 | \chapter{AliDCSClient} | |
219 | ||
220 | \section{Overview} | |
221 | ||
222 | AliDCSClient provides API for historical data access to DCS data base. It's completely | |
223 | based on ROOT framework and there isn't any external libraries. It communicates | |
224 | with AMANDA server using AliDCSProtocol. AliDCSProtocol is a simple protocol which comprises | |
225 | set of messages (AliDCSMessage). Protocol messages are transfered over TCP/IP. | |
226 | ||
227 | The main functionality of AliDCSClient is to provide value series (stored into DCS | |
228 | data base) for paticular \emph{alias}/\emph{DataPoint}\footnote { | |
229 | It was described in \ref{sec:Shuttle:Overview} that every real object is represented | |
230 | by one \emph{DataPoint} at time. As this \emph{DataPoint} can be changed in some | |
231 | moment, additional attribute called \emph{alias} is assigned to it. \emph{Alias} | |
232 | provides constant identifier for the underlying real object. If \emph{DataPoint} | |
233 | is changed its \emph{alias} attribute will be set the same so it will provide a | |
234 | constant association \mbox{\emph{alias}-real object}. | |
235 | } in given time interval. | |
236 | This value series is represented by collection (TList) of AliDCSValue. | |
237 | ||
238 | \section{Basic types and AliDCSValue} | |
239 | ||
240 | Every \emph{alias} which is used in the calibration has particular type. | |
241 | On table \ref{client:types} are listed the whole set of types. There are five primitive | |
242 | types and the corresponding dynamic types (arrays of primitive types with arbitrary number | |
243 | of elements). | |
244 | ||
245 | These types are wrapped by AliSimpleValue. Every instance of this class represents a value | |
246 | which type is one of the described. AliSimpleValue is an ROOT class and it can be | |
247 | serialized by the standard ROOT persistent object mechanism. | |
248 | ||
249 | \emph{Alias} value series is a collection of value/timestamp pairs. Every such pair is | |
250 | realized by AliDCSValue. AliDCSValue has two fields: AliDCSVlaue.value (AliSimpleValue) | |
251 | and AliDCSValue.timestamp (UInt\_t). The following simple rule could be used to understand | |
252 | the meaning of value series: | |
253 | ||
254 | \emph{Every alias has value (AliDCSValue.value) from the moment this value | |
255 | became valid (AliDCSValue.timestamp) to the moment next value becomes valid.} | |
256 | ||
257 | ||
258 | ||
259 | \begin{table} | |
260 | \begin{center} | |
261 | \begin{tabular}{|l|c|} | |
262 | \hline | |
263 | Type & size in bytes\\ | |
264 | \hline | |
265 | Boolean & 1\\ | |
266 | Byte & 1\\ | |
267 | Integer & 4\\ | |
268 | Unsigned Integer & 4\\ | |
269 | Float & 4\\ | |
270 | \hline | |
271 | Dynamic Boolean & n * 1\\ | |
272 | Dynamic Byte & n * 1\\ | |
273 | Dynamic Integer & n * 4\\ | |
274 | Dynamic Unsigned Integer & n * 4\\ | |
275 | Dynamic Float & n * 4 \\ | |
276 | \hline | |
277 | \end{tabular} | |
278 | \end{center} | |
279 | \label{client:types} | |
280 | \caption[Basic types]{ | |
281 | Basic \emph{alias} types. For dynamic types 'n' means the | |
282 | number of the elements. Every dynamic type can have arbitrary | |
283 | number of elements. | |
284 | } | |
285 | \end{table} | |
286 | ||
287 | \section {AliDCSProtocol} | |
288 | ||
289 | AliDCSProtocol is a communication protocol which comprises set of messages (AliDCSMessage). | |
290 | Every message is composed of two parts: \emph{header} and \emph{body}. Message \emph{header} | |
291 | (table \ref{client:protocol:header}) has fixed size and describes message \emph{body} (size | |
292 | and type). | |
293 | ||
294 | There are four message types every one of each has different message \emph{body} structure. | |
295 | Below is a detailed description of every message type: | |
296 | ||
297 | \begin{description} | |
298 | \item[Request] Message sent by the client to make a data request for | |
299 | particular \emph{alias}/\emph{DataPoint} and given time interval (table | |
300 | \ref{client:protocol:body:request}). | |
301 | ||
302 | \item[Count] If precedent request was valid and data could be retrieved from data | |
303 | base, AMANDA server sends this message to indicated the total number of values | |
304 | corresponding to it (table \ref{client:protocol:body:count}). | |
305 | ||
306 | \item[ResultSet] Every such message contains part of the requested data. Server sends | |
307 | series of these messages until it returns the total amount indicated by precedent | |
308 | Count message (table \ref{client:protocol:body:resultset}). | |
309 | ||
310 | \item[Error] Server sends this message if some error occurred. | |
311 | (table \ref{client:protocol:body:error}). | |
312 | ||
313 | \end{description} | |
314 | ||
315 | On figure \ref{client:protocol:flowchart} is shown the protocol flowchart. | |
316 | ||
317 | \begin{table} | |
318 | \begin{center} | |
319 | \begin{tabular}{|c|l|} | |
320 | \hline | |
321 | Byte & Meaning\\ | |
322 | \hline | |
323 | 0 - 1 & Message signature ('A' and 'D').\\ | |
324 | 3 & Message version (ver: 1).\\ | |
325 | 4 & Message type. Describes message \emph{body} type.\\ | |
326 | 5 - 8 & Message \emph{body} size (unsigned interger).\\ | |
327 | \hline | |
328 | \end{tabular} | |
329 | \caption[Message header structure]{Message \emph{header} structure.} | |
330 | \label{client:protocol:header} | |
331 | \end{center} | |
332 | \end{table} | |
333 | ||
334 | \begin{table} | |
335 | \begin{center} | |
336 | \begin{tabular}{|p{1cm}|p{9cm}|} | |
337 | \hline | |
338 | Byte & Meaning\\ | |
339 | \hline | |
340 | 0 & Request identifier (1 = \emph{alias}, 2 = \emph{DataPoint}).\\ | |
341 | 1 - 4 & Request StartTime - Beginning of the requested interval | |
342 | (unsigned integer).\\ | |
343 | 5 - 8 & Request EndTime - End of the requested interval | |
344 | (unsigned integer).\\ | |
345 | 8 - end & Request string - Zero terminated string representing | |
346 | requested \emph{alias}/\emph{DataPoint}.\\ | |
347 | \hline | |
348 | \end{tabular} | |
349 | \caption[Request message structure]{Request message \emph{body} structure.} | |
350 | \label{client:protocol:body:request} | |
351 | \end{center} | |
352 | \end{table} | |
353 | ||
354 | \begin{table} | |
355 | \begin{center} | |
356 | \begin{tabular}{|p{1cm}|p{9cm}|} | |
357 | \hline | |
358 | Byte & Meaning\\ | |
359 | \hline | |
360 | 0 - 3 & Total number of values (unsigned integer).\\ | |
361 | \hline | |
362 | \end{tabular} | |
363 | \caption[Count message structure]{Count message \emph{body} structure.} | |
364 | \label{client:protocol:body:count} | |
365 | \end{center} | |
366 | \end{table} | |
367 | ||
368 | \begin{table} | |
369 | \begin{center} | |
370 | \begin{tabular}{|p{1cm}|p{9cm}|} | |
371 | \hline | |
372 | Byte & Meaning\\ | |
373 | \hline | |
374 | 0 & Value type identifier (On of the basic types on table: | |
375 | \ref{client:types}). | |
376 | Specifies the type of values contained in the message.\\ | |
377 | 1 - 4 & Number of values contained in the message (unsigned integer).\\ | |
378 | 5 - end & Sequence of value/timestamp pairs. Size depends on value type. | |
379 | Timestmap size is always 4 bytes (unsigned integer). \\ | |
380 | \hline | |
381 | \end{tabular} | |
382 | \caption[ResultSet message structure]{ResultSet message \emph{body} structure.} | |
383 | \label{client:protocol:body:resultset} | |
384 | \end{center} | |
385 | \end{table} | |
386 | ||
387 | \begin{table} | |
388 | \begin{center} | |
389 | \begin{tabular}{|p{1cm}|p{9cm}|} | |
390 | \hline | |
391 | Byte & Meaning\\ | |
392 | \hline | |
393 | 0 & Server error code.\\ | |
394 | & (UnknownAlisDPName = 1\\ | |
395 | & InvalidTimeRange = 2\\ | |
396 | & InvalidBufferSize = 3\\ | |
397 | & InvalidRequest = 4\\ | |
398 | & UnsupportedType = 5\\ | |
399 | & UnknownError = 6)\\ | |
400 | 1 - end & Server error string - Zero terminated string describing the error.\\ | |
401 | \hline | |
402 | \end{tabular} | |
403 | \caption[Error message structure]{Error message \emph{body} structure.} | |
404 | \label{client:protocol:body:error} | |
405 | \end{center} | |
406 | \end{table} | |
407 | ||
408 | \begin{figure} | |
409 | \begin{center} | |
410 | \includegraphics[width=1.1\textwidth,height=0.5\textheight]{pics/Protocol} | |
411 | \end{center} | |
412 | \caption{AliDCSProtocol flowchart.} | |
413 | \label{client:protocol:flowchart} | |
414 | \end{figure} | |
415 | ||
416 | \section{AliDCSClient} | |
417 | ||
418 | AliDCSClient provides the client API. The following methods compose the most relevant part of | |
419 | the interface: | |
420 | ||
421 | \begin{description} | |
422 | ||
423 | \item \emph{AliDCSClient(const char* host, Int\_t port, UInt\_t timeout, Int\_t retries)} - | |
424 | Class constructor. \\ | |
425 | \emph{host} - Amanda server host.\\ | |
426 | \emph{prot} - Amanda server port.\\ | |
427 | \emph{time} - Timeout (in milliseconds) which is used during the communication. | |
428 | \emph{retries} - Number of tries after which the client considers connection for | |
429 | invalid and returns the corresponding error. | |
430 | ||
431 | \item \emph{Bool\_t IsConnected()} - Returns kTrue in case there is a valid connection with | |
432 | AMANDA server. | |
433 | ||
434 | \item \emph{void Close()} - Close established connection. | |
435 | ||
436 | \item \emph{Int\_t GetDPValues(const char* dpName, UInt\_t startTime, UInt\_t endTime, | |
437 | TList\& result)} - Makes synchronous request to AMANDA server for particular | |
438 | \emph{DataPoint} and time interval.\\ | |
439 | \emph{dpName} - Requested \emph{DataPoint}.\\ | |
440 | \emph{startTime} - Beginning of time interval (in absolute time).\\ | |
441 | \emph{endTime} - End of time interval (in absolute time).\\ | |
442 | \emph{result} - In this collection (TList) is returned the result of request | |
443 | (Collection of AliDCSValue).\\ | |
444 | In case of error returns negative (error code) value otherwise returns the number | |
445 | of retrieved values. | |
446 | ||
447 | \item \emph{Int\_t GetAliasValues(const char* alias, UInt\_t startTime, UInt\_t endTime, | |
448 | TList\& result)} - Makes synchronous request to AMANDA server for particular | |
449 | \emph{alias} and time interval.\\ | |
450 | \emph{alias} - Requested \emph{alias}.\\ | |
451 | \emph{startTime} - Beginning of time interval (in absolute time).\\ | |
452 | \emph{endTime} - End of time interval (in absolute time).\\ | |
453 | \emph{result} - In this collection (TList) is returned the result of request | |
454 | (Collection of AliDCSValue).\\ | |
455 | In case of error returns negative (error code) value otherwise returns the number | |
456 | of retrieved values. | |
457 | ||
458 | \item \emph{AliDCSMessage::ErrorCode GetServerErrorCode()} - In case of Error message returned | |
459 | by AMANDA server this method returns the corresponding server error code. | |
460 | \item \emph{const TString\& GetServerError()} - In case of Error message returned | |
461 | by AMANDA server this method returns the corresponding server error description. | |
462 | \end{description} | |
463 | ||
464 | The following list contains the error codes which could be returned by \mbox{\emph{GetDPValues}} and | |
465 | \mbox{\emph{GetAliasValues}} methods in case of error occurred (negative value returned). | |
466 | \begin{description} | |
467 | \item[fgkBadState] - There was no valid connection to AMANDA server when the request was made. | |
468 | ||
469 | \item[fgkTimeout] - Specified number of retries was made and for every one the timeout was | |
470 | reached before AMANDA server sends a response message or accept the connection. | |
471 | ||
472 | \item[fgkBadMessage] - Invalid message received. | |
473 | ||
474 | \item[fgkCommError] - TPC/IP connection error occurred. | |
475 | ||
476 | \item[fgkServerError] - AMANDA server sent Error message. The corresponding error information | |
477 | can be retrieved by \mbox{\emph{GetServerErrorCode()}} and \mbox{\emph{GetServerError()}}. | |
478 | \end{description} | |
479 | ||
480 | \end{document} |