Line data Source code
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 : /* $Id$ */
17 :
18 : ///////////////////////////////////////////////////////////////////////////////
19 : ///
20 : /// This is a class for reading raw data from a date file or event.
21 : ///
22 : /// The AliRawReaderDate is constructed either with a pointer to a
23 : /// date event or with a file name and an event number.
24 : ///
25 : ///////////////////////////////////////////////////////////////////////////////
26 :
27 : #include "AliRawReaderDate.h"
28 : #include "event.h"
29 :
30 128 : ClassImp(AliRawReaderDate)
31 :
32 :
33 0 : AliRawReaderDate::AliRawReaderDate(void* event, Bool_t owner) :
34 0 : fFile(NULL),
35 0 : fEvent(NULL),
36 0 : fSubEvent(NULL),
37 0 : fEquipment(NULL),
38 0 : fPosition(NULL),
39 0 : fEnd(NULL),
40 0 : fOwner(owner)
41 0 : {
42 : // create an object to read digits from the given date event
43 :
44 0 : fEvent = (eventHeaderStruct*) event;
45 0 : }
46 :
47 0 : AliRawReaderDate::AliRawReaderDate(const char* fileName, Int_t eventNumber) :
48 0 : fFile(NULL),
49 0 : fEvent(NULL),
50 0 : fSubEvent(NULL),
51 0 : fEquipment(NULL),
52 0 : fPosition(NULL),
53 0 : fEnd(NULL),
54 0 : fOwner(kTRUE)
55 0 : {
56 : // create an object to read digits from the given date event
57 :
58 0 : fFile = fopen(fileName, "rb");
59 0 : if (!fFile) {
60 0 : Error("AliRawReaderDate", "could not open file %s", fileName);
61 0 : fIsValid = kFALSE;
62 0 : return;
63 : }
64 0 : if (eventNumber < 0) return;
65 :
66 0 : eventHeaderStruct header;
67 : UInt_t headerSize = sizeof(eventHeaderStruct);
68 0 : while (fread(&header, 1, headerSize, fFile) == headerSize) {
69 0 : if (eventNumber == 0) {
70 0 : UChar_t* buffer = new UChar_t[header.eventSize];
71 0 : fseek(fFile, -(long)headerSize, SEEK_CUR);
72 0 : if (fread(buffer, 1, header.eventSize, fFile) != header.eventSize) break;
73 0 : fEvent = (eventHeaderStruct*) buffer;
74 0 : break;
75 : }
76 0 : fseek(fFile, header.eventSize-headerSize, SEEK_CUR);
77 0 : eventNumber--;
78 : }
79 :
80 0 : }
81 :
82 : AliRawReaderDate::~AliRawReaderDate()
83 0 : {
84 : // destructor
85 :
86 0 : if (fEvent && fOwner) delete[] fEvent;
87 0 : if (fFile) {
88 0 : fclose(fFile);
89 : }
90 0 : }
91 :
92 :
93 : UInt_t AliRawReaderDate::GetType() const
94 : {
95 : // get the type from the event header
96 :
97 0 : if (!fEvent) return 0;
98 0 : return fEvent->eventType;
99 0 : }
100 :
101 : UInt_t AliRawReaderDate::GetRunNumber() const
102 : {
103 : // get the run number from the event header
104 :
105 0 : if (!fEvent) return 0;
106 0 : return fEvent->eventRunNb;
107 0 : }
108 :
109 : const UInt_t* AliRawReaderDate::GetEventId() const
110 : {
111 : // get the event id from the event header
112 :
113 0 : if (!fEvent) return NULL;
114 0 : return fEvent->eventId;
115 0 : }
116 :
117 : const UInt_t* AliRawReaderDate::GetTriggerPattern() const
118 : {
119 : // get the trigger pattern from the event header
120 :
121 0 : if (!fEvent) return NULL;
122 0 : return fEvent->eventTriggerPattern;
123 0 : }
124 :
125 : const UInt_t* AliRawReaderDate::GetDetectorPattern() const
126 : {
127 : // get the detector pattern from the event header
128 :
129 0 : if (!fEvent) return NULL;
130 0 : return fEvent->eventDetectorPattern;
131 0 : }
132 :
133 : const UInt_t* AliRawReaderDate::GetAttributes() const
134 : {
135 : // get the type attributes from the event header
136 :
137 0 : if (!fEvent) return NULL;
138 0 : return fEvent->eventTypeAttribute;
139 0 : }
140 :
141 : const UInt_t* AliRawReaderDate::GetSubEventAttributes() const
142 : {
143 : // get the type attributes from the sub event header
144 :
145 0 : if (!fSubEvent) return NULL;
146 0 : return fSubEvent->eventTypeAttribute;
147 0 : }
148 :
149 : UInt_t AliRawReaderDate::GetLDCId() const
150 : {
151 : // get the LDC Id from the event header
152 :
153 0 : if (!fSubEvent) return 0;
154 0 : return fSubEvent->eventLdcId;
155 0 : }
156 :
157 : UInt_t AliRawReaderDate::GetGDCId() const
158 : {
159 : // get the GDC Id from the event header
160 :
161 0 : if (!fEvent) return 0;
162 0 : return fEvent->eventGdcId;
163 0 : }
164 :
165 : UInt_t AliRawReaderDate::GetTimestamp() const
166 : {
167 : // get the timestamp from the event header
168 :
169 0 : if (!fEvent) return 0;
170 0 : return fEvent->eventTimestamp;
171 0 : }
172 :
173 : Int_t AliRawReaderDate::GetEquipmentSize() const
174 : {
175 : // get the size of the equipment (including the header)
176 :
177 0 : if (!fEquipment) return 0;
178 0 : if (fSubEvent->eventVersion <= 0x00030001) {
179 0 : return fEquipment->equipmentSize + sizeof(equipmentHeaderStruct);
180 : } else {
181 0 : return fEquipment->equipmentSize;
182 : }
183 0 : }
184 :
185 : Int_t AliRawReaderDate::GetEquipmentType() const
186 : {
187 : // get the type from the equipment header
188 :
189 0 : if (!fEquipment) return -1;
190 0 : return fEquipment->equipmentType;
191 0 : }
192 :
193 : Int_t AliRawReaderDate::GetEquipmentId() const
194 : {
195 : // get the ID from the equipment header
196 :
197 0 : if (!fEquipment) return -1;
198 0 : return fEquipment->equipmentId;
199 0 : }
200 :
201 : const UInt_t* AliRawReaderDate::GetEquipmentAttributes() const
202 : {
203 : // get the attributes from the equipment header
204 :
205 0 : if (!fEquipment) return NULL;
206 0 : return fEquipment->equipmentTypeAttribute;
207 0 : }
208 :
209 : Int_t AliRawReaderDate::GetEquipmentElementSize() const
210 : {
211 : // get the basic element size from the equipment header
212 :
213 0 : if (!fEquipment) return 0;
214 0 : return fEquipment->equipmentBasicElementSize;
215 0 : }
216 :
217 : Int_t AliRawReaderDate::GetEquipmentHeaderSize() const
218 : {
219 : // Get the equipment header size
220 : // 28 bytes by default
221 0 : return sizeof(equipmentHeaderStruct);
222 : }
223 :
224 : Bool_t AliRawReaderDate::ReadHeader()
225 : {
226 : // read a data header at the current position
227 : // returns kFALSE if the data header could not be read
228 :
229 0 : fErrorCode = 0;
230 :
231 0 : fHeader = NULL;
232 0 : if (!fEvent) return kFALSE;
233 : // check whether there are sub events
234 0 : if (fEvent->eventSize <= fEvent->eventHeadSize) return kFALSE;
235 :
236 : do {
237 : // skip payload (if event was not selected)
238 0 : if (fCount > 0) fPosition += fCount;
239 :
240 : // get the first or the next equipment if at the end of an equipment
241 0 : if (!fEquipment || (fPosition >= fEnd)) {
242 0 : fEquipment = NULL;
243 :
244 : // get the first or the next sub event if at the end of a sub event
245 0 : if (!fSubEvent ||
246 0 : (fPosition >= ((UChar_t*)fSubEvent) + fSubEvent->eventSize)) {
247 :
248 : // check for end of event data
249 0 : if (fPosition >= ((UChar_t*)fEvent)+fEvent->eventSize) return kFALSE;
250 0 : if (!TEST_SYSTEM_ATTRIBUTE(fEvent->eventTypeAttribute,
251 : ATTR_SUPER_EVENT)) {
252 0 : fSubEvent = fEvent; // no super event
253 0 : } else if (fSubEvent) {
254 0 : fSubEvent = (eventHeaderStruct*) (((UChar_t*)fSubEvent) +
255 0 : fSubEvent->eventSize);
256 0 : } else {
257 0 : fSubEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) +
258 0 : fEvent->eventHeadSize);
259 : }
260 :
261 : // check the magic word of the sub event
262 0 : if (fSubEvent->eventMagic != EVENT_MAGIC_NUMBER) {
263 0 : Error("ReadHeader", "wrong magic number in sub event!\n"
264 : " run: %d event: %d %d LDC: %d GDC: %d\n",
265 0 : fSubEvent->eventRunNb,
266 0 : fSubEvent->eventId[0], fSubEvent->eventId[1],
267 0 : fSubEvent->eventLdcId, fSubEvent->eventGdcId);
268 0 : fErrorCode = kErrMagic;
269 0 : return kFALSE;
270 : }
271 :
272 : // continue if no data in the subevent
273 0 : if (fSubEvent->eventSize == fSubEvent->eventHeadSize) {
274 0 : fPosition = fEnd = ((UChar_t*)fSubEvent) + fSubEvent->eventSize;
275 0 : fCount = 0;
276 0 : continue;
277 : }
278 :
279 0 : fEquipment = (equipmentHeaderStruct*)
280 0 : (((UChar_t*)fSubEvent) + fSubEvent->eventHeadSize);
281 :
282 0 : } else {
283 0 : fEquipment = (equipmentHeaderStruct*) fEnd;
284 : }
285 :
286 0 : fCount = 0;
287 0 : fPosition = ((UChar_t*)fEquipment) + sizeof(equipmentHeaderStruct);
288 0 : if (fSubEvent->eventVersion <= 0x00030001) {
289 0 : fEnd = fPosition + fEquipment->equipmentSize;
290 0 : } else {
291 0 : fEnd = ((UChar_t*)fEquipment) + fEquipment->equipmentSize;
292 : }
293 : }
294 :
295 : // continue with the next sub event if no data left in the payload
296 0 : if (fPosition >= fEnd) continue;
297 :
298 0 : if (fRequireHeader) {
299 : // check that there are enough bytes left for the data header
300 0 : if (fPosition + sizeof(AliRawDataHeader) > fEnd) {
301 0 : Error("ReadHeader", "could not read data header data!");
302 0 : Warning("ReadHeader", "skipping %ld bytes\n"
303 : " run: %d event: %d %d LDC: %d GDC: %d\n",
304 0 : fEnd - fPosition, fSubEvent->eventRunNb,
305 0 : fSubEvent->eventId[0], fSubEvent->eventId[1],
306 0 : fSubEvent->eventLdcId, fSubEvent->eventGdcId);
307 0 : fCount = 0;
308 0 : fPosition = fEnd;
309 0 : fErrorCode = kErrNoDataHeader;
310 0 : continue;
311 : }
312 :
313 : // "read" the data header
314 0 : fHeader = (AliRawDataHeader*) fPosition;
315 : // Now check the version of the header
316 : UChar_t version = 2;
317 0 : if (fHeader) version=fHeader->GetVersion();
318 :
319 0 : switch (version) {
320 : case 2:
321 : {
322 0 : if ((fPosition + fHeader->fSize) != fEnd) {
323 0 : if ((fHeader->fSize != 0xFFFFFFFF) &&
324 0 : (fEquipment->equipmentId != 4352))
325 0 : Warning("ReadHeader",
326 : "raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
327 0 : fHeader->fSize, fEnd - fPosition);
328 0 : fHeader->fSize = fEnd - fPosition;
329 0 : }
330 0 : fPosition += sizeof(AliRawDataHeader);
331 0 : fHeaderV3 = 0;
332 0 : break;
333 : }
334 : case 3:
335 : {
336 0 : fHeaderV3 = (AliRawDataHeaderV3*) fPosition;
337 0 : if ((fPosition + fHeaderV3->fSize) != fEnd) {
338 0 : if ((fHeaderV3->fSize != 0xFFFFFFFF) &&
339 0 : (fEquipment->equipmentId != 4352))
340 0 : Warning("ReadHeader",
341 : "raw data size found in the header is wrong (%d != %ld)! Using the equipment size instead !",
342 0 : fHeaderV3->fSize, fEnd - fPosition);
343 0 : fHeaderV3->fSize = fEnd - fPosition;
344 0 : }
345 0 : fPosition += sizeof(AliRawDataHeaderV3);
346 0 : fHeader = 0;
347 0 : break;
348 : }
349 : default:
350 : // We have got a version we don't know
351 0 : if (fEquipment->equipmentId != 4352)
352 : {
353 0 : Error("ReadHeader",
354 : "version is neither 2 nor 3, we can't handle it (version found : %d). Jump to the end of the equipment",version);
355 0 : Warning("ReadHeader",
356 : " run: %d event: %d %d LDC: %d GDC: %d\n",
357 0 : fSubEvent->eventRunNb,
358 0 : fSubEvent->eventId[0], fSubEvent->eventId[1],
359 0 : fSubEvent->eventLdcId, fSubEvent->eventGdcId);
360 0 : }
361 0 : fHeader = 0x0;
362 0 : fHeaderV3 = 0x0;
363 0 : fPosition = fEnd;
364 0 : continue;
365 : }
366 0 : }
367 0 : if (fHeader && (fHeader->fSize != 0xFFFFFFFF)) {
368 0 : fCount = fHeader->fSize - sizeof(AliRawDataHeader);
369 :
370 : // check consistency of data size in the header and in the sub event
371 0 : if (fPosition + fCount > fEnd) {
372 0 : Error("ReadHeader", "size in data header exceeds event size!");
373 0 : Warning("ReadHeader", "skipping %ld bytes\n"
374 : " run: %d event: %d %d LDC: %d GDC: %d\n",
375 0 : fEnd - fPosition, fSubEvent->eventRunNb,
376 0 : fSubEvent->eventId[0], fSubEvent->eventId[1],
377 0 : fSubEvent->eventLdcId, fSubEvent->eventGdcId);
378 0 : fCount = 0;
379 0 : fPosition = fEnd;
380 0 : fErrorCode = kErrSize;
381 0 : continue;
382 : }
383 :
384 0 : } else if (fHeaderV3 && (fHeaderV3->fSize != 0xFFFFFFFF)) {
385 0 : fCount = fHeaderV3->fSize - sizeof(AliRawDataHeaderV3);
386 :
387 : // check consistency of data size in the header and in the sub event
388 0 : if (fPosition + fCount > fEnd) {
389 0 : Error("ReadHeader", "size in data header exceeds event size!");
390 0 : Warning("ReadHeader", "skipping %ld bytes\n"
391 : " run: %d event: %d %d LDC: %d GDC: %d\n",
392 0 : fEnd - fPosition, fSubEvent->eventRunNb,
393 0 : fSubEvent->eventId[0], fSubEvent->eventId[1],
394 0 : fSubEvent->eventLdcId, fSubEvent->eventGdcId);
395 0 : fCount = 0;
396 0 : fPosition = fEnd;
397 0 : fErrorCode = kErrSize;
398 0 : continue;
399 : }
400 :
401 : } else {
402 0 : fCount = fEnd - fPosition;
403 : }
404 :
405 0 : } while (!fEquipment || !IsSelected());
406 :
407 0 : return kTRUE;
408 0 : }
409 :
410 : Bool_t AliRawReaderDate::ReadNextData(UChar_t*& data)
411 : {
412 : // reads the next payload at the current position
413 : // returns kFALSE if the data could not be read
414 :
415 0 : fErrorCode = 0;
416 0 : while (fCount == 0) {
417 0 : if (!ReadHeader()) return kFALSE;
418 : }
419 0 : data = fPosition;
420 0 : fPosition += fCount;
421 0 : fCount = 0;
422 0 : return kTRUE;
423 0 : }
424 :
425 : Bool_t AliRawReaderDate::ReadNext(UChar_t* data, Int_t size)
426 : {
427 : // reads the next block of data at the current position
428 : // returns kFALSE if the data could not be read
429 :
430 0 : fErrorCode = 0;
431 0 : if (fPosition + size > fEnd) {
432 0 : Error("ReadNext", "could not read data!");
433 0 : fErrorCode = kErrOutOfBounds;
434 0 : return kFALSE;
435 : }
436 0 : memcpy(data, fPosition, size);
437 0 : fPosition += size;
438 0 : fCount -= size;
439 0 : return kTRUE;
440 0 : }
441 :
442 :
443 : Bool_t AliRawReaderDate::Reset()
444 : {
445 : // reset the current position to the beginning of the event
446 :
447 0 : fSubEvent = NULL;
448 0 : fEquipment = NULL;
449 0 : fCount = 0;
450 0 : fPosition = fEnd = NULL;
451 0 : fHeader=NULL;
452 0 : fHeaderV3=NULL;
453 0 : return kTRUE;
454 : }
455 :
456 :
457 : Bool_t AliRawReaderDate::NextEvent()
458 : {
459 : // go to the next event in the date file
460 :
461 0 : if (!fFile) {
462 0 : if (fEventNumber < 0 && fEvent) {
463 0 : fEventNumber++;
464 0 : return kTRUE;
465 : }
466 : else
467 0 : return kFALSE;
468 : }
469 :
470 0 : Reset();
471 0 : eventHeaderStruct header;
472 : UInt_t headerSize = sizeof(eventHeaderStruct);
473 0 : if (fEvent) delete[] fEvent;
474 0 : fEvent = &header;
475 :
476 0 : while (fread(&header, 1, headerSize, fFile) == headerSize) {
477 0 : if (!IsEventSelected()) {
478 0 : fseek(fFile, header.eventSize-headerSize, SEEK_CUR);
479 0 : continue;
480 : }
481 0 : UChar_t* buffer = new UChar_t[header.eventSize];
482 0 : fseek(fFile, -(long)headerSize, SEEK_CUR);
483 0 : if (fread(buffer, 1, header.eventSize, fFile) != header.eventSize) {
484 0 : Error("NextEvent", "could not read event from file");
485 0 : delete[] buffer;
486 0 : break;
487 : }
488 0 : fEvent = (eventHeaderStruct*) buffer;
489 0 : fEventNumber++;
490 0 : return kTRUE;
491 : };
492 :
493 0 : fEvent = NULL;
494 :
495 0 : return kFALSE;
496 0 : }
497 :
498 : Bool_t AliRawReaderDate::RewindEvents()
499 : {
500 : // go back to the beginning of the date file
501 :
502 0 : if (fFile)
503 0 : fseek(fFile, 0, SEEK_SET);
504 :
505 0 : fEventNumber = -1;
506 0 : return Reset();
507 : }
508 :
509 :
510 : Int_t AliRawReaderDate::CheckData() const
511 : {
512 : // check the consistency of the data
513 :
514 0 : if (!fEvent) return 0;
515 : // check whether there are sub events
516 0 : if (fEvent->eventSize <= fEvent->eventHeadSize) return 0;
517 :
518 : eventHeaderStruct* subEvent = NULL;
519 : UChar_t* position = 0;
520 : UChar_t* end = 0;
521 : Int_t result = 0;
522 :
523 0 : while (kTRUE) {
524 : // get the first or the next sub event if at the end of a sub event
525 0 : if (!subEvent || (position >= end)) {
526 :
527 : // check for end of event data
528 0 : if (position >= ((UChar_t*)fEvent)+fEvent->eventSize) return result;
529 0 : if (!TEST_SYSTEM_ATTRIBUTE(fEvent->eventTypeAttribute,
530 : ATTR_SUPER_EVENT)) {
531 : subEvent = fEvent; // no super event
532 0 : } else if (subEvent) {
533 0 : subEvent = (eventHeaderStruct*) (((UChar_t*)subEvent) +
534 0 : subEvent->eventSize);
535 0 : } else {
536 0 : subEvent = (eventHeaderStruct*) (((UChar_t*)fEvent) +
537 0 : fEvent->eventHeadSize);
538 : }
539 :
540 : // check the magic word of the sub event
541 0 : if (subEvent->eventMagic != EVENT_MAGIC_NUMBER) {
542 0 : result |= kErrMagic;
543 0 : return result;
544 : }
545 :
546 0 : position = ((UChar_t*)subEvent) + subEvent->eventHeadSize +
547 : sizeof(equipmentHeaderStruct);
548 0 : end = ((UChar_t*)subEvent) + subEvent->eventSize;
549 0 : }
550 :
551 : // continue with the next sub event if no data left in the payload
552 0 : if (position >= end) continue;
553 :
554 0 : if (fRequireHeader) {
555 : // check that there are enough bytes left for the data header
556 0 : if (position + sizeof(AliRawDataHeader) > end) {
557 0 : result |= kErrNoDataHeader;
558 : position = end;
559 0 : continue;
560 : }
561 :
562 : // Here we have to check if we have header v2 or v3
563 : // check consistency of data size in the data header and in the sub event
564 0 : AliRawDataHeader* header = (AliRawDataHeader*) position;
565 0 : UChar_t version = header->GetVersion();
566 0 : if (version==2) {
567 0 : if ((position + header->fSize) != end) {
568 0 : if (header->fSize != 0xFFFFFFFF)
569 0 : Warning("CheckData",
570 : "raw data size found in the header V2 is wrong (%d != %ld)! Using the equipment size instead !",
571 0 : header->fSize, end - position);
572 0 : header->fSize = end - position;
573 0 : result |= kErrSize;
574 0 : }
575 : }
576 0 : else if (version==3) {
577 0 : AliRawDataHeaderV3 * headerV3 = (AliRawDataHeaderV3*) position;
578 0 : if ((position + headerV3->fSize) != end) {
579 0 : if (headerV3->fSize != 0xFFFFFFFF)
580 0 : Warning("CheckData",
581 : "raw data size found in the header V3 is wrong (%d != %ld)! Using the equipment size instead !",
582 0 : headerV3->fSize, end - position);
583 0 : headerV3->fSize = end - position;
584 0 : result |= kErrSize;
585 0 : }
586 0 : }
587 :
588 0 : }
589 : position = end;
590 : };
591 :
592 : return 0;
593 0 : }
594 :
595 : AliRawReader* AliRawReaderDate::CloneSingleEvent() const
596 : {
597 : // Clones the current event and
598 : // creates raw-reader for the cloned event
599 : // Can be used in order to make asynchronious
600 : // access to the current raw data within
601 : // several threads (online event display/reco)
602 :
603 0 : if (fEvent) {
604 0 : UInt_t evSize = fEvent->eventSize;
605 0 : if (evSize) {
606 0 : UChar_t *newEvent = new UChar_t[evSize];
607 0 : memcpy(newEvent,fEvent,evSize);
608 0 : return new AliRawReaderDate((void *)newEvent,kTRUE);
609 : }
610 0 : }
611 0 : return NULL;
612 0 : }
|