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