]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RAW/AliRawReaderFile.cxx
ALIROOT-5677 Modification of dateStream to take into account CDH v3
[u/mrichter/AliRoot.git] / RAW / AliRawReaderFile.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 a class for reading raw data files.
21 ///
22 /// The files of one event are expected to be in one directory. The name 
23 /// of the directory is "raw" + the event number. Each file contains
24 /// the raw data (with data header) of one DDL. The convention for the
25 /// file names is "DET_#DDL.ddl". "DET" is the name of the detector and
26 /// "#DDL" is the unique equipment ID.
27 ///
28 /// The constructor of AliRawReaderFile takes the event number or the
29 /// directory name as argument.
30 /// 
31 ///////////////////////////////////////////////////////////////////////////////
32
33 #include <cstdlib>
34 #include "AliRawReaderFile.h"
35 #include "AliDAQ.h"
36 #include <TSystem.h>
37 #include <TArrayC.h>
38
39
40 using std::ios;
41 ClassImp(AliRawReaderFile)
42
43
44 AliRawReaderFile::AliRawReaderFile(Int_t eventNumber) :
45   fEventIndex(eventNumber),
46   fDirName("."),
47   fDirectory(NULL),
48   fStream(NULL),
49   fEquipmentId(-1),
50   fBuffer(NULL),
51   fBufferSize(0),
52   fEquipmentSize(0),
53   fDDLIndex(NULL),
54   fDDLCurrent(-1),
55   fType(7),
56   fRunNb(0),
57   fDetectorPattern(0),
58   fTimestamp(0)
59 {
60 // create an object to read digits from the given event
61 // in the current directory
62
63   fDirectory = OpenDirectory();
64   if (!fDirectory) fIsValid = kFALSE;
65   if (!OpenNextFile()) fIsValid = kFALSE;
66
67   fId[0] = fId[1] = 0;
68   fTriggerPattern[0] = fTriggerPattern[1] = fTriggerPattern[3] = fTriggerPattern[3] = 0;
69 }
70
71 AliRawReaderFile::AliRawReaderFile(const char* dirName, Int_t eventNumber) :
72   fEventIndex(eventNumber),
73   fDirName(dirName),
74   fDirectory(NULL),
75   fStream(NULL),
76   fEquipmentId(-1),
77   fBuffer(NULL),
78   fBufferSize(0),
79   fEquipmentSize(0),
80   fDDLIndex(NULL),
81   fDDLCurrent(-1),
82   fType(7),
83   fRunNb(0),
84   fDetectorPattern(0),
85   fTimestamp(0)
86 {
87 // create an object to read digits from the given directory
88
89   fDirectory = OpenDirectory();
90   if (!fDirectory) fIsValid = kFALSE;
91   if (fEventIndex >= 0 && (!OpenNextFile())) fIsValid = kFALSE;
92
93   fId[0] = fId[1] = 0;
94   fTriggerPattern[0] = fTriggerPattern[1] = fTriggerPattern[3] = fTriggerPattern[3] = 0;
95 }
96
97 AliRawReaderFile::~AliRawReaderFile()
98 {
99 // close the input file
100
101   if (fDirectory) gSystem->FreeDirectory(fDirectory);
102   if (fStream) {
103 #if defined(__HP_aCC) || defined(__DECCXX)
104     if (fStream->rdbuf()->is_open()) fStream->close();
105 #else
106     if (fStream->is_open()) fStream->close();
107 #endif
108     delete fStream;
109   }
110   if (fHeader) delete fHeader;
111   if (fHeaderV3) delete fHeaderV3;
112
113   if (fBuffer) delete[] fBuffer;
114   if (fDDLIndex) delete fDDLIndex; fDDLIndex=NULL;
115 }
116
117 void AliRawReaderFile::RequireHeader(Bool_t required)
118 {
119   // Reading of raw data in case of missing
120   // raw data header is not implemented for
121   // this class
122   if (!required) {
123     Warning("AliRawReaderFile","Reading of raw data without raw data header!");
124     if (fHeader) delete fHeader;
125     if (fHeaderV3) delete fHeaderV3;
126     fHeader = NULL;
127     fHeaderV3 = NULL;
128   }
129
130   AliRawReader::RequireHeader(required);
131 }
132
133 TString AliRawReaderFile::GetDirName() const
134 {
135 // return the current directory name
136
137   TString dirName(fDirName);
138   if (fEventIndex >= 0) {
139     dirName += "/raw";
140     dirName += fEventIndex;
141   }
142   return dirName;
143 }
144
145 void* AliRawReaderFile::OpenDirectory()
146 {
147 // open and return the directory
148
149   TString dirName = GetDirName();
150   void* directory = gSystem->OpenDirectory(dirName);
151   if (!directory) {
152     Error("OpenDirectory", "could not open directory %s", dirName.Data());
153   }
154   return directory;
155 }
156
157 Bool_t AliRawReaderFile::CreateFileIndex()
158 {
159 // scan the files of the directory and create index of all DDL files
160 // returns kFALSE if no DDL files available
161   Bool_t result=kFALSE;
162   fDDLCurrent=-1;
163   if (fDDLIndex) return fDDLIndex->GetSize()>0;
164   if (!fDirectory) return kFALSE;
165   fDDLIndex=new TArrayC(0);
166   if (!fDDLIndex) return kFALSE;
167   TString entry;
168   while ((entry = gSystem->GetDirEntry(fDirectory))) {
169     const char* filename=entry.Data();
170     if (!filename || entry.IsNull()) break;
171     if (entry.BeginsWith("run")) {
172       entry.ReplaceAll("run","");
173       fRunNb = entry.Atoi();
174       continue;
175     }
176     if (!entry.EndsWith(".ddl")) continue;
177     result=kTRUE;
178     entry.Remove(0, entry.Last('_')+1);
179     entry.Remove(entry.Length()-4);
180     Int_t equipmentId = atoi(entry.Data());
181     Int_t ddlIndex = -1;
182     fDetectorPattern |= (1 << AliDAQ::DetectorIDFromDdlID(equipmentId,ddlIndex));
183     if (fDDLIndex->GetSize()<=equipmentId) {
184       fDDLIndex->Set(equipmentId+1);
185     }
186     char* array=(char*)fDDLIndex->GetArray();
187     array[equipmentId]=1;
188   }
189
190   return result;
191 }
192
193 Bool_t AliRawReaderFile::OpenNextFile()
194 {
195 // open the next file
196 // returns kFALSE if the current file is the last one
197
198   if (!fDDLIndex && !CreateFileIndex()) return kFALSE;
199   if (fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>fEquipmentId)
200     fDDLCurrent=fSelectMinEquipmentId-1;
201
202   if (fStream) {
203 #if defined(__HP_aCC) || defined(__DECCXX)
204     if (fStream->rdbuf()->is_open()) fStream->close();
205 #else
206     if (fStream->is_open()) fStream->close();
207 #endif
208     delete fStream;
209     fStream = NULL;
210     fEquipmentId = -1;
211     fEquipmentSize = 0;
212   }
213
214   if (!fDirectory) return kFALSE;
215   while (++fDDLCurrent<(fDDLIndex->GetSize()) && 
216          (fDDLCurrent<=fSelectMaxEquipmentId || fSelectMaxEquipmentId<0)) {
217     if (fDDLIndex->At(fDDLCurrent)==0) continue;
218     Int_t dummy=0;
219     TString entry;
220     entry.Form("%s_%d.ddl", AliDAQ::DetectorNameFromDdlID(fDDLCurrent, dummy), fDDLCurrent);
221     char* fileName = gSystem->ConcatFileName(GetDirName(), entry);
222     if (!fileName) continue;
223     // read the timestamp
224     FileStat_t buf;
225     if (gSystem->GetPathInfo(fileName,buf) == 0) {
226       fTimestamp = buf.fMtime;
227     }
228 #ifndef __DECCXX 
229     fStream = new fstream(fileName, ios::binary|ios::in);
230 #else
231     fStream = new fstream(fileName, ios::in);
232 #endif
233     delete [] fileName;
234     break;
235   }
236
237   if (!fStream) return kFALSE;
238   fEquipmentId = fDDLCurrent;
239 #if defined(__HP_aCC) || defined(__DECCXX)
240   return (fStream->rdbuf()->is_open());
241 #else
242   return (fStream->is_open());
243 #endif
244 }
245
246
247 Bool_t AliRawReaderFile::ReadHeader()
248 {
249 // read a data header at the current stream position
250 // returns kFALSE if the mini header could not be read
251
252   if (!fStream && !OpenNextFile()) return kFALSE;
253   do {
254     UInt_t dataSize=0;
255     UInt_t headerSize=0;
256     if (fCount > 0) fStream->seekg(Int_t(fStream->tellg()) + fCount);
257     UInt_t currentPos = fStream->tellg();
258     if (fRequireHeader) {
259       if(! fHeader) fHeader = new AliRawDataHeader;
260       while (!fStream->read((char*) fHeader, sizeof(AliRawDataHeader))) {
261         if (!OpenNextFile()) return kFALSE;
262         currentPos = fStream->tellg();
263       }
264       dataSize=fHeader->fSize;
265       headerSize=sizeof(AliRawDataHeader);
266       if(fHeader->GetVersion() == 3){
267         delete fHeader;
268         fHeader = NULL;
269         if(! fHeaderV3) fHeaderV3 = new AliRawDataHeaderV3;
270         //rewind
271         fStream->seekg(currentPos);
272         if (!fStream->read((char*) fHeaderV3, sizeof(AliRawDataHeaderV3)))
273           return kFALSE;
274         headerSize=sizeof(AliRawDataHeaderV3);
275       } else if (fHeaderV3) {
276         delete fHeaderV3;
277         fHeaderV3 = NULL;
278       }
279       
280     }
281     else {
282       if (fStream->eof())
283         if (!OpenNextFile()) return kFALSE;
284     }
285     if ( headerSize && dataSize != 0xFFFFFFFF) {
286       fCount = dataSize - headerSize;
287     } else {
288       currentPos = fStream->tellg();
289       fStream->seekg(0, ios::end);
290       fCount = UInt_t(fStream->tellg()) - currentPos;
291       fStream->seekg(currentPos);
292     }
293     fEquipmentSize = fCount + headerSize;
294   } while (!IsSelected());
295   return kTRUE;
296 }
297
298 Bool_t AliRawReaderFile::ReadNextData(UChar_t*& data)
299 {
300 // reads the next payload at the current stream position
301 // returns kFALSE if the data could not be read
302
303   while (fCount == 0) {
304     if (!ReadHeader()) return kFALSE;
305   }
306   if (fBufferSize < fCount) {
307     if (fBuffer) delete[] fBuffer;
308     fBufferSize = Int_t(fCount*1.2);
309     fBuffer = new UChar_t[fBufferSize];
310   }
311   if (!fStream->read((char*) fBuffer, fCount)) {
312     Error("ReadNext", "could not read data!");
313     return kFALSE;
314   }
315   fCount = 0;
316
317   data = fBuffer;
318   return kTRUE;
319 }
320
321 Bool_t AliRawReaderFile::ReadNext(UChar_t* data, Int_t size)
322 {
323 // reads the next block of data at the current stream position
324 // returns kFALSE if the data could not be read
325
326   if (!fStream->read((char*) data, size)) {
327     Error("ReadNext", "could not read data!");
328     return kFALSE;
329   }
330   fCount -= size;
331   return kTRUE;
332 }
333
334
335 Bool_t AliRawReaderFile::Reset()
336 {
337 // reset the current stream position to the first DDL file of the curevent
338
339   void* directory = OpenDirectory();
340   if (!directory) return kFALSE;
341
342   if (fStream) {
343 #if defined(__HP_aCC) || defined(__DECCXX)
344     if (fStream->rdbuf()->is_open()) fStream->close();
345 #else
346     if (fStream->is_open()) fStream->close();
347 #endif
348     delete fStream;
349     fStream = NULL;
350   }
351
352   if (fDirectory) gSystem->FreeDirectory(fDirectory);
353   fDirectory = directory;
354
355   // Matthias 05.06.2008
356   // do not open the next file. That might collide with a subsequent
357   // SelectEquipment call as the 'file pointer' is already set.
358   // This is important for the indexing of the DDL files.
359   // ---------------------------------------------------------
360   // All ReadNext functions first require the fCount member to be
361   // non zero or call ReadHeader. That allows to postpone the call
362   // to OpenNextFile to the next invocation of ReadHeader.
363   // ReadHeader has been mofified according to that.
364   /*
365   OpenNextFile();
366   */
367   fEquipmentId=-1;
368   fDDLCurrent=-1;
369   fCount = 0;
370   return kTRUE;
371 }
372
373 Bool_t AliRawReaderFile::NextEvent()
374 {
375 // go to the next event directory
376
377   if (fDDLIndex) delete fDDLIndex;
378   fDDLIndex=NULL;
379   fDetectorPattern = 0;
380   if (fEventIndex < -1) return kFALSE;
381
382   do {
383     TString dirName = fDirName + "/raw";
384     dirName += (fEventIndex + 1);
385     void* directory = gSystem->OpenDirectory(dirName);
386     if (!directory) return kFALSE;
387     gSystem->FreeDirectory(directory);
388
389     fEventIndex++;
390     Reset();
391   } while (!IsEventSelected());
392
393   // Read the header of the first payload
394   // in order to fill the 'fake' event header
395   if (ReadHeader() && ( fHeader || fHeaderV3) ) {
396     UInt_t eid1=0, eid2=0;
397     ULong64_t trg1=0, trg2=0;
398     if(fHeader){
399       eid1=fHeader->GetEventID1();
400       eid2=fHeader->GetEventID2();
401       trg1=fHeader->GetTriggerClasses();
402     } else {
403       eid1=fHeaderV3->GetEventID1();
404       eid2=fHeaderV3->GetEventID2();
405       trg1=fHeaderV3->GetTriggerClasses();
406       trg2=fHeaderV3->GetTriggerClassesNext50();
407     }
408
409     fId[0] = ((eid2 >> 20) & 0xf);
410     fId[1] = (eid1 & 0xfff) | ((eid2 & 0xfffff) << 12);
411     fTriggerPattern[0] = (trg1 & 0xffffffff);
412     fTriggerPattern[1] = ((trg1 >> 32) & 0x3ffff) | ((trg2 & 0x3fff) << 18);
413     fTriggerPattern[2] = ((trg2 >> 14) & 0xffffffff);
414     fTriggerPattern[3] = ((trg2 >> 46) & 0xf);
415   }
416   else {
417     Warning("AliRawReaderFile","Can not read CDH header! The event header fields will be empty!");
418   }
419   Reset();
420
421   fEventNumber++;
422
423   return kTRUE;
424 }
425
426 Bool_t AliRawReaderFile::RewindEvents()
427 {
428 // reset the event counter
429
430   if (fEventIndex >= 0)  fEventIndex = -1;
431   fEventNumber = -1;
432   return Reset();
433 }