Bugfix in raw data reader classes. The bug affected the determination of the raw...
[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 "AliRawReaderFile.h"
34 #include <TSystem.h>
35
36
37 ClassImp(AliRawReaderFile)
38
39
40 AliRawReaderFile::AliRawReaderFile(Int_t eventNumber) :
41   fEventIndex(eventNumber),
42   fDirName("."),
43   fDirectory(NULL),
44   fStream(NULL),
45   fEquipmentId(-1),
46   fBuffer(NULL),
47   fBufferSize(0)
48 {
49 // create an object to read digits from the given event
50 // in the current directory
51
52   fDirectory = OpenDirectory();
53   OpenNextFile();
54   fHeader = new AliRawDataHeader;
55 }
56
57 AliRawReaderFile::AliRawReaderFile(const char* dirName, Int_t eventNumber) :
58   fEventIndex(eventNumber),
59   fDirName(dirName),
60   fDirectory(NULL),
61   fStream(NULL),
62   fEquipmentId(-1),
63   fBuffer(NULL),
64   fBufferSize(0)
65 {
66 // create an object to read digits from the given directory
67
68   fDirectory = OpenDirectory();
69   OpenNextFile();
70   fHeader = new AliRawDataHeader;
71 }
72
73 AliRawReaderFile::AliRawReaderFile(const AliRawReaderFile& rawReader) :
74   AliRawReader(rawReader)
75 {
76   Fatal("AliRawReaderFile", "copy constructor not implemented");
77 }
78
79 AliRawReaderFile& AliRawReaderFile::operator = (const AliRawReaderFile& 
80                                               /* rawReader */)
81 {
82   Fatal("operator =", "assignment operator not implemented");
83   return *this;
84 }
85
86 AliRawReaderFile::~AliRawReaderFile()
87 {
88 // close the input file
89
90   if (fDirectory) gSystem->FreeDirectory(fDirectory);
91   if (fStream) {
92 #if defined(__HP_aCC) || defined(__DECCXX)
93     if (fStream->rdbuf()->is_open()) fStream->close();
94 #else
95     if (fStream->is_open()) fStream->close();
96 #endif
97     delete fStream;
98   }
99   delete fHeader;
100   if (fBuffer) delete[] fBuffer;
101 }
102
103 void AliRawReaderFile::RequireHeader(Bool_t required)
104 {
105   // Reading of raw data in case of missing
106   // raw data header is not implemented for
107   // this class
108   if (!required)
109     Fatal("AliRawReaderFile","Reading of raw data without raw data header is not implemented !");
110
111   AliRawReader::RequireHeader(required);
112 }
113
114 TString AliRawReaderFile::GetDirName() const
115 {
116 // return the current directory name
117
118   TString dirName(fDirName);
119   if (fEventIndex >= 0) {
120     dirName += "/raw";
121     dirName += fEventIndex;
122   }
123   return dirName;
124 }
125
126 void* AliRawReaderFile::OpenDirectory()
127 {
128 // open and return the directory
129
130   TString dirName = GetDirName();
131   void* directory = gSystem->OpenDirectory(dirName);
132   if (!directory) {
133     Error("OpenDirectory", "could not open directory %s", dirName.Data());
134   }
135   return directory;
136 }
137
138 Bool_t AliRawReaderFile::OpenNextFile()
139 {
140 // open the next file
141 // returns kFALSE if the current file is the last one
142
143   if (fStream) {
144 #if defined(__HP_aCC) || defined(__DECCXX)
145     if (fStream->rdbuf()->is_open()) fStream->close();
146 #else
147     if (fStream->is_open()) fStream->close();
148 #endif
149     delete fStream;
150     fStream = NULL;
151     fEquipmentId = -1;
152   }
153
154   if (!fDirectory) return kFALSE;
155   TString entry;
156   while (entry = gSystem->GetDirEntry(fDirectory)) {
157     if (entry.IsNull()) return kFALSE;
158     if (!entry.EndsWith(".ddl")) continue;
159     char* fileName = gSystem->ConcatFileName(GetDirName(), entry);
160 #ifndef __DECCXX 
161     fStream = new fstream(fileName, ios::binary|ios::in);
162 #else
163     fStream = new fstream(fileName, ios::in);
164 #endif
165     break;
166   }
167
168   if (!fStream) return kFALSE;
169   entry.Remove(0, entry.Last('_')+1);
170   entry.Remove(entry.Length()-4);
171   fEquipmentId = atoi(entry.Data());
172 #if defined(__HP_aCC) || defined(__DECCXX)
173   return (fStream->rdbuf()->is_open());
174 #else
175   return (fStream->is_open());
176 #endif
177 }
178
179
180 Bool_t AliRawReaderFile::ReadHeader()
181 {
182 // read a data header at the current stream position
183 // returns kFALSE if the mini header could not be read
184
185   if (!fStream) return kFALSE;
186   do {
187     if (fCount > 0) fStream->seekg(Int_t(fStream->tellg()) + fCount);
188     while (!fStream->read((char*) fHeader, sizeof(AliRawDataHeader))) {
189       if (!OpenNextFile()) return kFALSE;
190     }
191     if (fHeader->fSize != 0xFFFFFFFF) {
192       fCount = fHeader->fSize - sizeof(AliRawDataHeader);
193     } else {
194       UInt_t currentPos = fStream->tellg();
195       fStream->seekg(0, ios::end);
196       fCount = UInt_t(fStream->tellg()) - currentPos;
197       fStream->seekg(currentPos);
198     }
199   } while (!IsSelected());
200   return kTRUE;
201 }
202
203 Bool_t AliRawReaderFile::ReadNextData(UChar_t*& data)
204 {
205 // reads the next payload at the current stream position
206 // returns kFALSE if the data could not be read
207
208   while (fCount == 0) {
209     if (!ReadHeader()) return kFALSE;
210   }
211   if (fBufferSize < fCount) {
212     if (fBuffer) delete[] fBuffer;
213     fBufferSize = Int_t(fCount*1.2);
214     fBuffer = new UChar_t[fBufferSize];
215   }
216   if (!fStream->read((char*) fBuffer, fCount)) {
217     Error("ReadNext", "could not read data!");
218     return kFALSE;
219   }
220   fCount = 0;
221
222   data = fBuffer;
223   return kTRUE;
224 }
225
226 Bool_t AliRawReaderFile::ReadNext(UChar_t* data, Int_t size)
227 {
228 // reads the next block of data at the current stream position
229 // returns kFALSE if the data could not be read
230
231   if (!fStream->read((char*) data, size)) {
232     Error("ReadNext", "could not read data!");
233     return kFALSE;
234   }
235   fCount -= size;
236   return kTRUE;
237 }
238
239
240 Bool_t AliRawReaderFile::Reset()
241 {
242 // reset the current stream position to the first DDL file of the curevent
243
244   void* directory = OpenDirectory();
245   if (!directory) return kFALSE;
246
247   if (fStream) {
248 #if defined(__HP_aCC) || defined(__DECCXX)
249     if (fStream->rdbuf()->is_open()) fStream->close();
250 #else
251     if (fStream->is_open()) fStream->close();
252 #endif
253     delete fStream;
254     fStream = NULL;
255   }
256
257   if (fDirectory) gSystem->FreeDirectory(fDirectory);
258   fDirectory = directory;
259
260   OpenNextFile();
261   fCount = 0;
262   return kTRUE;
263 }
264
265 Bool_t AliRawReaderFile::NextEvent()
266 {
267 // go to the next event directory
268
269   if (fEventIndex < -1) return kFALSE;
270
271   do {
272     TString dirName = fDirName + "/raw";
273     dirName += (fEventIndex + 1);
274     void* directory = gSystem->OpenDirectory(dirName);
275     if (!directory) return kFALSE;
276     gSystem->FreeDirectory(directory);
277
278     fEventIndex++;
279     Reset();
280   } while (!IsEventSelected());
281
282   return kTRUE;
283 }
284
285 Bool_t AliRawReaderFile::RewindEvents()
286 {
287 // reset the event counter
288
289   if (fEventIndex >= 0)  fEventIndex = -1;
290   return Reset();
291 }