Adding support for raw data events without subevent header
[u/mrichter/AliRoot.git] / RAW / AliRawReader.cxx
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 the base class for reading raw data.
21 ///
22 /// The derived classes, which operate on concrete raw data formats,
23 /// should implement
24 /// - ReadHeader to read the next (data/equipment) header
25 /// - ReadNextData to read the next raw data block (=1 DDL)
26 /// - ReadNext to read a given number of bytes
27 /// - several getters like GetType
28 ///
29 /// Sequential access to the raw data is provided by the methods
30 /// ReadHeader, ReadNextData, ReadNextInt, ReadNextShort, ReadNextChar
31 ///
32 /// If only data from a specific detector (and a given range of DDL numbers)
33 /// should be read, this can be achieved by the Select method.
34 /// Several getters provide information about the current event and the
35 /// current type of raw data.
36 ///
37 ///////////////////////////////////////////////////////////////////////////////
38
39 #include "AliRawReader.h"
40
41
42 ClassImp(AliRawReader)
43
44
45 AliRawReader::AliRawReader() :
46   fRequireHeader(kTRUE),
47   fHeader(NULL),
48   fCount(0),
49   fSelectEquipmentType(-1),
50   fSelectMinEquipmentId(-1),
51   fSelectMaxEquipmentId(-1),
52   fSkipInvalid(kFALSE),
53   fSelectEventType(-1),
54   fErrorCode(0)
55 {
56 // default constructor: initialize data members
57
58 }
59
60 AliRawReader::AliRawReader(const AliRawReader& rawReader) :
61   TObject(rawReader),
62   fRequireHeader(rawReader.fRequireHeader),
63   fHeader(rawReader.fHeader),
64   fCount(rawReader.fCount),
65   fSelectEquipmentType(rawReader.fSelectEquipmentType),
66   fSelectMinEquipmentId(rawReader.fSelectMinEquipmentId),
67   fSelectMaxEquipmentId(rawReader.fSelectMaxEquipmentId),
68   fSkipInvalid(rawReader.fSkipInvalid),
69   fSelectEventType(rawReader.fSelectEventType),
70   fErrorCode(0)
71 {
72 // copy constructor
73
74 }
75
76 AliRawReader& AliRawReader::operator = (const AliRawReader& rawReader)
77 {
78 // assignment operator
79
80   fHeader = rawReader.fHeader;
81   fCount = rawReader.fCount;
82
83   fSelectEquipmentType = rawReader.fSelectEquipmentType;
84   fSelectMinEquipmentId = rawReader.fSelectMinEquipmentId;
85   fSelectMaxEquipmentId = rawReader.fSelectMaxEquipmentId;
86   fSkipInvalid = rawReader.fSkipInvalid;
87   fSelectEventType = rawReader.fSelectEventType;
88
89   fErrorCode = rawReader.fErrorCode;
90
91   return *this;
92 }
93
94
95 void AliRawReader::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
96 {
97 // read only data of the detector with the given ID and in the given
98 // range of DDLs (minDDLID <= DDLID <= maxDDLID).
99 // no selection is applied if a value < 0 is used.
100
101   fSelectEquipmentType = 0;
102   if (minDDLID < 0) minDDLID = 0;
103   fSelectMinEquipmentId = (detectorID << 8) + minDDLID;
104   if (maxDDLID < 0) maxDDLID = 0xFF;
105   fSelectMaxEquipmentId = (detectorID << 8) + maxDDLID;
106 }
107
108 void AliRawReader::SelectEquipment(Int_t equipmentType, 
109                                    Int_t minEquipmentId, Int_t maxEquipmentId)
110 {
111 // read only data of the equipment with the given type and in the given
112 // range of IDs (minEquipmentId <= EquipmentId <= maxEquipmentId).
113 // no selection is applied if a value < 0 is used.
114
115   fSelectEquipmentType = equipmentType;
116   fSelectMinEquipmentId = minEquipmentId;
117   fSelectMaxEquipmentId = maxEquipmentId;
118 }
119
120 void AliRawReader::SelectEvents(Int_t type)
121 {
122 // read only events with the given type.
123 // no selection is applied if a value < 0 is used.
124
125   fSelectEventType = type;
126 }
127
128 Bool_t AliRawReader::IsSelected() const
129 {
130 // apply the selection (if any)
131
132   if (fSkipInvalid && !IsValid()) return kFALSE;
133
134   if (fSelectEquipmentType >= 0) {
135     if (GetEquipmentType() != fSelectEquipmentType) return kFALSE;
136     if ((fSelectMinEquipmentId >= 0) && 
137         (GetEquipmentId() < fSelectMinEquipmentId))
138       return kFALSE;
139     if ((fSelectMaxEquipmentId >= 0) && 
140         (GetEquipmentId() > fSelectMaxEquipmentId))
141       return kFALSE;
142   }
143
144   return kTRUE;
145 }
146
147 Bool_t AliRawReader::IsEventSelected() const
148 {
149 // apply the event selection (if any)
150
151   if (fSelectEventType >= 0) {
152     if (GetType() != (UInt_t) fSelectEventType) return kFALSE;
153   }
154
155   return kTRUE;
156 }
157
158
159 Bool_t AliRawReader::ReadNextInt(UInt_t& data)
160 {
161 // reads the next 4 bytes at the current position
162 // returns kFALSE if the data could not be read
163
164   while (fCount == 0) {
165     if (!ReadHeader()) return kFALSE;
166   }
167   if (fCount < (Int_t) sizeof(data)) {
168     Error("ReadNextInt", 
169           "too few data left (%d bytes) to read an UInt_t!", fCount);
170     return kFALSE;
171   }
172   if (!ReadNext((UChar_t*) &data, sizeof(data))) {
173     Error("ReadNextInt", "could not read data!");
174     return kFALSE;
175   }
176   return kTRUE;
177 }
178
179 Bool_t AliRawReader::ReadNextShort(UShort_t& data)
180 {
181 // reads the next 2 bytes at the current position
182 // returns kFALSE if the data could not be read
183
184   while (fCount == 0) {
185     if (!ReadHeader()) return kFALSE;
186   }
187   if (fCount < (Int_t) sizeof(data)) {
188     Error("ReadNextShort", 
189           "too few data left (%d bytes) to read an UShort_t!", fCount);
190     return kFALSE;
191   }
192   if (!ReadNext((UChar_t*) &data, sizeof(data))) {
193     Error("ReadNextShort", "could not read data!");
194     return kFALSE;
195   }
196   return kTRUE;
197 }
198
199 Bool_t AliRawReader::ReadNextChar(UChar_t& data)
200 {
201 // reads the next 1 byte at the current stream position
202 // returns kFALSE if the data could not be read
203
204   while (fCount == 0) {
205     if (!ReadHeader()) return kFALSE;
206   }
207   if (!ReadNext((UChar_t*) &data, sizeof(data))) {
208     Error("ReadNextChar", "could not read data!");
209     return kFALSE;
210   }
211   return kTRUE;
212 }
213
214
215 Int_t AliRawReader::CheckData() const
216 {
217 // check the consistency of the data
218 // derived classes should overwrite the default method which returns 0 (no err)
219
220   return 0;
221 }
222
223
224 void AliRawReader::DumpData(Int_t limit)
225 {
226 // print the raw data
227 // if limit is not negative, only the first and last "limit" lines of raw data
228 // are printed
229
230   Reset();
231   if (!ReadHeader()) {
232     Error("DumpData", "no header");
233     return;
234   }
235   printf("header:\n"
236          " type = %d  run = %d  ", GetType(), GetRunNumber());
237   if (GetEventId()) {
238     printf("event = %8.8x %8.8x\n", GetEventId()[1], GetEventId()[0]);
239   } else {
240     printf("event = -------- --------\n");
241   }
242   if (GetTriggerPattern()) {
243     printf(" trigger = %8.8x %8.8x  ",
244            GetTriggerPattern()[1], GetTriggerPattern()[0]);
245   } else {
246     printf(" trigger = -------- --------  ");
247   }
248   if (GetDetectorPattern()) {
249     printf("detector = %8.8x\n", GetDetectorPattern()[0]);
250   } else {
251     printf("detector = --------\n");
252   }
253   if (GetAttributes()) {
254     printf(" attributes = %8.8x %8.8x %8.8x  ",
255            GetAttributes()[2], GetAttributes()[1], GetAttributes()[0]);
256   } else {
257     printf(" attributes = -------- -------- --------  ");
258   }
259   printf("GDC = %d\n", GetGDCId());
260   printf("\n");
261
262   do {
263     printf("-------------------------------------------------------------------------------\n");
264     printf("LDC = %d\n", GetLDCId());
265
266     printf("equipment:\n"
267            " size = %d  type = %d  id = %d\n",
268            GetEquipmentSize(), GetEquipmentType(), GetEquipmentId());
269     if (GetEquipmentAttributes()) {
270       printf(" attributes = %8.8x %8.8x %8.8x  ", GetEquipmentAttributes()[2],
271              GetEquipmentAttributes()[1], GetEquipmentAttributes()[0]);
272     } else {
273       printf(" attributes = -------- -------- --------  ");
274     }
275     printf("element size = %d\n", GetEquipmentElementSize());
276
277     printf("data header:\n"
278            " size = %d  version = %d  valid = %d  compression = %d\n",
279            GetDataSize(), GetVersion(), IsValid(), IsCompressed());
280
281     printf("\n");
282     if (limit == 0) continue;
283
284     Int_t size = GetDataSize();
285     char line[70];
286     for (Int_t i = 0; i < 70; i++) line[i] = ' ';
287     line[69] = '\0';
288     Int_t pos = 0;
289     Int_t max = 16;
290     UChar_t byte;
291
292     for (Int_t n = 0; n < size; n++) {
293       if (!ReadNextChar(byte)) {
294         Error("DumpData", "couldn't read byte number %d\n", n);
295         break;
296       }
297       if (pos >= max) {
298         printf("%8.8x  %s\n", n-pos, line);
299         for (Int_t i = 0; i < 70; i++) line[i] = ' ';
300         line[69] = '\0';
301         pos = 0;
302         if ((limit > 0) && (n/max == limit)) {
303           Int_t nContinue = ((size-1)/max+1-limit) * max;
304           if (nContinue > n) {
305             printf(" [skipping %d bytes]\n", nContinue-n);
306             n = nContinue-1;
307             continue;
308           }
309         }
310       }
311       Int_t offset = pos/4;
312       if ((byte > 0x20) && (byte < 0x7f)) {
313         line[pos+offset] = byte;
314       } else {
315         line[pos+offset] = '.';
316       }
317       char hex[3];
318       sprintf(hex, "%2.2x", byte);
319       line[max+max/4+3+2*pos+offset] = hex[0];
320       line[max+max/4+4+2*pos+offset] = hex[1];
321       pos++;
322     }
323
324     if (pos > 0) printf("%8.8x  %s\n", size-pos, line);
325     printf("\n");
326            
327   } while (ReadHeader());
328 }