#include "AliRawReaderHLT.h"
#include "AliHLTOUTRawReader.h"
#include "AliHLTModuleAgent.h"
+#include "AliHLTOUTHandler.h"
+#include "AliHLTOUTHandlerEquId.h"
+#include "AliHLTSystem.h"
#include "AliLog.h"
#include "AliDAQ.h" // RAW, for detector names and equipment ids
#include "TObjString.h"
AliRawReaderHLT::AliRawReaderHLT(AliRawReader* pRawreader, const char* options)
:
AliRawReader(),
+ AliHLTReconstructorBase(),
fpParentReader(pRawreader),
fOptions(),
+ fSystemOptions(),
fpData(NULL),
fDataSize(0),
fOffset(0),
+ fPosition(0),
fEquipmentId(-1),
fbHaveHLTData(false),
fDetectors(),
- fpHLTOUT(NULL)
+ fpHLTOUT(NULL),
+ fbReadFirst(true),
+ fpDataHandler(NULL)
{
// see header file for class documentation
// or
AliRawReaderHLT::~AliRawReaderHLT()
{
// see header file for class documentation
+ ReleaseHLTData();
}
UInt_t AliRawReaderHLT::GetType() const
Bool_t AliRawReaderHLT::ReadHeader()
{
// see header file for class documentation
- Bool_t result=fpParentReader->ReadHeader();
- fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
+ Bool_t result=kFALSE;
+ Bool_t firstParentCycle=fbHaveHLTData;
+ while (fbHaveHLTData=(fbHaveHLTData && ReadNextHLTData())) {
+ // all internal data variables set
+ assert(fpData!=NULL);
+ fHeader=reinterpret_cast<AliRawDataHeader*>(const_cast<AliHLTUInt8_t*>(fpData));
+ fOffset=sizeof(AliRawDataHeader);
+ fPosition=fOffset;
+ if (result=IsSelected()) break;
+ }
+ firstParentCycle&=!fbHaveHLTData; // true if it just changed from true to false
+ while (!result) {
+ if (firstParentCycle) {
+ firstParentCycle=kFALSE;
+ // reset and set the selection back to the original one
+ fpParentReader->Reset();
+ fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId);
+ }
+
+ if (!(result=fpParentReader->ReadHeader())) {
+ fHeader=NULL;
+ break;
+ }
+ fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
+
+ // filter out all equipment ids which should be taken from the HLT stream
+ int id=fpParentReader->GetEquipmentId();
+ if (result=!IsHLTInput(id)) break;
+ }
return result;
}
// this function is the backbone of the ReadNext functions, it gets the
// whole data block either from the HLT stream or the parent raw reader.
// Each call of ReadNextData directly jumps to the next data set.
- Bool_t result=kFALSE;
- if (fbHaveHLTData&=ReadNextHLTData()) {
- // all internal data variables set
- assert(fpData!=NULL);
- data=const_cast<AliHLTUInt8_t*>(fpData);
- result=kTRUE;
- }
- if (!result) {
- // no data in the HLT stream, read real data
- //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId));
-
- // first set the selection back to the original one
- fpParentReader->SelectEquipment(fSelectEquipmentType, fSelectMinEquipmentId, fSelectMaxEquipmentId);
-
- // read data
- while (result=fpParentReader->ReadNextData(data)) {
- // continue if the Equipment Id is supposed to be replaced by the HLT stream
- // in that case we do not want to read it from the parent raw reader
- if (!IsHLTInput(fpParentReader->GetEquipmentId())) break;
- }
-
- // set the header of this reader from the parent reader.
- // This is necessary because of a few base class methods working directly
- // on the header
- fHeader=const_cast<AliRawDataHeader*>(fpParentReader->GetDataHeader());
- if (result) {
- fpData=data;
- fDataSize=fpParentReader->GetDataSize();
+ Bool_t result=kTRUE;
+
+ // read new header if data already read
+ if (fPosition<fDataSize || (result=ReadHeader())) {
+ if (fbHaveHLTData && fpHLTOUT!=NULL) {
+ // all internal data variables set
+ result=kTRUE;
+ data=const_cast<AliHLTUInt8_t*>(fpData+sizeof(AliRawDataHeader));
} else {
- fpData=NULL;
- fDataSize=0;
+ // no data in the HLT stream, read real data
+ //AliInfo(Form("read from parent reader: min=%d max=%d", fSelectMinEquipmentId, fSelectMaxEquipmentId));
+
+ // read data
+ result=fpParentReader->ReadNextData(data);
+ if (result) {
+ fpData=data;
+ fDataSize=fpParentReader->GetDataSize();
+ } else {
+ fpData=NULL;
+ fDataSize=0;
+ }
+
+ fEquipmentId=-1;
}
- fOffset=0;
- fEquipmentId=-1;
+ fOffset=sizeof(AliRawDataHeader);
+ fPosition=fDataSize;
}
return result;
}
Bool_t AliRawReaderHLT::Reset()
{
// see header file for class documentation
+ ReleaseHLTData(false/* keep HLTOUT instance */);
Bool_t result=fpParentReader->Reset();
- fpData=NULL;
- fDataSize=0;
- fOffset=0;
fEquipmentId=-1;
- if (fbHaveHLTData=(fDetectors.size()>0)) {
- vector<int>::iterator detector=fDetectors.begin();
- for (; detector!=fDetectors.end(); detector++) {
- int ddlOffset=AliDAQ::DdlIDOffset(*detector);
- int nofDDLs=AliDAQ::NumberOfDdls(*detector);
- if ((fSelectMinEquipmentId>=0 && fSelectMinEquipmentId>ddlOffset+nofDDLs) ||
- (fSelectMinEquipmentId>=0 && fSelectMaxEquipmentId<ddlOffset))
- continue;
- break;
- }
- fbHaveHLTData=detector!=fDetectors.end();
- }
+
+ // check if redirection is enabled for at least one detector in the selected range
+ fbHaveHLTData=EvaluateSelection();
+
+ // start reading HLTOUT data blocks from the beginning
+ fbReadFirst=true;
+
return result;
}
Bool_t AliRawReaderHLT::NextEvent()
{
// see header file for class documentation
+
+ ReleaseHLTData();
+
Bool_t result=fpParentReader->NextEvent();
if (result) {
fEventNumber++;
// see header file for class documentation
AliRawReader::Select(detectorID, minDDLID, maxDDLID);
fpParentReader->Select(detectorID, minDDLID, maxDDLID);
+ fbHaveHLTData=EvaluateSelection();
}
// most likely we do not need this method since the base class directly forwards
// see header file for class documentation
//AliInfo(Form("equipmentType=%d, minEquipmentId=%d, maxEquipmentId=%d", equipmentType, minEquipmentId, maxEquipmentId));
- AliRawReader::Select(equipmentType, minEquipmentId, maxEquipmentId);
- fpParentReader->Select(equipmentType, minEquipmentId, maxEquipmentId);
+ AliRawReader::SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
+ fpParentReader->SelectEquipment(equipmentType, minEquipmentId, maxEquipmentId);
+ fbHaveHLTData=EvaluateSelection();
}
void AliRawReaderHLT::SkipInvalid(Bool_t skip)
int detId=AliDAQ::DetectorID(argument.Data());
if (detId>=0) {
fDetectors.push_back(detId);
+ } else {
+ if (!fSystemOptions.IsNull()) fSystemOptions+=" ";
+ fSystemOptions+=argument;
}
}
delete pTokens;
{
// see header file for class documentation
bool result=kTRUE;
- if (!fpHLTOUT) {
+ if (fbReadFirst || !fpHLTOUT) {
+ if (!fpHLTOUT) {
fpHLTOUT=new AliHLTOUTRawReader(fpParentReader);
if (result=(fpHLTOUT!=NULL)) {
+ AliHLTSystem* pSystem=GetInstance();
+ if (pSystem) {
+ pSystem->ScanOptions(fSystemOptions.Data());
+ }
if (result=(fpHLTOUT->Init()>=0)) {
- result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
- AliHLTModuleAgent::kRawReader)>=0;
}
}
- } else {
- fpHLTOUT->ReleaseDataBuffer(fpData);
- if (!(result=fpHLTOUT->SelectNextDataBlock()>=0)) {
- delete fpHLTOUT;
- fpHLTOUT=NULL;
}
+ if (result) {
+ result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
+ AliHLTModuleAgent::kRawReader)>=0;
+ }
+ fbReadFirst=false;
+ } else {
+ // first release the data buffer
+ ReleaseHLTData(false /* keep HLTOUT instance */);
+ result=fpHLTOUT->SelectNextDataBlock()>=0;
}
if (result) {
+ AliHLTComponentDataType dt=kAliHLTVoidDataType;
+ AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
+ fpHLTOUT->GetDataBlockDescription(dt, spec);
AliHLTUInt32_t size=0;
- result=fpHLTOUT->GetDataBuffer(fpData, size)>=0;
- fDataSize=(int)size;
- fEquipmentId=-1;
+ AliHLTOUTHandler* pHandler=fpHLTOUT->GetHandler();
+ if (pHandler) {
+ if (dynamic_cast<AliHLTOUTHandlerEquId*>(pHandler)!=NULL) {
+ AliHLTOUT::AliHLTOUTLockGuard g(fpHLTOUT);
+ fEquipmentId=pHandler->ProcessData(fpHLTOUT);
+ fpData=NULL;
+ fDataSize=pHandler->GetProcessedData(fpData);
+ if (!fpData) {
+ result=fpHLTOUT->GetDataBuffer(fpData, size)>=0;
+ fpDataHandler=NULL;
+ AliDebug(AliLog::kDebug, Form("forward data block from HLTOUT stream to equipment %d", fEquipmentId));
+ fDataSize=(int)size;
+ } else {
+ // remember the current handler in order to properly release the data buffer
+ fpDataHandler=pHandler;
+ AliDebug(AliLog::kDebug, Form("forward decoded data block provided by handler to equipment %d", fEquipmentId));
+ }
+ return kTRUE;
+ } else {
+ AliError(Form("handler is not of type AliHLTOUTHandlerEquId for block %x data type %s spec %#x; data block skipped",
+ fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
+ }
+ } else {
+ AliWarning(Form("no data handler found for block %x data type %s spec %#x; data block skipped",
+ fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
+ }
} else {
- fpData=NULL;
- fDataSize=0;
- fOffset=0;
- fEquipmentId=-1;
+ ReleaseHLTData(false /* keep HLTOUT instance */);
}
- return false;
+ return kFALSE;
}
Bool_t AliRawReaderHLT::IsHLTInput(int ddlid)
return kFALSE;
}
+int AliRawReaderHLT::ReleaseHLTData(bool bReleaseHLTOUT)
+{
+ // see header file for class documentation
+ if (fpHLTOUT) {
+ if (fpDataHandler) fpDataHandler->ReleaseProcessedData(fpData, fDataSize);
+ else fpHLTOUT->ReleaseDataBuffer(fpData);
+ fpDataHandler=NULL;
+ if (bReleaseHLTOUT) {
+ delete fpHLTOUT;
+ fpHLTOUT=NULL;
+ }
+ }
+
+ fpData=NULL;
+ fDataSize=0;
+ fOffset=0;
+ fPosition=0;
+ fEquipmentId=-1;
+
+ return 0;
+}
+
+Bool_t AliRawReaderHLT::EvaluateSelection()
+{
+ // see header file for class documentation
+ Bool_t bHaveHLTData=kFALSE;
+ if (bHaveHLTData=(fDetectors.size()>0)) {
+ vector<int>::iterator detector=fDetectors.begin();
+ for (; detector!=fDetectors.end(); detector++) {
+ int ddlOffset=AliDAQ::DdlIDOffset(*detector);
+ int nofDDLs=AliDAQ::NumberOfDdls(*detector);
+ if ((fSelectMinEquipmentId<0 || fSelectMinEquipmentId<ddlOffset+nofDDLs) &&
+ (fSelectMaxEquipmentId<0 || fSelectMaxEquipmentId>=ddlOffset))
+ break;
+ }
+ bHaveHLTData=detector!=fDetectors.end();
+ }
+ return bHaveHLTData;
+}
+
AliRawReader* AliRawReaderHLTCreateInstance(AliRawReader* pParentReader, const char* options)
{
// see header file for class documentation