#include <cstdlib>
#include "AliRawReaderFile.h"
#include "AliDAQ.h"
#include <TSystem.h>
#include <TArrayC.h>
using std::ios;
ClassImp(AliRawReaderFile)
AliRawReaderFile::AliRawReaderFile(Int_t eventNumber) :
fEventIndex(eventNumber),
fDirName("."),
fDirectory(NULL),
fStream(NULL),
fEquipmentId(-1),
fBuffer(NULL),
fBufferSize(0),
fEquipmentSize(0),
fDDLIndex(NULL),
fDDLCurrent(-1),
fType(7),
fRunNb(0),
fDetectorPattern(0),
fTimestamp(0)
{
fDirectory = OpenDirectory();
if (!fDirectory) fIsValid = kFALSE;
if (!OpenNextFile()) fIsValid = kFALSE;
fId[0] = fId[1] = 0;
fTriggerPattern[0] = fTriggerPattern[1] = fTriggerPattern[3] = fTriggerPattern[3] = 0;
}
AliRawReaderFile::AliRawReaderFile(const char* dirName, Int_t eventNumber) :
fEventIndex(eventNumber),
fDirName(dirName),
fDirectory(NULL),
fStream(NULL),
fEquipmentId(-1),
fBuffer(NULL),
fBufferSize(0),
fEquipmentSize(0),
fDDLIndex(NULL),
fDDLCurrent(-1),
fType(7),
fRunNb(0),
fDetectorPattern(0),
fTimestamp(0)
{
fDirectory = OpenDirectory();
if (!fDirectory) fIsValid = kFALSE;
if (fEventIndex >= 0 && (!OpenNextFile())) fIsValid = kFALSE;
fId[0] = fId[1] = 0;
fTriggerPattern[0] = fTriggerPattern[1] = fTriggerPattern[3] = fTriggerPattern[3] = 0;
}
AliRawReaderFile::~AliRawReaderFile()
{
if (fDirectory) gSystem->FreeDirectory(fDirectory);
if (fStream) {
#if defined(__HP_aCC) || defined(__DECCXX)
if (fStream->rdbuf()->is_open()) fStream->close();
#else
if (fStream->is_open()) fStream->close();
#endif
delete fStream;
}
if (fHeader) delete fHeader;
if (fHeaderV3) delete fHeaderV3;
if (fBuffer) delete[] fBuffer;
if (fDDLIndex) delete fDDLIndex; fDDLIndex=NULL;
}
void AliRawReaderFile::RequireHeader(Bool_t required)
{
if (!required) {
Warning("AliRawReaderFile","Reading of raw data without raw data header!");
if (fHeader) delete fHeader;
if (fHeaderV3) delete fHeaderV3;
fHeader = NULL;
fHeaderV3 = NULL;
}
AliRawReader::RequireHeader(required);
}
TString AliRawReaderFile::GetDirName() const
{
TString dirName(fDirName);
if (fEventIndex >= 0) {
dirName += "/raw";
dirName += fEventIndex;
}
return dirName;
}
void* AliRawReaderFile::OpenDirectory()
{
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()
{
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()
{
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();
#else
if (fStream->is_open()) fStream->close();
#endif
delete fStream;
fStream = NULL;
fEquipmentId = -1;
fEquipmentSize = 0;
}
if (!fDirectory) return kFALSE;
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;
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;
fEquipmentId = fDDLCurrent;
#if defined(__HP_aCC) || defined(__DECCXX)
return (fStream->rdbuf()->is_open());
#else
return (fStream->is_open());
#endif
}
Bool_t AliRawReaderFile::ReadHeader()
{
if (!fStream && !OpenNextFile()) return kFALSE;
do {
UInt_t dataSize=0;
UInt_t headerSize=0;
if (fCount > 0) fStream->seekg(Int_t(fStream->tellg()) + fCount);
UInt_t currentPos = fStream->tellg();
if (fRequireHeader) {
if(! fHeader) fHeader = new AliRawDataHeader;
while (!fStream->read((char*) fHeader, sizeof(AliRawDataHeader))) {
if (!OpenNextFile()) return kFALSE;
currentPos = fStream->tellg();
}
dataSize=fHeader->fSize;
headerSize=sizeof(AliRawDataHeader);
if(fHeader->GetVersion() == 3){
delete fHeader;
fHeader = NULL;
if(! fHeaderV3) fHeaderV3 = new AliRawDataHeaderV3;
fStream->seekg(currentPos);
if (!fStream->read((char*) fHeaderV3, sizeof(AliRawDataHeaderV3)))
return kFALSE;
headerSize=sizeof(AliRawDataHeaderV3);
} else if (fHeaderV3) {
delete fHeaderV3;
fHeaderV3 = NULL;
}
}
else {
if (fStream->eof())
if (!OpenNextFile()) return kFALSE;
}
if ( headerSize && dataSize != 0xFFFFFFFF) {
fCount = dataSize - headerSize;
} else {
currentPos = fStream->tellg();
fStream->seekg(0, ios::end);
fCount = UInt_t(fStream->tellg()) - currentPos;
fStream->seekg(currentPos);
}
fEquipmentSize = fCount + headerSize;
} while (!IsSelected());
return kTRUE;
}
Bool_t AliRawReaderFile::ReadNextData(UChar_t*& data)
{
while (fCount == 0) {
if (!ReadHeader()) return kFALSE;
}
if (fBufferSize < fCount) {
if (fBuffer) delete[] fBuffer;
fBufferSize = Int_t(fCount*1.2);
fBuffer = new UChar_t[fBufferSize];
}
if (!fStream->read((char*) fBuffer, fCount)) {
Error("ReadNext", "could not read data!");
return kFALSE;
}
fCount = 0;
data = fBuffer;
return kTRUE;
}
Bool_t AliRawReaderFile::ReadNext(UChar_t* data, Int_t size)
{
if (!fStream->read((char*) data, size)) {
Error("ReadNext", "could not read data!");
return kFALSE;
}
fCount -= size;
return kTRUE;
}
Bool_t AliRawReaderFile::Reset()
{
void* directory = OpenDirectory();
if (!directory) return kFALSE;
if (fStream) {
#if defined(__HP_aCC) || defined(__DECCXX)
if (fStream->rdbuf()->is_open()) fStream->close();
#else
if (fStream->is_open()) fStream->close();
#endif
delete fStream;
fStream = NULL;
}
if (fDirectory) gSystem->FreeDirectory(fDirectory);
fDirectory = directory;
fEquipmentId=-1;
fDDLCurrent=-1;
fCount = 0;
return kTRUE;
}
Bool_t AliRawReaderFile::NextEvent()
{
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());
if (ReadHeader() && ( fHeader || fHeaderV3) ) {
UInt_t eid1=0, eid2=0;
ULong64_t trg1=0, trg2=0;
if(fHeader){
eid1=fHeader->GetEventID1();
eid2=fHeader->GetEventID2();
trg1=fHeader->GetTriggerClasses();
} else {
eid1=fHeaderV3->GetEventID1();
eid2=fHeaderV3->GetEventID2();
trg1=fHeaderV3->GetTriggerClasses();
trg2=fHeaderV3->GetTriggerClassesNext50();
}
fId[0] = ((eid2 >> 20) & 0xf);
fId[1] = (eid1 & 0xfff) | ((eid2 & 0xfffff) << 12);
fTriggerPattern[0] = (trg1 & 0xffffffff);
fTriggerPattern[1] = ((trg1 >> 32) & 0x3ffff) | ((trg2 & 0x3fff) << 18);
fTriggerPattern[2] = ((trg2 >> 14) & 0xffffffff);
fTriggerPattern[3] = ((trg2 >> 46) & 0xf);
}
else {
Warning("AliRawReaderFile","Can not read CDH header! The event header fields will be empty!");
}
Reset();
fEventNumber++;
return kTRUE;
}
Bool_t AliRawReaderFile::RewindEvents()
{
if (fEventIndex >= 0) fEventIndex = -1;
fEventNumber = -1;
return Reset();
}