]>
Commit | Line | Data |
---|---|---|
16048fcf | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | /////////////////////////////////////////////////////////////////////////////// | |
17 | // | |
18 | // This is a class for reading a raw data from a date event and providing | |
19 | // information about digits | |
20 | // | |
21 | /////////////////////////////////////////////////////////////////////////////// | |
22 | ||
23 | #include "AliRawReaderDate.h" | |
24 | #ifdef ALI_DATE | |
25 | #include "event.h" | |
26 | #endif | |
27 | ||
28 | ClassImp(AliRawReaderDate) | |
29 | ||
30 | ||
31 | AliRawReaderDate::AliRawReaderDate( | |
32 | #ifdef ALI_DATE | |
33 | void* event | |
34 | #else | |
35 | void* /* event */ | |
36 | #endif | |
c946ab02 | 37 | ) : |
38 | fRequireMiniHeader(kTRUE), | |
39 | fEvent(NULL), | |
40 | fSubEvent(NULL), | |
41 | fEquipment(NULL), | |
42 | fIsOwner(kFALSE), | |
43 | fPosition(NULL), | |
44 | fEnd(NULL) | |
16048fcf | 45 | { |
46 | // create an object to read digits from the given date event | |
47 | ||
48 | #ifdef ALI_DATE | |
49 | fEvent = (eventHeaderStruct*) event; | |
c946ab02 | 50 | #else |
51 | Fatal("AliRawReaderDate", "this class was compiled without DATE"); | |
52 | #endif | |
53 | } | |
54 | ||
55 | AliRawReaderDate::AliRawReaderDate( | |
56 | #ifdef ALI_DATE | |
57 | const char* fileName, Int_t eventNumber | |
58 | #else | |
59 | const char* /*fileName*/, | |
60 | Int_t /*eventNumber*/ | |
61 | #endif | |
62 | ) : | |
63 | fRequireMiniHeader(kTRUE), | |
64 | fEvent(NULL), | |
65 | fSubEvent(NULL), | |
66 | fEquipment(NULL), | |
67 | fIsOwner(kFALSE), | |
68 | fPosition(NULL), | |
69 | fEnd(NULL) | |
70 | { | |
71 | // create an object to read digits from the given date event | |
72 | ||
73 | #ifdef ALI_DATE | |
74 | FILE* file = fopen(fileName, "rb"); | |
75 | if (!file) { | |
76 | Error("AliRawReaderDate", "could not open file %s", fileName); | |
77 | return; | |
78 | } | |
79 | eventHeaderStruct header; | |
80 | UInt_t headerSize = sizeof(eventHeaderStruct); | |
81 | while (fread(&header, 1, headerSize, file) == headerSize) { | |
82 | if (eventNumber == 0) { | |
83 | UChar_t* buffer = new UChar_t[header.eventSize]; | |
84 | fseek(file, -headerSize, SEEK_CUR); | |
85 | if (fread(buffer, 1, header.eventSize, file) != header.eventSize) break; | |
86 | fEvent = (eventHeaderStruct*) buffer; | |
87 | fIsOwner = kTRUE; | |
88 | break; | |
89 | } | |
90 | fseek(file, header.eventSize-headerSize, SEEK_CUR); | |
91 | eventNumber--; | |
92 | } | |
93 | fclose(file); | |
94 | ||
16048fcf | 95 | #else |
96 | Fatal("AliRawReaderDate", "this class was compiled without DATE"); | |
97 | #endif | |
98 | } | |
99 | ||
100 | AliRawReaderDate::AliRawReaderDate(const AliRawReaderDate& rawReader) : | |
c946ab02 | 101 | AliRawReader(rawReader), |
102 | fRequireMiniHeader(rawReader.fRequireMiniHeader), | |
103 | fEvent(rawReader.fEvent), | |
104 | fSubEvent(rawReader.fSubEvent), | |
105 | fEquipment(rawReader.fEquipment), | |
106 | fIsOwner(kFALSE), | |
107 | fPosition(rawReader.fPosition), | |
108 | fEnd(rawReader.fEnd) | |
109 | ||
16048fcf | 110 | { |
111 | // copy constructor | |
112 | ||
16048fcf | 113 | } |
114 | ||
115 | AliRawReaderDate& AliRawReaderDate::operator = (const AliRawReaderDate& | |
116 | rawReader) | |
117 | { | |
118 | // assignment operator | |
119 | ||
120 | this->~AliRawReaderDate(); | |
121 | new(this) AliRawReaderDate(rawReader); | |
122 | return *this; | |
123 | } | |
124 | ||
c946ab02 | 125 | AliRawReaderDate::~AliRawReaderDate() |
126 | { | |
127 | // destructor | |
128 | ||
129 | #ifdef ALI_DATE | |
130 | if (fIsOwner) delete[] fEvent; | |
131 | #endif | |
132 | } | |
133 | ||
16048fcf | 134 | |
135 | UInt_t AliRawReaderDate::GetType() const | |
136 | { | |
137 | // get the type from the event header | |
138 | ||
139 | #ifdef ALI_DATE | |
140 | if (!fEvent) return 0; | |
141 | return fEvent->eventType; | |
142 | #else | |
143 | return 0; | |
144 | #endif | |
145 | } | |
146 | ||
147 | UInt_t AliRawReaderDate::GetRunNumber() const | |
148 | { | |
149 | // get the run number from the event header | |
150 | ||
151 | #ifdef ALI_DATE | |
152 | if (!fEvent) return 0; | |
153 | return fEvent->eventRunNb; | |
154 | #else | |
155 | return 0; | |
156 | #endif | |
157 | } | |
158 | ||
159 | const UInt_t* AliRawReaderDate::GetEventId() const | |
160 | { | |
161 | // get the event id from the event header | |
162 | ||
163 | #ifdef ALI_DATE | |
164 | if (!fEvent) return NULL; | |
165 | return fEvent->eventId; | |
166 | #else | |
167 | return NULL; | |
168 | #endif | |
169 | } | |
170 | ||
171 | const UInt_t* AliRawReaderDate::GetTriggerPattern() const | |
172 | { | |
173 | // get the trigger pattern from the event header | |
174 | ||
175 | #ifdef ALI_DATE | |
176 | if (!fEvent) return NULL; | |
177 | return fEvent->eventTriggerPattern; | |
178 | #else | |
179 | return NULL; | |
180 | #endif | |
181 | } | |
182 | ||
183 | const UInt_t* AliRawReaderDate::GetDetectorPattern() const | |
184 | { | |
185 | // get the detector pattern from the event header | |
186 | ||
187 | #ifdef ALI_DATE | |
188 | if (!fEvent) return NULL; | |
189 | return fEvent->eventDetectorPattern; | |
190 | #else | |
191 | return NULL; | |
192 | #endif | |
193 | } | |
194 | ||
195 | const UInt_t* AliRawReaderDate::GetAttributes() const | |
196 | { | |
197 | // get the type attributes from the event header | |
198 | ||
199 | #ifdef ALI_DATE | |
200 | if (!fEvent) return NULL; | |
201 | return fEvent->eventTypeAttribute; | |
202 | #else | |
203 | return NULL; | |
204 | #endif | |
205 | } | |
206 | ||
c946ab02 | 207 | UInt_t AliRawReaderDate::GetLDCId() const |
208 | { | |
209 | // get the LDC Id from the event header | |
210 | ||
211 | #ifdef ALI_DATE | |
212 | if (!fSubEvent) return 0; | |
213 | return fSubEvent->eventLdcId; | |
214 | #else | |
215 | return 0; | |
216 | #endif | |
217 | } | |
218 | ||
16048fcf | 219 | UInt_t AliRawReaderDate::GetGDCId() const |
220 | { | |
221 | // get the GDC Id from the event header | |
222 | ||
223 | #ifdef ALI_DATE | |
224 | if (!fEvent) return 0; | |
225 | return fEvent->eventGdcId; | |
226 | #else | |
227 | return 0; | |
228 | #endif | |
229 | } | |
230 | ||
231 | ||
c946ab02 | 232 | Int_t AliRawReaderDate::GetEquipmentSize() const |
233 | { | |
234 | // get the size of the equipment | |
235 | ||
236 | #ifdef ALI_DATE | |
237 | if (!fEquipment) return 0; | |
238 | return fEquipment->equipmentSize; | |
239 | #else | |
240 | return 0; | |
241 | #endif | |
242 | } | |
243 | ||
244 | Int_t AliRawReaderDate::GetEquipmentType() const | |
245 | { | |
246 | // get the type from the equipment header | |
247 | ||
248 | #ifdef ALI_DATE | |
249 | if (!fEquipment) return -1; | |
250 | return fEquipment->equipmentType; | |
251 | #else | |
252 | return 0; | |
253 | #endif | |
254 | } | |
255 | ||
256 | Int_t AliRawReaderDate::GetEquipmentId() const | |
257 | { | |
258 | // get the ID from the equipment header | |
259 | ||
260 | #ifdef ALI_DATE | |
261 | if (!fEquipment) return -1; | |
262 | return fEquipment->equipmentId; | |
263 | #else | |
264 | return 0; | |
265 | #endif | |
266 | } | |
267 | ||
268 | const UInt_t* AliRawReaderDate::GetEquipmentAttributes() const | |
269 | { | |
270 | // get the attributes from the equipment header | |
271 | ||
272 | #ifdef ALI_DATE | |
273 | if (!fEquipment) return NULL; | |
274 | return fEquipment->equipmentTypeAttribute; | |
275 | #else | |
276 | return 0; | |
277 | #endif | |
278 | } | |
279 | ||
280 | Int_t AliRawReaderDate::GetEquipmentElementSize() const | |
281 | { | |
282 | // get the basic element size from the equipment header | |
283 | ||
284 | #ifdef ALI_DATE | |
285 | if (!fEquipment) return 0; | |
286 | return fEquipment->equipmentBasicElementSize; | |
287 | #else | |
288 | return 0; | |
289 | #endif | |
290 | } | |
291 | ||
292 | ||
293 | Bool_t AliRawReaderDate::ReadHeader() | |
16048fcf | 294 | { |
295 | // read a mini header at the current position | |
296 | // returns kFALSE if the mini header could not be read | |
297 | ||
b4857df7 | 298 | fErrorCode = 0; |
299 | ||
16048fcf | 300 | #ifdef ALI_DATE |
301 | if (!fEvent) return kFALSE; | |
b4857df7 | 302 | // check whether there are sub events |
303 | if (fEvent->eventSize <= fEvent->eventHeadSize) return kFALSE; | |
304 | ||
16048fcf | 305 | do { |
b4857df7 | 306 | // skip payload (if event was not selected) |
307 | if (fCount > 0) fPosition += fCount; | |
308 | ||
c946ab02 | 309 | // get the first or the next equipment if at the end of an equipment |
310 | if (!fEquipment || (fPosition >= fEnd)) { | |
311 | ||
312 | // get the first or the next sub event if at the end of a sub event | |
313 | if (!fSubEvent || | |
314 | (fPosition >= ((UChar_t*)fSubEvent) + fSubEvent->eventSize)) { | |
315 | ||
316 | // check for end of event data | |
317 | if (fPosition >= ((UChar_t*)fEvent)+fEvent->eventSize) return kFALSE; | |
318 | if (fSubEvent) { | |
319 | fSubEvent = (eventHeaderStruct*) (((UChar_t*)fSubEvent) + | |
320 | fSubEvent->eventSize); | |
321 | } else { | |
322 | fSubEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + | |
323 | fEvent->eventHeadSize); | |
324 | } | |
325 | ||
326 | // check the magic word of the sub event | |
327 | if (fSubEvent->eventMagic != EVENT_MAGIC_NUMBER) { | |
328 | Error("ReadHeader", "wrong magic number in sub event!\n" | |
329 | " run: %d event: %d %d LDC: %d GDC: %d\n", | |
330 | fSubEvent->eventRunNb, | |
331 | fSubEvent->eventId[0], fSubEvent->eventId[1], | |
332 | fSubEvent->eventLdcId, fSubEvent->eventGdcId); | |
333 | fErrorCode = kErrMagic; | |
334 | return kFALSE; | |
335 | } | |
336 | ||
337 | fEquipment = (equipmentHeaderStruct*) | |
338 | (((UChar_t*)fSubEvent) + fSubEvent->eventHeadSize); | |
b4857df7 | 339 | |
16048fcf | 340 | } else { |
c946ab02 | 341 | fEquipment = (equipmentHeaderStruct*) fEnd; |
b4857df7 | 342 | } |
343 | ||
16048fcf | 344 | fCount = 0; |
c946ab02 | 345 | fPosition = ((UChar_t*)fEquipment) + sizeof(equipmentHeaderStruct); |
346 | fEnd = fPosition + fEquipment->equipmentSize; | |
16048fcf | 347 | } |
b4857df7 | 348 | |
349 | // continue with the next sub event if no data left in the payload | |
350 | if (fPosition >= fEnd) continue; | |
351 | ||
c946ab02 | 352 | fMiniHeader = NULL; |
353 | if (fRequireMiniHeader) { | |
354 | // check that there are enough bytes left for the mini header | |
355 | if (fPosition + sizeof(AliMiniHeader) > fEnd) { | |
356 | Error("ReadHeader", "could not read mini header data!"); | |
357 | Warning("ReadHeader", "skipping %d bytes\n" | |
358 | " run: %d event: %d %d LDC: %d GDC: %d\n", | |
359 | fEnd - fPosition, fSubEvent->eventRunNb, | |
360 | fSubEvent->eventId[0], fSubEvent->eventId[1], | |
361 | fSubEvent->eventLdcId, fSubEvent->eventGdcId); | |
362 | fCount = 0; | |
363 | fPosition = fEnd; | |
364 | fErrorCode = kErrNoMiniHeader; | |
365 | continue; | |
366 | } | |
b4857df7 | 367 | |
c946ab02 | 368 | // "read" and check the mini header |
369 | fMiniHeader = (AliMiniHeader*) fPosition; | |
370 | fPosition += sizeof(AliMiniHeader); | |
371 | if (!CheckMiniHeader()) { | |
372 | Error("ReadHeader", "wrong magic word in mini header!"); | |
373 | Warning("ReadHeader", "skipping %d bytes\n" | |
374 | " run: %d event: %d %d LDC: %d GDC: %d\n", | |
375 | fEnd - fPosition, fSubEvent->eventRunNb, | |
376 | fSubEvent->eventId[0], fSubEvent->eventId[1], | |
377 | fSubEvent->eventLdcId, fSubEvent->eventGdcId); | |
378 | fCount = 0; | |
379 | fPosition = fEnd; | |
380 | fErrorCode = kErrMiniMagic; | |
381 | continue; | |
382 | } | |
383 | ||
384 | } else { // if mini header not required | |
385 | // assume there is a mini header if the magic word is correct | |
386 | if ((fPosition + sizeof(AliMiniHeader) <= fEnd) && | |
387 | CheckMiniHeader((AliMiniHeader*) fPosition)) { | |
388 | fMiniHeader = (AliMiniHeader*) fPosition; | |
389 | fPosition += sizeof(AliMiniHeader); | |
390 | } | |
72dd1d4f | 391 | } |
c946ab02 | 392 | |
393 | if (fMiniHeader) { | |
394 | fCount = fMiniHeader->fSize; | |
395 | ||
396 | // check consistency of data size in the mini header and in the sub event | |
397 | if (fPosition + fCount > fEnd) { | |
398 | Error("ReadHeader", "size in mini header exceeds event size!"); | |
399 | Warning("ReadHeader", "skipping %d bytes\n" | |
400 | " run: %d event: %d %d LDC: %d GDC: %d\n", | |
401 | fEnd - fPosition, fSubEvent->eventRunNb, | |
402 | fSubEvent->eventId[0], fSubEvent->eventId[1], | |
403 | fSubEvent->eventLdcId, fSubEvent->eventGdcId); | |
404 | fCount = 0; | |
405 | fPosition = fEnd; | |
406 | fErrorCode = kErrSize; | |
407 | continue; | |
408 | } | |
409 | ||
410 | } else { | |
411 | fCount = fEnd - fPosition; | |
16048fcf | 412 | } |
b4857df7 | 413 | |
16048fcf | 414 | } while (!IsSelected()); |
b4857df7 | 415 | |
16048fcf | 416 | return kTRUE; |
417 | #else | |
418 | return kFALSE; | |
419 | #endif | |
420 | } | |
421 | ||
422 | Bool_t AliRawReaderDate::ReadNextData(UChar_t*& data) | |
423 | { | |
424 | // reads the next payload at the current position | |
425 | // returns kFALSE if the data could not be read | |
426 | ||
b4857df7 | 427 | fErrorCode = 0; |
16048fcf | 428 | while (fCount == 0) { |
c946ab02 | 429 | if (!ReadHeader()) return kFALSE; |
16048fcf | 430 | } |
431 | data = fPosition; | |
432 | fPosition += fCount; | |
433 | fCount = 0; | |
434 | return kTRUE; | |
435 | } | |
436 | ||
437 | Bool_t AliRawReaderDate::ReadNext(UChar_t* data, Int_t size) | |
438 | { | |
439 | // reads the next block of data at the current position | |
440 | // returns kFALSE if the data could not be read | |
441 | ||
b4857df7 | 442 | fErrorCode = 0; |
16048fcf | 443 | if (fPosition + size > fEnd) { |
444 | Error("ReadNext", "could not read data!"); | |
b4857df7 | 445 | fErrorCode = kErrOutOfBounds; |
16048fcf | 446 | return kFALSE; |
447 | } | |
448 | memcpy(data, fPosition, size); | |
449 | fPosition += size; | |
450 | fCount -= size; | |
451 | return kTRUE; | |
452 | } | |
453 | ||
454 | ||
455 | Bool_t AliRawReaderDate::Reset() | |
456 | { | |
457 | // reset the current position to the beginning of the event | |
458 | ||
459 | #ifdef ALI_DATE | |
460 | fSubEvent = NULL; | |
461 | #endif | |
462 | fCount = 0; | |
463 | fPosition = fEnd = NULL; | |
464 | return kTRUE; | |
465 | } | |
b4857df7 | 466 | |
467 | ||
468 | Int_t AliRawReaderDate::CheckData() const | |
469 | { | |
470 | // check the consistency of the data | |
471 | ||
472 | #ifdef ALI_DATE | |
473 | if (!fEvent) return 0; | |
474 | // check whether there are sub events | |
475 | if (fEvent->eventSize <= fEvent->eventHeadSize) return 0; | |
476 | ||
477 | eventHeaderStruct* subEvent = NULL; | |
478 | UChar_t* position = 0; | |
479 | UChar_t* end = 0; | |
be50fca2 | 480 | Int_t result = 0; |
b4857df7 | 481 | |
482 | while (kTRUE) { | |
483 | // get the first or the next sub event if at the end of a sub event | |
484 | if (!subEvent || (position >= end)) { | |
485 | ||
486 | // check for end of event data | |
be50fca2 | 487 | if (position >= ((UChar_t*)fEvent)+fEvent->eventSize) return result; |
b4857df7 | 488 | if (subEvent) { |
489 | subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) + | |
490 | subEvent->eventSize); | |
491 | } else { | |
492 | subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) + | |
493 | fEvent->eventHeadSize); | |
494 | } | |
495 | ||
496 | // check the magic word of the sub event | |
be50fca2 | 497 | if (subEvent->eventMagic != EVENT_MAGIC_NUMBER) { |
498 | result |= kErrMagic; | |
499 | return result; | |
500 | } | |
b4857df7 | 501 | |
502 | position = ((UChar_t*)subEvent) + subEvent->eventHeadSize + | |
503 | sizeof(equipmentHeaderStruct); | |
504 | end = ((UChar_t*)subEvent) + subEvent->eventSize; | |
505 | } | |
506 | ||
507 | // continue with the next sub event if no data left in the payload | |
508 | if (position >= end) continue; | |
509 | ||
510 | // check that there are enough bytes left for the mini header | |
be50fca2 | 511 | if (position + sizeof(AliMiniHeader) > end) { |
512 | result |= kErrNoMiniHeader; | |
513 | position = end; | |
514 | continue; | |
515 | } | |
b4857df7 | 516 | |
517 | // "read" and check the mini header | |
518 | AliMiniHeader* miniHeader = (AliMiniHeader*) position; | |
519 | position += sizeof(AliMiniHeader); | |
be50fca2 | 520 | if (!CheckMiniHeader(miniHeader)){ |
521 | result |= kErrMiniMagic; | |
522 | position = end; | |
523 | continue; | |
524 | } | |
b4857df7 | 525 | |
526 | // check consistency of data size in the mini header and in the sub event | |
be50fca2 | 527 | if (position + miniHeader->fSize > end) result |= kErrSize; |
b4857df7 | 528 | position += miniHeader->fSize; |
529 | }; | |
530 | ||
531 | #endif | |
532 | return 0; | |
533 | } |