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