~AliHLTOUTHandlerDesc() {}
+ bool operator==(const AliHLTOUTHandlerType handlerType) const {
+ return fHType==handlerType;
+ }
+
private:
/** type of the handler */
AliHLTOUTHandlerType fHType; //!transient
:
fSearchDataType(kAliHLTVoidDataType),
fSearchSpecification(kAliHLTVoidDataSpec),
+ fSearchHandlerType(AliHLTModuleAgent::kUnknownOutput),
fFlags(0),
fBlockDescList(),
fCurrent(fBlockDescList.begin()),
fpBuffer(NULL),
- fDataHandlers()
+ fDataHandlers(),
+ fbVerbose(true)
{
// see header file for class documentation
// or
}
int AliHLTOUT::SelectFirstDataBlock(AliHLTComponentDataType dt, AliHLTUInt32_t spec,
- AliHLTModuleAgent::AliHLTOUTHandlerType /*handlerType*/)
+ AliHLTModuleAgent::AliHLTOUTHandlerType handlerType)
{
// see header file for class documentation
if (CheckStatusFlag(kLocked)) return -EPERM;
fCurrent=fBlockDescList.begin();
fSearchDataType=dt;
fSearchSpecification=spec;
- //fSearchHandlerType=handlerType;
+ fSearchHandlerType=handlerType;
return FindAndSelectDataBlock();
}
int iResult=-ENOENT;
while (fCurrent!=fBlockDescList.end() && iResult==-ENOENT) {
if ((*fCurrent)==fSearchDataType &&
- fSearchSpecification==kAliHLTVoidDataSpec || (*fCurrent)==fSearchSpecification &&
- 1/*fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput*/) {
+ (fSearchSpecification==kAliHLTVoidDataSpec || (*fCurrent)==fSearchSpecification) &&
+ (fSearchHandlerType==AliHLTModuleAgent::kUnknownOutput || FindHandlerDesc(fCurrent->GetIndex())==fSearchHandlerType)) {
iResult=fCurrent->GetIndex();
// TODO: check the byte order on the current system and the byte order of the
// data block, print warning when missmatch and user did not check
// see header file for class documentation
int iResult=0;
AliHLTOUTIndexList remnants;
+ int iCount=0;
for (int havedata=SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec); havedata>=0; havedata=SelectNextDataBlock()) {
+ iCount++;
remnants.push_back(GetDataBlockIndex());
AliHLTComponentDataType dt=kAliHLTVoidDataType;
AliHLTUInt32_t spec=kAliHLTVoidDataSpec;
}
}
}
+
+ // warning if some of the data blocks are not selected by the kAliHLTAnyDataType
+ // criterion
+ if (GetNofDataBlocks()>iCount) {
+ HLTWarning("incomplete data type in %d out of %d data block(s)", GetNofDataBlocks()-iCount, iCount);
+ }
+
+ // warning if handler not found
if (remnants.size()>0) {
- HLTWarning("no handlers found for %d data blocks out of %d", remnants.size(), GetNofDataBlocks());
+ HLTWarning("no handlers found for %d data blocks out of %d", remnants.size(), iCount);
AliHLTOUTBlockDescriptorVector::iterator block=fBlockDescList.begin();
for (AliHLTOUTIndexList::iterator element=remnants.begin(); element!=remnants.end(); element++) {
for (int trials=0; trials<2; trials++) {
return iResult;
}
-AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
+const AliHLTOUT::AliHLTOUTHandlerListEntry& AliHLTOUT::FindHandlerDesc(AliHLTUInt32_t blockIndex)
{
// see header file for class documentation
AliHLTOUTHandlerListEntryVector::iterator element=fDataHandlers.begin();
}
element++;
}
- return AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
+ return const_cast<AliHLTOUT::AliHLTOUTHandlerListEntry&>(AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry);
}
AliHLTOUT::AliHLTOUTHandlerListEntry::AliHLTOUTHandlerListEntry()
{
// see header file for class documentation
fpHandler=src.fpHandler;
- *fpHandlerDesc=*src.fpHandlerDesc;
+ if (src.fpHandlerDesc)
+ *fpHandlerDesc=*src.fpHandlerDesc;
fpAgent=src.fpAgent;
fBlocks.assign(src.fBlocks.begin(), src.fBlocks.end());
return *this;
return true;
}
+bool AliHLTOUT::AliHLTOUTHandlerListEntry::operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const
+{
+ // see header file for class documentation
+ if (!fpHandlerDesc) return false;
+ return *fpHandlerDesc==handlerType;
+}
+
void AliHLTOUT::AliHLTOUTHandlerListEntry::AddIndex(AliHLTOUT::AliHLTOUTHandlerListEntry &desc)
{
// see header file for class documentation
}
const AliHLTOUT::AliHLTOUTHandlerListEntry AliHLTOUT::AliHLTOUTHandlerListEntry::fgkVoidHandlerListEntry;
+
+AliHLTUInt64_t AliHLTOUT::Swap(AliHLTUInt64_t src)
+{
+ // see header file for class documentation
+ return ((src & 0xFFULL) << 56) |
+ ((src & 0xFF00ULL) << 40) |
+ ((src & 0xFF0000ULL) << 24) |
+ ((src & 0xFF000000ULL) << 8) |
+ ((src & 0xFF00000000ULL) >> 8) |
+ ((src & 0xFF0000000000ULL) >> 24) |
+ ((src & 0xFF000000000000ULL) >> 40) |
+ ((src & 0xFF00000000000000ULL) >> 56);
+}
+
+AliHLTUInt32_t AliHLTOUT::Swap(AliHLTUInt32_t src)
+{
+ // see header file for class documentation
+ return ((src & 0xFFULL) << 24) |
+ ((src & 0xFF00ULL) << 8) |
+ ((src & 0xFF0000ULL) >> 8) |
+ ((src & 0xFF000000ULL) >> 24);
+}
AliHLTUInt64_t fEventID; //! see above
};
+ enum {
+ /// versions 1 of the HLT header
+ kVersion1 = 1,
+ /// versions 2 of the HLT header
+ kVersion2 = 2
+ };
+
+ enum {
+ /// size of HLT decision in data format version 1: 29x4
+ kSizeDecisionVersion1 = 116,
+ /// size of HLT decision in data format version 2: 30x4
+ kSizeDecisionVersion2 = 120
+ };
+
// definitions from ALICE internal notes ALICE-INT-2002-010 and
// ALICE-INT-2006-XXX
enum {
*/
int CheckAlignment(AliHLTOUT::AliHLTOUTDataType type);
+ /**
+ * Helper function to byte swap a 64 bit value.
+ */
+ static AliHLTUInt64_t Swap(AliHLTUInt64_t src);
+
+ /**
+ * Helper function to byte swap a 32 bit value.
+ */
+ static AliHLTUInt32_t Swap(AliHLTUInt32_t src);
+
protected:
/**
* Add a block descriptor.
*/
int AddBlockDescriptor(const AliHLTOUTBlockDescriptor desc);
+ /**
+ * Print output or suppress.
+ */
+ bool BeVerbose() {return fbVerbose;}
+
+ /**
+ * Switch output.
+ */
+ void SwitchVerbosity(bool verbose) {fbVerbose=verbose;}
+
private:
/** copy constructor prohibited */
AliHLTOUT(const AliHLTOUT&);
static const AliHLTOUTHandlerListEntry fgkVoidHandlerListEntry; //! initializer
operator AliHLTOUTHandler*() const {return fpHandler;}
+
+ // please note that fpHandlerDesc is really a pointer and is created
+ // in the constructor. Thats why it is dereferenced here. The pointer
+ // type is on purpose, even though it is a bit confusing with the
+ // argument by reference in the AliHLTOUTHandlerListEntry constructor.
operator AliHLTModuleAgent::AliHLTOUTHandlerDesc&() const {return *fpHandlerDesc;}
operator AliHLTModuleAgent*() const {return fpAgent;}
*/
bool operator==(const AliHLTOUTHandlerListEntry& entry) const;
+ bool operator==(const AliHLTModuleAgent::AliHLTOUTHandlerType handlerType) const;
+
AliHLTUInt32_t operator[](int i) const;
/**
/**
* Find handler description for a certain block index.
*/
- AliHLTOUTHandlerListEntry FindHandlerDesc(AliHLTUInt32_t blockIndex);
+ const AliHLTOUTHandlerListEntry& FindHandlerDesc(AliHLTUInt32_t blockIndex);
/** data type for the current block search, set from @ref SelectFirstDataBlock */
AliHLTComponentDataType fSearchDataType; //!transient
/** data specification for the current block search */
AliHLTUInt32_t fSearchSpecification; //!transient
+ /** handler type for the current block search */
+ AliHLTModuleAgent::AliHLTOUTHandlerType fSearchHandlerType; // !transient
+
/** instance flags: locked, collecting, ... */
unsigned int fFlags; //!transient
/** list of AliHLTOUTHandlers */
AliHLTOUTHandlerListEntryVector fDataHandlers; // !transient
- ClassDef(AliHLTOUT, 1)
+ /** verbose or silent output */
+ bool fbVerbose; //!transient
+
+ ClassDef(AliHLTOUT, 2)
};
#endif
{
// see header file for class documentation
int iResult=0;
- if (pReader && pReader->ReadNextEvent()==0) {
+ if (pReader && (iResult=pReader->ReadNextEvent())==0) {
AliHLTUInt32_t nofBlocks=pReader->GetBlockCnt();
AliHLTUInt32_t tmp1=0x1;
AliHLTUInt32_t tmp2=offset;
homer_uint32 origin=pReader->GetBlockDataOrigin( i );
homer_uint32 spec=pReader->GetBlockDataSpec( i );
AliHLTComponentDataType dt;
- AliHLTComponent::SetDataType(dt, id, origin);
+ AliHLTComponent::SetDataType(dt, Swap(id), Swap(origin));
AliHLTOUTBlockDescriptor desc(dt, spec, offset|i);
HLTDebug("adding block %d: %s %#x", i, AliHLTComponent::DataType2Text(dt).c_str(), spec);
iResult=AddBlockDescriptor(desc);
}
} else {
- iResult=-ENODEV;
+ if (iResult==EBADMSG) {
+ HLTWarning("Format error in data block");
+ iResult*=-1;
+ } else if (iResult==ENOKEY) {
+ HLTWarning("Format error in data block: can not find HOMER block descriptor id");
+ iResult*=-1;
+ } else {
+ iResult=-ENODEV;
+ }
}
return iResult;
}
int AliHLTOUTRawReader::GenerateIndex()
{
// see header file for class documentation
- // step through all HLT ddls, create HOMER reader and
+ // step through all HLT ddls, create HOMER readers and
// scan data block
int iResult=0;
if (fpRawreader && fpManager) {
fpRawreader->Reset();
- fpRawreader->Select("HLT");
+ // there was a bug in AliDAQ returning the wrong equipment id
+ // for the HLT links. It has been fixed in the trunk on Feb 5th 2008
+ // and from v4-10-Release (Rev-02). For the moment we select directly
+ // to support older AliRoot versions
+ //fpRawreader->Select("HLT");
+ fpRawreader->SelectEquipment(0,7680, 7689);
UChar_t* pSrc=NULL;
while (fpRawreader->ReadNextData(pSrc) && pSrc!=NULL && iResult>=0) {
- AliHLTUInt32_t id=(fpRawreader->GetEquipmentId())<<fgkIdShift;
- int size=fpRawreader->GetDataSize();
- int offset=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
- AliHLTHOMERReader* pReader=fpManager->OpenReaderBuffer(pSrc+offset, size-offset);
+ AliHLTUInt32_t id=(fpRawreader->GetEquipmentId());
+ unsigned int size=fpRawreader->GetDataSize();
+
+ AliHLTHOMERReader* pReader=OpenReader(pSrc, size);
+
+ // we use the equipment id to identify the different homer blocks
+ id<<=fgkIdShift;
if (pReader) {
iResult=ScanReader(pReader, id);
fpManager->DeleteReader(pReader);
UChar_t* pSrc=NULL;
if (fpRawreader->ReadNextData(pSrc) && pSrc!=NULL) {
int srcSize=fpRawreader->GetDataSize();
- int offset=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
- fpCurrent=fpManager->OpenReaderBuffer(pSrc+offset, srcSize-offset);
+ fpCurrent=OpenReader(pSrc, srcSize);
if (fpCurrent && fpCurrent->ReadNextEvent()!=0) {
iResult=-ENODATA;
}
}
return iResult;
}
+
+AliHLTHOMERReader* AliHLTOUTRawReader::OpenReader(UChar_t* pSrc, unsigned int size)
+{
+ // see header file for class documentation
+ unsigned int offset=sizeof(AliHLTOUTEventHeader);
+ const AliRawDataHeader* pCDH=fpRawreader->GetDataHeader();
+ AliHLTUInt32_t id=(fpRawreader->GetEquipmentId());
+ AliHLTUInt32_t statusFlags=pCDH->GetStatus();
+ AliHLTOUTEventHeader* pHLTHeader=reinterpret_cast<AliHLTOUTEventHeader*>(pSrc);
+
+ // consistency check for the block size
+ if (pHLTHeader->fLength!=size) {
+ HLTWarning("can not treat HLT data block %d: size missmatch, header %d, but buffer is %d", id, pHLTHeader->fLength, size);
+ return NULL;
+ }
+
+ // determine the offset of the homer block
+ // the HLT header is mandatory, HLT decision and HLT
+ // payload are optional. HLT decision is always before HLT
+ // payload if existent.
+ if (statusFlags&(0x1<<kCDHFlagsHLTDecision)) {
+ // the block contains HLT decision data, this is just
+ // skipped here
+ AliHLTUInt32_t* pDecisionLen=reinterpret_cast<AliHLTUInt32_t*>(pSrc+offset);
+ if ((*pDecisionLen)*sizeof(AliHLTUInt32_t)+offset<size) {
+ // the first 32bit word specifies the number of 32bit words in the
+ // decision block -> +1 for this length word
+ offset+=((*pDecisionLen)+1)*sizeof(AliHLTUInt32_t);
+ } else {
+ HLTWarning("size missmatch: HLT decision block bigger than total block length, skipping ...");
+ return NULL;
+ }
+ }
+
+ // check if there is payload
+ if (!(statusFlags&(0x1<<kCDHFlagsHLTPayload))) return NULL;
+
+ // continue if there is no data left in the buffer
+ if (offset>=size) {
+ HLTWarning("no HLT payload available, but bit is set, skipping ...");
+ return NULL;
+ }
+
+ // check for the HOME descriptor type id
+ AliHLTUInt64_t* pHomerDesc=reinterpret_cast<AliHLTUInt64_t*>(pSrc+offset);
+ if (*(pHomerDesc+kID_64b_Offset) != HOMER_BLOCK_DESCRIPTOR_TYPEID &&
+ Swap(*(pHomerDesc+kID_64b_Offset)) != HOMER_BLOCK_DESCRIPTOR_TYPEID) {
+ HLTWarning("format error: can not find HOMER block descriptor typid, skipping this data block");
+ return NULL;
+ }
+
+ return fpManager->OpenReaderBuffer(pSrc+offset, size-offset);
+}
int GetDataBuffer(AliHLTUInt32_t index, const AliHLTUInt8_t* &pBuffer,
AliHLTUInt32_t& size);
+ /**
+ * Open HOMER reader for the data buffer.
+ * The function expects the data buffer including all headers (CDH
+ * and HLTOUT header). The offset for the HLT payload is determined from
+ * the headers and the optional HLT decision data.
+ * @param pSrc data buffer
+ * @param size size of the buffer in byte
+ * @return instance of HOMER reader
+ */
+ AliHLTHOMERReader* OpenReader(UChar_t* pSrc, unsigned int size);
+
/** the rawreader */
AliRawReader* fpRawreader; //!transient
fbHaveHLTData(false),
fDetectors(),
fpHLTOUT(NULL),
+ fbReadFirst(true),
fpDataHandler(NULL)
{
// see header file for class documentation
// read new header if data already read
if (fPosition<fDataSize || (result=ReadHeader())) {
- if (fpHLTOUT!=NULL) {
+ if (fbHaveHLTData && fpHLTOUT!=NULL) {
// all internal data variables set
result=kTRUE;
data=const_cast<AliHLTUInt8_t*>(fpData+sizeof(AliRawDataHeader));
Bool_t AliRawReaderHLT::Reset()
{
// see header file for class documentation
- ReleaseHLTData();
+ ReleaseHLTData(false/* keep HLTOUT instance */);
Bool_t result=fpParentReader->Reset();
fEquipmentId=-1;
// 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
bool result=kTRUE;
- if (!fpHLTOUT) {
+ if (fbReadFirst || !fpHLTOUT) {
+ if (!fpHLTOUT) {
fpHLTOUT=new AliHLTOUTRawReader(fpParentReader);
if (result=(fpHLTOUT!=NULL)) {
AliHLTSystem* pSystem=GetInstance();
pSystem->ScanOptions(fSystemOptions.Data());
}
if (result=(fpHLTOUT->Init()>=0)) {
- result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
- AliHLTModuleAgent::kRawReader)>=0;
}
}
+ }
+ if (result) {
+ result=fpHLTOUT->SelectFirstDataBlock(kAliHLTAnyDataType, kAliHLTVoidDataSpec,
+ AliHLTModuleAgent::kRawReader)>=0;
+ }
+ fbReadFirst=false;
} else {
// first release the data buffer
ReleaseHLTData(false /* keep HLTOUT instance */);
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 {
fpHLTOUT->GetDataBlockIndex(), AliHLTComponent::DataType2Text(dt).c_str(), spec));
}
} else {
- ReleaseHLTData();
+ ReleaseHLTData(false /* keep HLTOUT instance */);
}
return kFALSE;
}
/** instance of the HLTOUT handler */
AliHLTOUT* fpHLTOUT; // !transient
+ /** start reading HLTOUT from beginning */
+ bool fbReadFirst; //!transient
+
/** instance of the data handler providing the current data buffer */
AliHLTOUTHandler* fpDataHandler; // !transient
- ClassDef(AliRawReaderHLT, 3)
+ ClassDef(AliRawReaderHLT, 4)
};
#define ALIHLTREC_LIBRARY "libHLTrec.so"
AliHLTOfflineDataSink(),
fWriters(),
fNofDDLs(10),
- fIdFirstDDL(4864), // 0x13<<8
+ fIdFirstDDL(7680), // 0x1e<<8
fWriteDigits(kTRUE),
fWriteRaw(kTRUE),
fBuffer(),
// I guess DDL definitions should never change any more
assert(fNofDDLs==AliDAQ::NumberOfDdls("HLT"));
fNofDDLs=AliDAQ::NumberOfDdls("HLT");
+
+ /* AliDAQ::DdlIDOffset returns wrong offset for HLT links
assert(fIdFirstDDL==AliDAQ::DdlIDOffset("HLT"));
fIdFirstDDL=AliDAQ::DdlIDOffset("HLT");
+ */
}
AliHLTOUTComponent::~AliHLTOUTComponent()
for (int n=0; n<(int)evtData.fBlockCnt; n++ ) {
memset( homerHeader, 0, sizeof(homer_uint64)*kCount_64b_Words );
homerDescriptor.Initialize();
- homerDescriptor.SetType(*(reinterpret_cast<const homer_uint64*>(blocks[n].fDataType.fID)));
- homerDescriptor.SetSubType1(*(reinterpret_cast<const homer_uint32*>(blocks[n].fDataType.fOrigin)));
- homerDescriptor.SetSubType2(static_cast<homer_uint64>(blocks[n].fSpecification));
+ // for some traditional reason the TCPDumpSubscriber swaps the bytes
+ // of the data type id and data type origin. Actually I do not understand
+ // the corresponding code line
+ // homerBlock.SetType( blocks[n].fDataType.fID );
+ // this compiles in the PubSub framework and in addition does a byte swap
+ homer_uint64 id=0;
+ homer_uint64 origin=0;
+ memcpy(&id, blocks[n].fDataType.fID, sizeof(homer_uint64));
+ memcpy(((AliHLTUInt8_t*)&origin)+sizeof(homer_uint32), blocks[n].fDataType.fOrigin, sizeof(homer_uint32));
+ homerDescriptor.SetType(AliHLTOUT::Swap(id));
+ homerDescriptor.SetSubType1(AliHLTOUT::Swap(origin));
+ homerDescriptor.SetSubType2(blocks[n].fSpecification);
homerDescriptor.SetBlockSize(blocks[n].fSize);
int writerNo=ShuffleWriters(fWriters, blocks[n].fSize);
assert(writerNo>=0 && writerNo<(int)fWriters.size());
AliHLTOUT::AliHLTOUTEventHeader* pHLTH=reinterpret_cast<AliHLTOUT::AliHLTOUTEventHeader*>(&fBuffer[sizeof(AliRawDataHeader)]);
memset(pCDH, 0, sizeof(AliRawDataHeader));
memset(pHLTH, 0, sizeof(AliHLTOUT::AliHLTOUTEventHeader));
- pHLTH->fVersion=1;
+
if (pWriter) {
// copy payload
pWriter->Copy(&fBuffer[sizeof(AliRawDataHeader)+sizeof(AliHLTOUT::AliHLTOUTEventHeader)], 0, 0, 0, 0);
}
pHLTH->fLength+=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
pHLTH->fEventID=eventNo;
+ // version does not really matter since we do not add decision data
+ pHLTH->fVersion=AliHLTOUT::kVersion1;
pCDH->fSize=sizeof(AliRawDataHeader)+pHLTH->fLength;
+ pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::kCDHStatusFlagsOffset + AliHLTOUT::kCDHFlagsHLTPayload);
pBuffer=&fBuffer[0];
iResult=(int)bufferSize;