Code error is added to the raw data error log class
[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 <Riostream.h>
40 #include "AliRawReader.h"
41 #include "AliDAQ.h"
42 #include "AliLog.h"
43
44 ClassImp(AliRawReader)
45
46
47 AliRawReader::AliRawReader() :
48   fEquipmentIdsIn(NULL),
49   fEquipmentIdsOut(NULL),
50   fRequireHeader(kTRUE),
51   fHeader(NULL),
52   fCount(0),
53   fSelectEquipmentType(-1),
54   fSelectMinEquipmentId(-1),
55   fSelectMaxEquipmentId(-1),
56   fSkipInvalid(kFALSE),
57   fSelectEventType(-1),
58   fErrorCode(0),
59   fEventNumber(-1),
60   fErrorLogs("AliRawDataErrorLog",100)
61 {
62 // default constructor: initialize data members
63 }
64
65 Bool_t AliRawReader::LoadEquipmentIdsMap(const char *fileName)
66 {
67   // Open the mapping file
68   // and load the mapping data
69   ifstream input(fileName);
70   if (input.is_open()) {
71     Warning("AliRawReader","Equipment ID mapping file is found !");
72     const Int_t kMaxDDL = 256;
73     fEquipmentIdsIn = new TArrayI(kMaxDDL);
74     fEquipmentIdsOut = new TArrayI(kMaxDDL);
75     Int_t equipIn, equipOut;
76     Int_t nIds = 0;
77     while (input >> equipIn >> equipOut) {
78       if (nIds >= kMaxDDL) {
79         Error("AliRawReader","Too many equipment Id mappings found ! Truncating the list !");
80         break;
81       }
82       fEquipmentIdsIn->AddAt(equipIn,nIds); 
83       fEquipmentIdsOut->AddAt(equipOut,nIds);
84       nIds++;
85     }
86     fEquipmentIdsIn->Set(nIds);
87     fEquipmentIdsOut->Set(nIds);
88     input.close();
89     return kTRUE;
90   }
91   else {
92     Error("AliRawReader","equipment id map file is not found ! Skipping the mapping !");
93     return kFALSE;
94   }
95 }
96
97 AliRawReader::AliRawReader(const AliRawReader& rawReader) :
98   TObject(rawReader),
99   fEquipmentIdsIn(rawReader.fEquipmentIdsIn),
100   fEquipmentIdsOut(rawReader.fEquipmentIdsOut),
101   fRequireHeader(rawReader.fRequireHeader),
102   fHeader(rawReader.fHeader),
103   fCount(rawReader.fCount),
104   fSelectEquipmentType(rawReader.fSelectEquipmentType),
105   fSelectMinEquipmentId(rawReader.fSelectMinEquipmentId),
106   fSelectMaxEquipmentId(rawReader.fSelectMaxEquipmentId),
107   fSkipInvalid(rawReader.fSkipInvalid),
108   fSelectEventType(rawReader.fSelectEventType),
109   fErrorCode(0),
110   fEventNumber(-1),
111   fErrorLogs("AliRawDataErrorLog",100)
112 {
113 // copy constructor
114 }
115
116 AliRawReader& AliRawReader::operator = (const AliRawReader& rawReader)
117 {
118 // assignment operator
119   fEquipmentIdsIn = rawReader.fEquipmentIdsIn;
120   fEquipmentIdsOut = rawReader.fEquipmentIdsOut;
121
122   fHeader = rawReader.fHeader;
123   fCount = rawReader.fCount;
124
125   fSelectEquipmentType = rawReader.fSelectEquipmentType;
126   fSelectMinEquipmentId = rawReader.fSelectMinEquipmentId;
127   fSelectMaxEquipmentId = rawReader.fSelectMaxEquipmentId;
128   fSkipInvalid = rawReader.fSkipInvalid;
129   fSelectEventType = rawReader.fSelectEventType;
130
131   fErrorCode = rawReader.fErrorCode;
132
133   fEventNumber = rawReader.fEventNumber;
134   fErrorLogs = *((TClonesArray*)rawReader.fErrorLogs.Clone());
135
136   return *this;
137 }
138
139 AliRawReader::~AliRawReader()
140 {
141   // destructor
142   // delete the mapping arrays if
143   // initialized
144   if (fEquipmentIdsIn) delete fEquipmentIdsIn;
145   if (fEquipmentIdsOut) delete fEquipmentIdsOut;
146 }
147
148 Int_t AliRawReader::GetMappedEquipmentId() const
149 {
150   if (!fEquipmentIdsIn || !fEquipmentIdsOut) {
151     Error("AliRawReader","equipment Ids mapping is not initialized !");
152     return GetEquipmentId();
153   }
154   Int_t equipmentId = GetEquipmentId();
155   for(Int_t iId = 0; iId < fEquipmentIdsIn->GetSize(); iId++) {
156     if (equipmentId == fEquipmentIdsIn->At(iId)) {
157       equipmentId = fEquipmentIdsOut->At(iId);
158       break;
159     }
160   }
161   return equipmentId;
162 }
163
164 Int_t AliRawReader::GetDetectorID() const
165 {
166   // Get the detector ID
167   // The list of detector IDs
168   // can be found in AliDAQ.h
169   Int_t equipmentId;
170   if (fEquipmentIdsIn && fEquipmentIdsIn)
171     equipmentId = GetMappedEquipmentId();
172   else
173     equipmentId = GetEquipmentId();
174
175   if (equipmentId >= 0) {
176     Int_t ddlIndex;
177     return AliDAQ::DetectorIDFromDdlID(equipmentId,ddlIndex);
178   }
179   else
180     return -1;
181 }
182
183 Int_t AliRawReader::GetDDLID() const
184 {
185   // Get the DDL ID (within one sub-detector)
186   // The list of detector IDs
187   // can be found in AliDAQ.h
188   Int_t equipmentId;
189   if (fEquipmentIdsIn && fEquipmentIdsIn)
190     equipmentId = GetMappedEquipmentId();
191   else
192     equipmentId = GetEquipmentId();
193
194   if (equipmentId >= 0) {
195     Int_t ddlIndex;
196     AliDAQ::DetectorIDFromDdlID(equipmentId,ddlIndex);
197     return ddlIndex;
198   }
199   else
200     return -1;
201 }
202
203 void AliRawReader::Select(const char *detectorName, Int_t minDDLID, Int_t maxDDLID)
204 {
205 // read only data of the detector with the given name and in the given
206 // range of DDLs (minDDLID <= DDLID <= maxDDLID).
207 // no selection is applied if a value < 0 is used.
208   Int_t detectorID = AliDAQ::DetectorID(detectorName);
209   if(detectorID >= 0)
210     Select(detectorID,minDDLID,maxDDLID);
211 }
212
213 void AliRawReader::Select(Int_t detectorID, Int_t minDDLID, Int_t maxDDLID)
214 {
215 // read only data of the detector with the given ID and in the given
216 // range of DDLs (minDDLID <= DDLID <= maxDDLID).
217 // no selection is applied if a value < 0 is used.
218
219   fSelectEquipmentType = -1;
220
221   if (minDDLID < 0)
222     fSelectMinEquipmentId = AliDAQ::DdlIDOffset(detectorID);
223   else
224     fSelectMinEquipmentId = AliDAQ::DdlID(detectorID,minDDLID);
225
226   if (maxDDLID < 0)
227     fSelectMaxEquipmentId = AliDAQ::DdlID(detectorID,AliDAQ::NumberOfDdls(detectorID)-1);
228   else
229     fSelectMaxEquipmentId = AliDAQ::DdlID(detectorID,maxDDLID);
230 }
231
232 void AliRawReader::SelectEquipment(Int_t equipmentType, 
233                                    Int_t minEquipmentId, Int_t maxEquipmentId)
234 {
235 // read only data of the equipment with the given type and in the given
236 // range of IDs (minEquipmentId <= EquipmentId <= maxEquipmentId).
237 // no selection is applied if a value < 0 is used.
238
239   fSelectEquipmentType = equipmentType;
240   fSelectMinEquipmentId = minEquipmentId;
241   fSelectMaxEquipmentId = maxEquipmentId;
242 }
243
244 void AliRawReader::SelectEvents(Int_t type)
245 {
246 // read only events with the given type.
247 // no selection is applied if a value < 0 is used.
248
249   fSelectEventType = type;
250 }
251
252 Bool_t AliRawReader::IsSelected() const
253 {
254 // apply the selection (if any)
255
256   if (fSkipInvalid && !IsValid()) return kFALSE;
257
258   if (fSelectEquipmentType >= 0)
259     if (GetEquipmentType() != fSelectEquipmentType) return kFALSE;
260
261   Int_t equipmentId;
262   if (fEquipmentIdsIn && fEquipmentIdsIn)
263     equipmentId = GetMappedEquipmentId();
264   else
265     equipmentId = GetEquipmentId();
266
267   if ((fSelectMinEquipmentId >= 0) && 
268       (equipmentId < fSelectMinEquipmentId))
269     return kFALSE;
270   if ((fSelectMaxEquipmentId >= 0) && 
271       (equipmentId > fSelectMaxEquipmentId))
272     return kFALSE;
273
274   return kTRUE;
275 }
276
277 Bool_t AliRawReader::IsEventSelected() const
278 {
279 // apply the event selection (if any)
280
281   if (fSelectEventType >= 0) {
282     if (GetType() != (UInt_t) fSelectEventType) return kFALSE;
283   }
284
285   return kTRUE;
286 }
287
288
289 Bool_t AliRawReader::ReadNextInt(UInt_t& data)
290 {
291 // reads the next 4 bytes at the current position
292 // returns kFALSE if the data could not be read
293
294   while (fCount == 0) {
295     if (!ReadHeader()) return kFALSE;
296   }
297   if (fCount < (Int_t) sizeof(data)) {
298     Error("ReadNextInt", 
299           "too few data left (%d bytes) to read an UInt_t!", fCount);
300     return kFALSE;
301   }
302   if (!ReadNext((UChar_t*) &data, sizeof(data))) {
303     Error("ReadNextInt", "could not read data!");
304     return kFALSE;
305   }
306   return kTRUE;
307 }
308
309 Bool_t AliRawReader::ReadNextShort(UShort_t& data)
310 {
311 // reads the next 2 bytes at the current position
312 // returns kFALSE if the data could not be read
313
314   while (fCount == 0) {
315     if (!ReadHeader()) return kFALSE;
316   }
317   if (fCount < (Int_t) sizeof(data)) {
318     Error("ReadNextShort", 
319           "too few data left (%d bytes) to read an UShort_t!", fCount);
320     return kFALSE;
321   }
322   if (!ReadNext((UChar_t*) &data, sizeof(data))) {
323     Error("ReadNextShort", "could not read data!");
324     return kFALSE;
325   }
326   return kTRUE;
327 }
328
329 Bool_t AliRawReader::ReadNextChar(UChar_t& data)
330 {
331 // reads the next 1 byte at the current stream position
332 // returns kFALSE if the data could not be read
333
334   while (fCount == 0) {
335     if (!ReadHeader()) return kFALSE;
336   }
337   if (!ReadNext((UChar_t*) &data, sizeof(data))) {
338     Error("ReadNextChar", "could not read data!");
339     return kFALSE;
340   }
341   return kTRUE;
342 }
343
344
345 Int_t AliRawReader::CheckData() const
346 {
347 // check the consistency of the data
348 // derived classes should overwrite the default method which returns 0 (no err)
349
350   return 0;
351 }
352
353
354 void AliRawReader::DumpData(Int_t limit)
355 {
356 // print the raw data
357 // if limit is not negative, only the first and last "limit" lines of raw data
358 // are printed
359
360   Reset();
361   if (!ReadHeader()) {
362     Error("DumpData", "no header");
363     return;
364   }
365   printf("header:\n"
366          " type = %d  run = %d  ", GetType(), GetRunNumber());
367   if (GetEventId()) {
368     printf("event = %8.8x %8.8x\n", GetEventId()[1], GetEventId()[0]);
369   } else {
370     printf("event = -------- --------\n");
371   }
372   if (GetTriggerPattern()) {
373     printf(" trigger = %8.8x %8.8x  ",
374            GetTriggerPattern()[1], GetTriggerPattern()[0]);
375   } else {
376     printf(" trigger = -------- --------  ");
377   }
378   if (GetDetectorPattern()) {
379     printf("detector = %8.8x\n", GetDetectorPattern()[0]);
380   } else {
381     printf("detector = --------\n");
382   }
383   if (GetAttributes()) {
384     printf(" attributes = %8.8x %8.8x %8.8x  ",
385            GetAttributes()[2], GetAttributes()[1], GetAttributes()[0]);
386   } else {
387     printf(" attributes = -------- -------- --------  ");
388   }
389   printf("GDC = %d\n", GetGDCId());
390   printf("\n");
391
392   do {
393     printf("-------------------------------------------------------------------------------\n");
394     printf("LDC = %d\n", GetLDCId());
395
396     printf("equipment:\n"
397            " size = %d  type = %d  id = %d\n",
398            GetEquipmentSize(), GetEquipmentType(), GetEquipmentId());
399     if (GetEquipmentAttributes()) {
400       printf(" attributes = %8.8x %8.8x %8.8x  ", GetEquipmentAttributes()[2],
401              GetEquipmentAttributes()[1], GetEquipmentAttributes()[0]);
402     } else {
403       printf(" attributes = -------- -------- --------  ");
404     }
405     printf("element size = %d\n", GetEquipmentElementSize());
406
407     printf("data header:\n"
408            " size = %d  version = %d  valid = %d  compression = %d\n",
409            GetDataSize(), GetVersion(), IsValid(), IsCompressed());
410
411     printf("\n");
412     if (limit == 0) continue;
413
414     Int_t size = GetDataSize();
415     char line[70];
416     for (Int_t i = 0; i < 70; i++) line[i] = ' ';
417     line[69] = '\0';
418     Int_t pos = 0;
419     Int_t max = 16;
420     UChar_t byte;
421
422     for (Int_t n = 0; n < size; n++) {
423       if (!ReadNextChar(byte)) {
424         Error("DumpData", "couldn't read byte number %d\n", n);
425         break;
426       }
427       if (pos >= max) {
428         printf("%8.8x  %s\n", n-pos, line);
429         for (Int_t i = 0; i < 70; i++) line[i] = ' ';
430         line[69] = '\0';
431         pos = 0;
432         if ((limit > 0) && (n/max == limit)) {
433           Int_t nContinue = ((size-1)/max+1-limit) * max;
434           if (nContinue > n) {
435             printf(" [skipping %d bytes]\n", nContinue-n);
436             n = nContinue-1;
437             continue;
438           }
439         }
440       }
441       Int_t offset = pos/4;
442       if ((byte > 0x20) && (byte < 0x7f)) {
443         line[pos+offset] = byte;
444       } else {
445         line[pos+offset] = '.';
446       }
447       char hex[3];
448       sprintf(hex, "%2.2x", byte);
449       line[max+max/4+3+2*pos+offset] = hex[0];
450       line[max+max/4+4+2*pos+offset] = hex[1];
451       pos++;
452     }
453
454     if (pos > 0) printf("%8.8x  %s\n", size-pos, line);
455     printf("\n");
456            
457   } while (ReadHeader());
458 }
459
460 void AliRawReader::AddErrorLog(AliRawDataErrorLog::ERawDataErrorLevel level,
461                                Int_t code,
462                                const char *message)
463 {
464   // Add a raw data error message to the list
465   // of raw-data decoding errors
466   if (fEventNumber < 0) {
467     AliError("No events have read so far! Impossible to add a raw data error log!");
468     return;
469   }
470   Int_t ddlId = GetDDLID();
471   if (ddlId < 0) {
472     AliError("No ddl raw data have been read so far! Impossible to add a raw data error log!");
473     return;
474   }
475
476   new (fErrorLogs[fErrorLogs.GetEntriesFast()])
477     AliRawDataErrorLog(fEventNumber,
478                        ddlId,
479                        level,
480                        code,
481                        message);
482 }