]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - RAW/AliRawReaderFile.cxx
During simulation: fill STU region w/ non null time sums
[u/mrichter/AliRoot.git] / RAW / AliRawReaderFile.cxx
index 1b5edc3840ca95cdedcefafc1a35935cd73544e3..c379c0a6a978d1974d4456cdc1b11e8ee014e039 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
+/* $Id$ */
+
 ///////////////////////////////////////////////////////////////////////////////
-//
-// This is a class for reading a raw data file and providing
-// information about digits
-//
+/// 
+/// This is a class for reading raw data files.
+///
+/// The files of one event are expected to be in one directory. The name 
+/// of the directory is "raw" + the event number. Each file contains
+/// the raw data (with data header) of one DDL. The convention for the
+/// file names is "DET_#DDL.ddl". "DET" is the name of the detector and
+/// "#DDL" is the unique equipment ID.
+///
+/// The constructor of AliRawReaderFile takes the event number or the
+/// directory name as argument.
+/// 
 ///////////////////////////////////////////////////////////////////////////////
 
+#include <cstdlib>
 #include "AliRawReaderFile.h"
+#include "AliDAQ.h"
 #include <TSystem.h>
+#include <TArrayC.h>
 
 
 ClassImp(AliRawReaderFile)
 
 
 AliRawReaderFile::AliRawReaderFile(Int_t eventNumber) :
-  fDirName("raw"),
+  fEventIndex(eventNumber),
+  fDirName("."),
   fDirectory(NULL),
   fStream(NULL),
   fEquipmentId(-1),
   fBuffer(NULL),
-  fBufferSize(0)
+  fBufferSize(0),
+  fEquipmentSize(0),
+  fDDLIndex(NULL),
+  fDDLCurrent(-1),
+  fType(7),
+  fRunNb(0),
+  fDetectorPattern(0),
+  fTimestamp(0)
 {
 // create an object to read digits from the given event
+// in the current directory
 
-  fDirName += eventNumber;
-  fDirectory = gSystem->OpenDirectory(fDirName);
-  if (!fDirectory) {
-    Error("AliRawReaderFile", "could not open directory %s", fDirName.Data());
-  }
-  OpenNextFile();
+  fDirectory = OpenDirectory();
+  if (!fDirectory) fIsValid = kFALSE;
+  if (!OpenNextFile()) fIsValid = kFALSE;
   fHeader = new AliRawDataHeader;
+
+  fId[0] = fId[1] = 0;
+  fTriggerPattern[0] = fTriggerPattern[1] = 0;
 }
 
-AliRawReaderFile::AliRawReaderFile(const char* dirName) :
+AliRawReaderFile::AliRawReaderFile(const char* dirName, Int_t eventNumber) :
+  fEventIndex(eventNumber),
   fDirName(dirName),
   fDirectory(NULL),
   fStream(NULL),
   fEquipmentId(-1),
   fBuffer(NULL),
-  fBufferSize(0)
+  fBufferSize(0),
+  fEquipmentSize(0),
+  fDDLIndex(NULL),
+  fDDLCurrent(-1),
+  fType(7),
+  fRunNb(0),
+  fDetectorPattern(0),
+  fTimestamp(0)
 {
 // create an object to read digits from the given directory
 
-  fDirectory = gSystem->OpenDirectory(fDirName);
-  if (!fDirectory) {
-    Error("AliRawReaderFile", "could not open directory %s", fDirName.Data());
-  }
-  OpenNextFile();
+  fDirectory = OpenDirectory();
+  if (!fDirectory) fIsValid = kFALSE;
+  if (fEventIndex >= 0 && (!OpenNextFile())) fIsValid = kFALSE;
   fHeader = new AliRawDataHeader;
-}
 
-AliRawReaderFile::AliRawReaderFile(const AliRawReaderFile& rawReader) :
-  AliRawReader(rawReader)
-{
-  Fatal("AliRawReaderFile", "copy constructor not implemented");
-}
-
-AliRawReaderFile& AliRawReaderFile::operator = (const AliRawReaderFile& 
-                                             /* rawReader */)
-{
-  Fatal("operator =", "assignment operator not implemented");
-  return *this;
+  fId[0] = fId[1] = 0;
+  fTriggerPattern[0] = fTriggerPattern[1] = 0;
 }
 
 AliRawReaderFile::~AliRawReaderFile()
@@ -90,16 +108,97 @@ AliRawReaderFile::~AliRawReaderFile()
 #endif
     delete fStream;
   }
-  delete fHeader;
+  if (fHeader) delete fHeader;
   if (fBuffer) delete[] fBuffer;
+  if (fDDLIndex) delete fDDLIndex; fDDLIndex=NULL;
+}
+
+void AliRawReaderFile::RequireHeader(Bool_t required)
+{
+  // Reading of raw data in case of missing
+  // raw data header is not implemented for
+  // this class
+  if (!required) {
+    Warning("AliRawReaderFile","Reading of raw data without raw data header!");
+    if (fHeader) delete fHeader;
+    fHeader = NULL;
+  }
+  else {
+    if (!fHeader) fHeader = new AliRawDataHeader;
+  }
+
+  AliRawReader::RequireHeader(required);
+}
+
+TString AliRawReaderFile::GetDirName() const
+{
+// return the current directory name
+
+  TString dirName(fDirName);
+  if (fEventIndex >= 0) {
+    dirName += "/raw";
+    dirName += fEventIndex;
+  }
+  return dirName;
 }
 
+void* AliRawReaderFile::OpenDirectory()
+{
+// open and return the directory
+
+  TString dirName = GetDirName();
+  void* directory = gSystem->OpenDirectory(dirName);
+  if (!directory) {
+    Error("OpenDirectory", "could not open directory %s", dirName.Data());
+  }
+  return directory;
+}
+
+Bool_t AliRawReaderFile::CreateFileIndex()
+{
+// scan the files of the directory and create index of all DDL files
+// returns kFALSE if no DDL files available
+  Bool_t result=kFALSE;
+  fDDLCurrent=-1;
+  if (fDDLIndex) return fDDLIndex->GetSize()>0;
+  if (!fDirectory) return kFALSE;
+  fDDLIndex=new TArrayC(0);
+  if (!fDDLIndex) return kFALSE;
+  TString entry;
+  while ((entry = gSystem->GetDirEntry(fDirectory))) {
+    const char* filename=entry.Data();
+    if (!filename || entry.IsNull()) break;
+    if (entry.BeginsWith("run")) {
+      entry.ReplaceAll("run","");
+      fRunNb = entry.Atoi();
+      continue;
+    }
+    if (!entry.EndsWith(".ddl")) continue;
+    result=kTRUE;
+    entry.Remove(0, entry.Last('_')+1);
+    entry.Remove(entry.Length()-4);
+    Int_t equipmentId = atoi(entry.Data());
+    Int_t ddlIndex = -1;
+    fDetectorPattern |= (1 << AliDAQ::DetectorIDFromDdlID(equipmentId,ddlIndex));
+    if (fDDLIndex->GetSize()<=equipmentId) {
+      fDDLIndex->Set(equipmentId+1);
+    }
+    char* array=(char*)fDDLIndex->GetArray();
+    array[equipmentId]=1;
+  }
+
+  return result;
+}
 
 Bool_t AliRawReaderFile::OpenNextFile()
 {
 // open the next file
 // returns kFALSE if the current file is the last one
 
+  if (!fDDLIndex && !CreateFileIndex()) return kFALSE;
+  if (fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>fEquipmentId)
+    fDDLCurrent=fSelectMinEquipmentId-1;
+
   if (fStream) {
 #if defined(__HP_aCC) || defined(__DECCXX)
     if (fStream->rdbuf()->is_open()) fStream->close();
@@ -109,26 +208,34 @@ Bool_t AliRawReaderFile::OpenNextFile()
     delete fStream;
     fStream = NULL;
     fEquipmentId = -1;
+    fEquipmentSize = 0;
   }
 
   if (!fDirectory) return kFALSE;
-  TString entry;
-  while (entry = gSystem->GetDirEntry(fDirectory)) {
-    if (entry.IsNull()) return kFALSE;
-    if (!entry.EndsWith(".ddl")) continue;
-    char* fileName = gSystem->ConcatFileName(fDirName, entry);
+  while (++fDDLCurrent<(fDDLIndex->GetSize()) && 
+        (fDDLCurrent<=fSelectMaxEquipmentId || fSelectMaxEquipmentId<0)) {
+    if (fDDLIndex->At(fDDLCurrent)==0) continue;
+    Int_t dummy=0;
+    TString entry;
+    entry.Form("%s_%d.ddl", AliDAQ::DetectorNameFromDdlID(fDDLCurrent, dummy), fDDLCurrent);
+    char* fileName = gSystem->ConcatFileName(GetDirName(), entry);
+    if (!fileName) continue;
+    // read the timestamp
+    FileStat_t buf;
+    if (gSystem->GetPathInfo(fileName,buf) == 0) {
+      fTimestamp = buf.fMtime;
+    }
 #ifndef __DECCXX 
     fStream = new fstream(fileName, ios::binary|ios::in);
 #else
     fStream = new fstream(fileName, ios::in);
 #endif
+    delete [] fileName;
     break;
   }
 
   if (!fStream) return kFALSE;
-  entry.Remove(0, entry.Last('_')+1);
-  entry.Remove(entry.Length()-4);
-  fEquipmentId = atoi(entry.Data());
+  fEquipmentId = fDDLCurrent;
 #if defined(__HP_aCC) || defined(__DECCXX)
   return (fStream->rdbuf()->is_open());
 #else
@@ -142,13 +249,19 @@ Bool_t AliRawReaderFile::ReadHeader()
 // read a data header at the current stream position
 // returns kFALSE if the mini header could not be read
 
-  if (!fStream) return kFALSE;
+  if (!fStream && !OpenNextFile()) return kFALSE;
   do {
     if (fCount > 0) fStream->seekg(Int_t(fStream->tellg()) + fCount);
-    while (!fStream->read((char*) fHeader, sizeof(AliRawDataHeader))) {
-      if (!OpenNextFile()) return kFALSE;
+    if (fHeader) {
+      while (!fStream->read((char*) fHeader, sizeof(AliRawDataHeader))) {
+       if (!OpenNextFile()) return kFALSE;
+      }
     }
-    if (fHeader->fSize != 0xFFFFFFFF) {
+    else {
+      if (fStream->eof())
+       if (!OpenNextFile()) return kFALSE;
+    }
+    if (fHeader && fHeader->fSize != 0xFFFFFFFF) {
       fCount = fHeader->fSize - sizeof(AliRawDataHeader);
     } else {
       UInt_t currentPos = fStream->tellg();
@@ -156,6 +269,8 @@ Bool_t AliRawReaderFile::ReadHeader()
       fCount = UInt_t(fStream->tellg()) - currentPos;
       fStream->seekg(currentPos);
     }
+    fEquipmentSize = fCount;
+    if (fHeader) fEquipmentSize += sizeof(AliRawDataHeader);
   } while (!IsSelected());
   return kTRUE;
 }
@@ -199,13 +314,10 @@ Bool_t AliRawReaderFile::ReadNext(UChar_t* data, Int_t size)
 
 Bool_t AliRawReaderFile::Reset()
 {
-// reset the current stream position to the beginning of the file
+// reset the current stream position to the first DDL file of the curevent
 
-  void* directory = gSystem->OpenDirectory(fDirName);
-  if (!directory) {
-    Error("Reset", "could not open directory %s", fDirName.Data());
-    return kFALSE;
-  }
+  void* directory = OpenDirectory();
+  if (!directory) return kFALSE;
 
   if (fStream) {
 #if defined(__HP_aCC) || defined(__DECCXX)
@@ -220,8 +332,67 @@ Bool_t AliRawReaderFile::Reset()
   if (fDirectory) gSystem->FreeDirectory(fDirectory);
   fDirectory = directory;
 
+  // Matthias 05.06.2008
+  // do not open the next file. That might collide with a subsequent
+  // SelectEquipment call as the 'file pointer' is already set.
+  // This is important for the indexing of the DDL files.
+  // ---------------------------------------------------------
+  // All ReadNext functions first require the fCount member to be
+  // non zero or call ReadHeader. That allows to postpone the call
+  // to OpenNextFile to the next invocation of ReadHeader.
+  // ReadHeader has been mofified according to that.
+  /*
   OpenNextFile();
+  */
+  fEquipmentId=-1;
+  fDDLCurrent=-1;
   fCount = 0;
   return kTRUE;
 }
 
+Bool_t AliRawReaderFile::NextEvent()
+{
+// go to the next event directory
+
+  if (fDDLIndex) delete fDDLIndex;
+  fDDLIndex=NULL;
+  fDetectorPattern = 0;
+  if (fEventIndex < -1) return kFALSE;
+
+  do {
+    TString dirName = fDirName + "/raw";
+    dirName += (fEventIndex + 1);
+    void* directory = gSystem->OpenDirectory(dirName);
+    if (!directory) return kFALSE;
+    gSystem->FreeDirectory(directory);
+
+    fEventIndex++;
+    Reset();
+  } while (!IsEventSelected());
+
+  // Read the header of the first payload
+  // in order to fill the 'fake' event header
+  if (ReadHeader() && fHeader) {
+    fId[0] = ((fHeader->GetEventID2() >> 20) & 0xf);
+    fId[1] = (fHeader->GetEventID1() & 0xfff) | ((fHeader->GetEventID2() & 0xfffff) << 12);
+    fTriggerPattern[0] = (fHeader->GetTriggerClasses() & 0xffffffff);
+    fTriggerPattern[1] = ((fHeader->GetTriggerClasses() >> 32) & 0x3ffff);
+  }
+  else {
+    Warning("AliRawReaderFile","Can not read CDH header! The event header fields will be empty!");
+  }
+  Reset();
+
+  fEventNumber++;
+
+  return kTRUE;
+}
+
+Bool_t AliRawReaderFile::RewindEvents()
+{
+// reset the event counter
+
+  if (fEventIndex >= 0)  fEventIndex = -1;
+  fEventNumber = -1;
+  return Reset();
+}