1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 /// This is a class for reading raw data files.
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.
28 /// The constructor of AliRawReaderFile takes the event number or the
29 /// directory name as argument.
31 ///////////////////////////////////////////////////////////////////////////////
34 #include "AliRawReaderFile.h"
40 ClassImp(AliRawReaderFile)
43 AliRawReaderFile::AliRawReaderFile(Int_t eventNumber) :
44 fEventIndex(eventNumber),
59 // create an object to read digits from the given event
60 // in the current directory
62 fDirectory = OpenDirectory();
64 fHeader = new AliRawDataHeader;
67 fTriggerPattern[0] = fTriggerPattern[1] = 0;
70 AliRawReaderFile::AliRawReaderFile(const char* dirName, Int_t eventNumber) :
71 fEventIndex(eventNumber),
86 // create an object to read digits from the given directory
88 fDirectory = OpenDirectory();
90 fHeader = new AliRawDataHeader;
93 fTriggerPattern[0] = fTriggerPattern[1] = 0;
96 AliRawReaderFile::~AliRawReaderFile()
98 // close the input file
100 if (fDirectory) gSystem->FreeDirectory(fDirectory);
102 #if defined(__HP_aCC) || defined(__DECCXX)
103 if (fStream->rdbuf()->is_open()) fStream->close();
105 if (fStream->is_open()) fStream->close();
109 if (fHeader) delete fHeader;
110 if (fBuffer) delete[] fBuffer;
111 if (fDDLIndex) delete fDDLIndex; fDDLIndex=NULL;
114 void AliRawReaderFile::RequireHeader(Bool_t required)
116 // Reading of raw data in case of missing
117 // raw data header is not implemented for
120 Warning("AliRawReaderFile","Reading of raw data without raw data header!");
121 if (fHeader) delete fHeader;
125 if (!fHeader) fHeader = new AliRawDataHeader;
128 AliRawReader::RequireHeader(required);
131 TString AliRawReaderFile::GetDirName() const
133 // return the current directory name
135 TString dirName(fDirName);
136 if (fEventIndex >= 0) {
138 dirName += fEventIndex;
143 void* AliRawReaderFile::OpenDirectory()
145 // open and return the directory
147 TString dirName = GetDirName();
148 void* directory = gSystem->OpenDirectory(dirName);
150 Error("OpenDirectory", "could not open directory %s", dirName.Data());
155 Bool_t AliRawReaderFile::CreateFileIndex()
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;
161 if (fDDLIndex) return fDDLIndex->GetSize()>0;
162 if (!fDirectory) return kFALSE;
163 fDDLIndex=new TArrayC(0);
164 if (!fDDLIndex) return kFALSE;
166 while (entry = gSystem->GetDirEntry(fDirectory)) {
167 const char* filename=entry.Data();
168 if (!filename || entry.IsNull()) break;
169 if (!entry.EndsWith(".ddl")) continue;
171 entry.Remove(0, entry.Last('_')+1);
172 entry.Remove(entry.Length()-4);
173 Int_t equipmentId = atoi(entry.Data());
174 if (fDDLIndex->GetSize()<=equipmentId) {
175 fDDLIndex->Set(equipmentId+1);
177 char* array=(char*)fDDLIndex->GetArray();
178 array[equipmentId]=1;
184 Bool_t AliRawReaderFile::OpenNextFile()
186 // open the next file
187 // returns kFALSE if the current file is the last one
189 if (!fDDLIndex && !CreateFileIndex()) return kFALSE;
190 if (fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>fEquipmentId)
191 fDDLCurrent=fSelectMinEquipmentId-1;
194 #if defined(__HP_aCC) || defined(__DECCXX)
195 if (fStream->rdbuf()->is_open()) fStream->close();
197 if (fStream->is_open()) fStream->close();
205 if (!fDirectory) return kFALSE;
206 while (++fDDLCurrent<(fDDLIndex->GetSize()) &&
207 (fDDLCurrent<=fSelectMaxEquipmentId || fSelectMaxEquipmentId<0)) {
208 if (fDDLIndex->At(fDDLCurrent)==0) continue;
211 entry.Form("%s_%d.ddl", AliDAQ::DetectorNameFromDdlID(fDDLCurrent, dummy), fDDLCurrent);
212 char* fileName = gSystem->ConcatFileName(GetDirName(), entry);
213 if (!fileName) continue;
214 // read the timestamp
216 if (gSystem->GetPathInfo(fileName,buf) == 0) {
217 fTimestamp = buf.fMtime;
220 fStream = new fstream(fileName, ios::binary|ios::in);
222 fStream = new fstream(fileName, ios::in);
228 if (!fStream) return kFALSE;
229 fEquipmentId = fDDLCurrent;
230 #if defined(__HP_aCC) || defined(__DECCXX)
231 return (fStream->rdbuf()->is_open());
233 return (fStream->is_open());
238 Bool_t AliRawReaderFile::ReadHeader()
240 // read a data header at the current stream position
241 // returns kFALSE if the mini header could not be read
243 if (!fStream && !OpenNextFile()) return kFALSE;
245 if (fCount > 0) fStream->seekg(Int_t(fStream->tellg()) + fCount);
247 while (!fStream->read((char*) fHeader, sizeof(AliRawDataHeader))) {
248 if (!OpenNextFile()) return kFALSE;
253 if (!OpenNextFile()) return kFALSE;
255 if (fHeader && fHeader->fSize != 0xFFFFFFFF) {
256 fCount = fHeader->fSize - sizeof(AliRawDataHeader);
258 UInt_t currentPos = fStream->tellg();
259 fStream->seekg(0, ios::end);
260 fCount = UInt_t(fStream->tellg()) - currentPos;
261 fStream->seekg(currentPos);
263 fEquipmentSize = fCount;
264 if (fHeader) fEquipmentSize += sizeof(AliRawDataHeader);
265 } while (!IsSelected());
269 Bool_t AliRawReaderFile::ReadNextData(UChar_t*& data)
271 // reads the next payload at the current stream position
272 // returns kFALSE if the data could not be read
274 while (fCount == 0) {
275 if (!ReadHeader()) return kFALSE;
277 if (fBufferSize < fCount) {
278 if (fBuffer) delete[] fBuffer;
279 fBufferSize = Int_t(fCount*1.2);
280 fBuffer = new UChar_t[fBufferSize];
282 if (!fStream->read((char*) fBuffer, fCount)) {
283 Error("ReadNext", "could not read data!");
292 Bool_t AliRawReaderFile::ReadNext(UChar_t* data, Int_t size)
294 // reads the next block of data at the current stream position
295 // returns kFALSE if the data could not be read
297 if (!fStream->read((char*) data, size)) {
298 Error("ReadNext", "could not read data!");
306 Bool_t AliRawReaderFile::Reset()
308 // reset the current stream position to the first DDL file of the curevent
310 void* directory = OpenDirectory();
311 if (!directory) return kFALSE;
314 #if defined(__HP_aCC) || defined(__DECCXX)
315 if (fStream->rdbuf()->is_open()) fStream->close();
317 if (fStream->is_open()) fStream->close();
323 if (fDirectory) gSystem->FreeDirectory(fDirectory);
324 fDirectory = directory;
326 // Matthias 05.06.2008
327 // do not open the next file. That might collide with a subsequent
328 // SelectEquipment call as the 'file pointer' is already set.
329 // This is important for the indexing of the DDL files.
330 // ---------------------------------------------------------
331 // All ReadNext functions first require the fCount member to be
332 // non zero or call ReadHeader. That allows to postpone the call
333 // to OpenNextFile to the next invocation of ReadHeader.
334 // ReadHeader has been mofified according to that.
344 Bool_t AliRawReaderFile::NextEvent()
346 // go to the next event directory
348 if (fDDLIndex) delete fDDLIndex;
350 if (fEventIndex < -1) return kFALSE;
353 TString dirName = fDirName + "/raw";
354 dirName += (fEventIndex + 1);
355 void* directory = gSystem->OpenDirectory(dirName);
356 if (!directory) return kFALSE;
357 gSystem->FreeDirectory(directory);
361 } while (!IsEventSelected());
363 // Read the header of the first payload
364 // in order to fill the 'fake' event header
365 if (ReadHeader() && fHeader) {
366 fId[0] = ((fHeader->GetEventID2() >> 20) & 0xf);
367 fId[1] = (fHeader->GetEventID1() & 0xfff) | ((fHeader->GetEventID2() & 0xfffff) << 12);
368 fTriggerPattern[0] = (fHeader->GetTriggerClasses() & 0xffffffff);
369 fTriggerPattern[1] = ((fHeader->GetTriggerClasses() >> 32) & 0x3ffff);
372 Warning("AliRawReaderFile","Can not read CDH header! The event header fields will be empty!");
381 Bool_t AliRawReaderFile::RewindEvents()
383 // reset the event counter
385 if (fEventIndex >= 0) fEventIndex = -1;