]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RAW/AliRawReaderFile.cxx
Adding helper functions to define 2012 pp data PS and online trigger selection
[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   fHeader = new AliRawDataHeader;
67
68   fId[0] = fId[1] = 0;
69   fTriggerPattern[0] = fTriggerPattern[1] = 0;
70 }
71
72 AliRawReaderFile::AliRawReaderFile(const char* dirName, Int_t eventNumber) :
73   fEventIndex(eventNumber),
74   fDirName(dirName),
75   fDirectory(NULL),
76   fStream(NULL),
77   fEquipmentId(-1),
78   fBuffer(NULL),
79   fBufferSize(0),
80   fEquipmentSize(0),
81   fDDLIndex(NULL),
82   fDDLCurrent(-1),
83   fType(7),
84   fRunNb(0),
85   fDetectorPattern(0),
86   fTimestamp(0)
87 {
88 // create an object to read digits from the given directory
89
90   fDirectory = OpenDirectory();
91   if (!fDirectory) fIsValid = kFALSE;
92   if (fEventIndex >= 0 && (!OpenNextFile())) fIsValid = kFALSE;
93   fHeader = new AliRawDataHeader;
94
95   fId[0] = fId[1] = 0;
96   fTriggerPattern[0] = fTriggerPattern[1] = 0;
97 }
98
99 AliRawReaderFile::~AliRawReaderFile()
100 {
101 // close the input file
102
103   if (fDirectory) gSystem->FreeDirectory(fDirectory);
104   if (fStream) {
105 #if defined(__HP_aCC) || defined(__DECCXX)
106     if (fStream->rdbuf()->is_open()) fStream->close();
107 #else
108     if (fStream->is_open()) fStream->close();
109 #endif
110     delete fStream;
111   }
112   if (fHeader) delete fHeader;
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     fHeader = NULL;
126   }
127   else {
128     if (!fHeader) fHeader = new AliRawDataHeader;
129   }
130
131   AliRawReader::RequireHeader(required);
132 }
133
134 TString AliRawReaderFile::GetDirName() const
135 {
136 // return the current directory name
137
138   TString dirName(fDirName);
139   if (fEventIndex >= 0) {
140     dirName += "/raw";
141     dirName += fEventIndex;
142   }
143   return dirName;
144 }
145
146 void* AliRawReaderFile::OpenDirectory()
147 {
148 // open and return the directory
149
150   TString dirName = GetDirName();
151   void* directory = gSystem->OpenDirectory(dirName);
152   if (!directory) {
153     Error("OpenDirectory", "could not open directory %s", dirName.Data());
154   }
155   return directory;
156 }
157
158 Bool_t AliRawReaderFile::CreateFileIndex()
159 {
160 // scan the files of the directory and create index of all DDL files
161 // returns kFALSE if no DDL files available
162   Bool_t result=kFALSE;
163   fDDLCurrent=-1;
164   if (fDDLIndex) return fDDLIndex->GetSize()>0;
165   if (!fDirectory) return kFALSE;
166   fDDLIndex=new TArrayC(0);
167   if (!fDDLIndex) return kFALSE;
168   TString entry;
169   while ((entry = gSystem->GetDirEntry(fDirectory))) {
170     const char* filename=entry.Data();
171     if (!filename || entry.IsNull()) break;
172     if (entry.BeginsWith("run")) {
173       entry.ReplaceAll("run","");
174       fRunNb = entry.Atoi();
175       continue;
176     }
177     if (!entry.EndsWith(".ddl")) continue;
178     result=kTRUE;
179     entry.Remove(0, entry.Last('_')+1);
180     entry.Remove(entry.Length()-4);
181     Int_t equipmentId = atoi(entry.Data());
182     Int_t ddlIndex = -1;
183     fDetectorPattern |= (1 << AliDAQ::DetectorIDFromDdlID(equipmentId,ddlIndex));
184     if (fDDLIndex->GetSize()<=equipmentId) {
185       fDDLIndex->Set(equipmentId+1);
186     }
187     char* array=(char*)fDDLIndex->GetArray();
188     array[equipmentId]=1;
189   }
190
191   return result;
192 }
193
194 Bool_t AliRawReaderFile::OpenNextFile()
195 {
196 // open the next file
197 // returns kFALSE if the current file is the last one
198
199   if (!fDDLIndex && !CreateFileIndex()) return kFALSE;
200   if (fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>fEquipmentId)
201     fDDLCurrent=fSelectMinEquipmentId-1;
202
203   if (fStream) {
204 #if defined(__HP_aCC) || defined(__DECCXX)
205     if (fStream->rdbuf()->is_open()) fStream->close();
206 #else
207     if (fStream->is_open()) fStream->close();
208 #endif
209     delete fStream;
210     fStream = NULL;
211     fEquipmentId = -1;
212     fEquipmentSize = 0;
213   }
214
215   if (!fDirectory) return kFALSE;
216   while (++fDDLCurrent<(fDDLIndex->GetSize()) && 
217          (fDDLCurrent<=fSelectMaxEquipmentId || fSelectMaxEquipmentId<0)) {
218     if (fDDLIndex->At(fDDLCurrent)==0) continue;
219     Int_t dummy=0;
220     TString entry;
221     entry.Form("%s_%d.ddl", AliDAQ::DetectorNameFromDdlID(fDDLCurrent, dummy), fDDLCurrent);
222     char* fileName = gSystem->ConcatFileName(GetDirName(), entry);
223     if (!fileName) continue;
224     // read the timestamp
225     FileStat_t buf;
226     if (gSystem->GetPathInfo(fileName,buf) == 0) {
227       fTimestamp = buf.fMtime;
228     }
229 #ifndef __DECCXX 
230     fStream = new fstream(fileName, ios::binary|ios::in);
231 #else
232     fStream = new fstream(fileName, ios::in);
233 #endif
234     delete [] fileName;
235     break;
236   }
237
238   if (!fStream) return kFALSE;
239   fEquipmentId = fDDLCurrent;
240 #if defined(__HP_aCC) || defined(__DECCXX)
241   return (fStream->rdbuf()->is_open());
242 #else
243   return (fStream->is_open());
244 #endif
245 }
246
247
248 Bool_t AliRawReaderFile::ReadHeader()
249 {
250 // read a data header at the current stream position
251 // returns kFALSE if the mini header could not be read
252
253   if (!fStream && !OpenNextFile()) return kFALSE;
254   do {
255     if (fCount > 0) fStream->seekg(Int_t(fStream->tellg()) + fCount);
256     if (fHeader) {
257       while (!fStream->read((char*) fHeader, sizeof(AliRawDataHeader))) {
258         if (!OpenNextFile()) return kFALSE;
259       }
260     }
261     else {
262       if (fStream->eof())
263         if (!OpenNextFile()) return kFALSE;
264     }
265     if (fHeader && fHeader->fSize != 0xFFFFFFFF) {
266       fCount = fHeader->fSize - sizeof(AliRawDataHeader);
267     } else {
268       UInt_t currentPos = fStream->tellg();
269       fStream->seekg(0, ios::end);
270       fCount = UInt_t(fStream->tellg()) - currentPos;
271       fStream->seekg(currentPos);
272     }
273     fEquipmentSize = fCount;
274     if (fHeader) fEquipmentSize += sizeof(AliRawDataHeader);
275   } while (!IsSelected());
276   return kTRUE;
277 }
278
279 Bool_t AliRawReaderFile::ReadNextData(UChar_t*& data)
280 {
281 // reads the next payload at the current stream position
282 // returns kFALSE if the data could not be read
283
284   while (fCount == 0) {
285     if (!ReadHeader()) return kFALSE;
286   }
287   if (fBufferSize < fCount) {
288     if (fBuffer) delete[] fBuffer;
289     fBufferSize = Int_t(fCount*1.2);
290     fBuffer = new UChar_t[fBufferSize];
291   }
292   if (!fStream->read((char*) fBuffer, fCount)) {
293     Error("ReadNext", "could not read data!");
294     return kFALSE;
295   }
296   fCount = 0;
297
298   data = fBuffer;
299   return kTRUE;
300 }
301
302 Bool_t AliRawReaderFile::ReadNext(UChar_t* data, Int_t size)
303 {
304 // reads the next block of data at the current stream position
305 // returns kFALSE if the data could not be read
306
307   if (!fStream->read((char*) data, size)) {
308     Error("ReadNext", "could not read data!");
309     return kFALSE;
310   }
311   fCount -= size;
312   return kTRUE;
313 }
314
315
316 Bool_t AliRawReaderFile::Reset()
317 {
318 // reset the current stream position to the first DDL file of the curevent
319
320   void* directory = OpenDirectory();
321   if (!directory) return kFALSE;
322
323   if (fStream) {
324 #if defined(__HP_aCC) || defined(__DECCXX)
325     if (fStream->rdbuf()->is_open()) fStream->close();
326 #else
327     if (fStream->is_open()) fStream->close();
328 #endif
329     delete fStream;
330     fStream = NULL;
331   }
332
333   if (fDirectory) gSystem->FreeDirectory(fDirectory);
334   fDirectory = directory;
335
336   // Matthias 05.06.2008
337   // do not open the next file. That might collide with a subsequent
338   // SelectEquipment call as the 'file pointer' is already set.
339   // This is important for the indexing of the DDL files.
340   // ---------------------------------------------------------
341   // All ReadNext functions first require the fCount member to be
342   // non zero or call ReadHeader. That allows to postpone the call
343   // to OpenNextFile to the next invocation of ReadHeader.
344   // ReadHeader has been mofified according to that.
345   /*
346   OpenNextFile();
347   */
348   fEquipmentId=-1;
349   fDDLCurrent=-1;
350   fCount = 0;
351   return kTRUE;
352 }
353
354 Bool_t AliRawReaderFile::NextEvent()
355 {
356 // go to the next event directory
357
358   if (fDDLIndex) delete fDDLIndex;
359   fDDLIndex=NULL;
360   fDetectorPattern = 0;
361   if (fEventIndex < -1) return kFALSE;
362
363   do {
364     TString dirName = fDirName + "/raw";
365     dirName += (fEventIndex + 1);
366     void* directory = gSystem->OpenDirectory(dirName);
367     if (!directory) return kFALSE;
368     gSystem->FreeDirectory(directory);
369
370     fEventIndex++;
371     Reset();
372   } while (!IsEventSelected());
373
374   // Read the header of the first payload
375   // in order to fill the 'fake' event header
376   if (ReadHeader() && fHeader) {
377     fId[0] = ((fHeader->GetEventID2() >> 20) & 0xf);
378     fId[1] = (fHeader->GetEventID1() & 0xfff) | ((fHeader->GetEventID2() & 0xfffff) << 12);
379     fTriggerPattern[0] = (fHeader->GetTriggerClasses() & 0xffffffff);
380     fTriggerPattern[1] = ((fHeader->GetTriggerClasses() >> 32) & 0x3ffff);
381   }
382   else {
383     Warning("AliRawReaderFile","Can not read CDH header! The event header fields will be empty!");
384   }
385   Reset();
386
387   fEventNumber++;
388
389   return kTRUE;
390 }
391
392 Bool_t AliRawReaderFile::RewindEvents()
393 {
394 // reset the event counter
395
396   if (fEventIndex >= 0)  fEventIndex = -1;
397   fEventNumber = -1;
398   return Reset();
399 }