Adding helper functions to define 2012 pp data PS and online trigger selection
[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
714281ef 40using std::ios;
04fa961a 41ClassImp(AliRawReaderFile)
42
43
39f9963f 44AliRawReaderFile::AliRawReaderFile(Int_t eventNumber) :
dd9a70fe 45 fEventIndex(eventNumber),
46 fDirName("."),
39f9963f 47 fDirectory(NULL),
48 fStream(NULL),
49 fEquipmentId(-1),
50 fBuffer(NULL),
1c10cde6 51 fBufferSize(0),
df3a33be 52 fEquipmentSize(0),
53 fDDLIndex(NULL),
be974aae 54 fDDLCurrent(-1),
55 fType(7),
56 fRunNb(0),
57 fDetectorPattern(0),
58 fTimestamp(0)
04fa961a 59{
39f9963f 60// create an object to read digits from the given event
dd9a70fe 61// in the current directory
04fa961a 62
dd9a70fe 63 fDirectory = OpenDirectory();
a97af23d 64 if (!fDirectory) fIsValid = kFALSE;
65 if (!OpenNextFile()) fIsValid = kFALSE;
39f9963f 66 fHeader = new AliRawDataHeader;
be974aae 67
68 fId[0] = fId[1] = 0;
69 fTriggerPattern[0] = fTriggerPattern[1] = 0;
39f9963f 70}
71
dd9a70fe 72AliRawReaderFile::AliRawReaderFile(const char* dirName, Int_t eventNumber) :
73 fEventIndex(eventNumber),
39f9963f 74 fDirName(dirName),
75 fDirectory(NULL),
76 fStream(NULL),
77 fEquipmentId(-1),
78 fBuffer(NULL),
1c10cde6 79 fBufferSize(0),
df3a33be 80 fEquipmentSize(0),
81 fDDLIndex(NULL),
be974aae 82 fDDLCurrent(-1),
83 fType(7),
84 fRunNb(0),
85 fDetectorPattern(0),
86 fTimestamp(0)
39f9963f 87{
88// create an object to read digits from the given directory
89
dd9a70fe 90 fDirectory = OpenDirectory();
a97af23d 91 if (!fDirectory) fIsValid = kFALSE;
36af91c9 92 if (fEventIndex >= 0 && (!OpenNextFile())) fIsValid = kFALSE;
39f9963f 93 fHeader = new AliRawDataHeader;
be974aae 94
95 fId[0] = fId[1] = 0;
96 fTriggerPattern[0] = fTriggerPattern[1] = 0;
04fa961a 97}
98
99AliRawReaderFile::~AliRawReaderFile()
100{
101// close the input file
102
39f9963f 103 if (fDirectory) gSystem->FreeDirectory(fDirectory);
04fa961a 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 }
1c10cde6 112 if (fHeader) delete fHeader;
04fa961a 113 if (fBuffer) delete[] fBuffer;
df3a33be 114 if (fDDLIndex) delete fDDLIndex; fDDLIndex=NULL;
04fa961a 115}
116
299738b9 117void 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
1c10cde6 122 if (!required) {
839d0155 123 Warning("AliRawReaderFile","Reading of raw data without raw data header!");
1c10cde6 124 if (fHeader) delete fHeader;
125 fHeader = NULL;
126 }
127 else {
128 if (!fHeader) fHeader = new AliRawDataHeader;
129 }
299738b9 130
131 AliRawReader::RequireHeader(required);
132}
04fa961a 133
dd9a70fe 134TString 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
146void* 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
df3a33be 158Bool_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;
41627f6d 169 while ((entry = gSystem->GetDirEntry(fDirectory))) {
df3a33be 170 const char* filename=entry.Data();
171 if (!filename || entry.IsNull()) break;
3fbd60fe 172 if (entry.BeginsWith("run")) {
173 entry.ReplaceAll("run","");
174 fRunNb = entry.Atoi();
175 continue;
176 }
df3a33be 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());
4ba28796 182 Int_t ddlIndex = -1;
183 fDetectorPattern |= (1 << AliDAQ::DetectorIDFromDdlID(equipmentId,ddlIndex));
df3a33be 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
04fa961a 194Bool_t AliRawReaderFile::OpenNextFile()
195{
42d20574 196// open the next file
197// returns kFALSE if the current file is the last one
198
df3a33be 199 if (!fDDLIndex && !CreateFileIndex()) return kFALSE;
200 if (fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>fEquipmentId)
201 fDDLCurrent=fSelectMinEquipmentId-1;
202
04fa961a 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;
39f9963f 211 fEquipmentId = -1;
1c10cde6 212 fEquipmentSize = 0;
04fa961a 213 }
04fa961a 214
39f9963f 215 if (!fDirectory) return kFALSE;
df3a33be 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);
dd9a70fe 222 char* fileName = gSystem->ConcatFileName(GetDirName(), entry);
df3a33be 223 if (!fileName) continue;
be974aae 224 // read the timestamp
225 FileStat_t buf;
226 if (gSystem->GetPathInfo(fileName,buf) == 0) {
227 fTimestamp = buf.fMtime;
228 }
04fa961a 229#ifndef __DECCXX
39f9963f 230 fStream = new fstream(fileName, ios::binary|ios::in);
04fa961a 231#else
39f9963f 232 fStream = new fstream(fileName, ios::in);
04fa961a 233#endif
df3a33be 234 delete [] fileName;
39f9963f 235 break;
236 }
237
238 if (!fStream) return kFALSE;
df3a33be 239 fEquipmentId = fDDLCurrent;
04fa961a 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
39f9963f 248Bool_t AliRawReaderFile::ReadHeader()
04fa961a 249{
39f9963f 250// read a data header at the current stream position
04fa961a 251// returns kFALSE if the mini header could not be read
252
df3a33be 253 if (!fStream && !OpenNextFile()) return kFALSE;
04fa961a 254 do {
255 if (fCount > 0) fStream->seekg(Int_t(fStream->tellg()) + fCount);
1c10cde6 256 if (fHeader) {
257 while (!fStream->read((char*) fHeader, sizeof(AliRawDataHeader))) {
258 if (!OpenNextFile()) return kFALSE;
259 }
04fa961a 260 }
cdd735d9 261 else {
262 if (fStream->eof())
263 if (!OpenNextFile()) return kFALSE;
264 }
1c10cde6 265 if (fHeader && fHeader->fSize != 0xFFFFFFFF) {
39f9963f 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 }
1c10cde6 273 fEquipmentSize = fCount;
274 if (fHeader) fEquipmentSize += sizeof(AliRawDataHeader);
04fa961a 275 } while (!IsSelected());
276 return kTRUE;
277}
278
279Bool_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) {
39f9963f 285 if (!ReadHeader()) return kFALSE;
04fa961a 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
302Bool_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
316Bool_t AliRawReaderFile::Reset()
317{
dd9a70fe 318// reset the current stream position to the first DDL file of the curevent
04fa961a 319
dd9a70fe 320 void* directory = OpenDirectory();
321 if (!directory) return kFALSE;
39f9963f 322
323 if (fStream) {
04fa961a 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;
04fa961a 331 }
332
39f9963f 333 if (fDirectory) gSystem->FreeDirectory(fDirectory);
334 fDirectory = directory;
04fa961a 335
df3a33be 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 /*
39f9963f 346 OpenNextFile();
df3a33be 347 */
348 fEquipmentId=-1;
349 fDDLCurrent=-1;
04fa961a 350 fCount = 0;
351 return kTRUE;
352}
353
dd9a70fe 354Bool_t AliRawReaderFile::NextEvent()
355{
356// go to the next event directory
357
df3a33be 358 if (fDDLIndex) delete fDDLIndex;
359 fDDLIndex=NULL;
4ba28796 360 fDetectorPattern = 0;
dd9a70fe 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
be974aae 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
38cf12f3 387 fEventNumber++;
388
dd9a70fe 389 return kTRUE;
390}
391
392Bool_t AliRawReaderFile::RewindEvents()
393{
394// reset the event counter
395
396 if (fEventIndex >= 0) fEventIndex = -1;
38cf12f3 397 fEventNumber = -1;
dd9a70fe 398 return Reset();
399}