From 4b113031872d0e403e1b5657dc259ef238734cda Mon Sep 17 00:00:00 2001 From: richterm Date: Mon, 29 Oct 2007 18:54:03 +0000 Subject: [PATCH] further work on HLTOUT component;CDH and HLT OUT Event header;bugfixes in AliHLTOUTHomerBuffer --- HLT/BASE/AliHLTOUT.cxx | 8 ++ HLT/BASE/AliHLTOUT.h | 24 ++++ HLT/BASE/AliHLTOUTHomerBuffer.cxx | 8 +- HLT/sim/AliHLTOUTComponent.cxx | 200 +++++++++++++++++++++++++++++- HLT/sim/AliHLTOUTComponent.h | 58 +++++++++ 5 files changed, 288 insertions(+), 10 deletions(-) diff --git a/HLT/BASE/AliHLTOUT.cxx b/HLT/BASE/AliHLTOUT.cxx index 5bdde9a31ff..0641d8d094b 100644 --- a/HLT/BASE/AliHLTOUT.cxx +++ b/HLT/BASE/AliHLTOUT.cxx @@ -49,6 +49,14 @@ AliHLTOUT::AliHLTOUT() // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt } +// definitions from ALICE internal note ALICE-INT-2002-010 +const unsigned char AliHLTOUT::fgkCDHStatusWord=4; +const unsigned char AliHLTOUT::fgkCDHStatusFlagsOffset=12; + +// definitions from ALICE internal note ALICE-INT-2006-XXX +const unsigned char AliHLTOUT::fgkCDHFlagsHLTDecision=6; +const unsigned char AliHLTOUT::fgkCDHFlagsHLTPayload=7; + AliHLTOUT::~AliHLTOUT() { // see header file for class documentation diff --git a/HLT/BASE/AliHLTOUT.h b/HLT/BASE/AliHLTOUT.h index 7cb94fc9f84..4586b44b67d 100644 --- a/HLT/BASE/AliHLTOUT.h +++ b/HLT/BASE/AliHLTOUT.h @@ -109,6 +109,30 @@ class AliHLTOUT : public AliHLTLogging { AliHLTOUT* fpInstance; //!transient }; + /** + * The HLT OUT Event Header. + * Defined between HLT and DAQ. + */ + struct AliHLTOUTEventHeader { + /**Total length of the data in bytes, including HLT event header, excluding CDH. */ + AliHLTUInt32_t fLength; //! see above + /** version of the header */ + AliHLTUInt32_t fVersion; //! see above + /** event id */ + AliHLTUInt64_t fEventID; //! see above + }; + + // definitions from ALICE internal notes ALICE-INT-2002-010 and + // ALICE-INT-2006-XXX + /** the 32bit word in the CDH containing the status flags */ + static const unsigned char fgkCDHStatusWord; //! see above + /** start of the flags in word fgkCDHStatusWord */ + static const unsigned char fgkCDHStatusFlagsOffset; //! see above + /** bit indicating HLT decision in the HLTOUT*/ + static const unsigned char fgkCDHFlagsHLTDecision; //! see above + /** bit indicating HLT payload in the HLTOUT*/ + static const unsigned char fgkCDHFlagsHLTPayload; //! see above + /** * Block descriptor. */ diff --git a/HLT/BASE/AliHLTOUTHomerBuffer.cxx b/HLT/BASE/AliHLTOUTHomerBuffer.cxx index 73c6bf3f552..b93514b0423 100644 --- a/HLT/BASE/AliHLTOUTHomerBuffer.cxx +++ b/HLT/BASE/AliHLTOUTHomerBuffer.cxx @@ -39,10 +39,10 @@ ClassImp(AliHLTOUTHomerBuffer) AliHLTOUTHomerBuffer::AliHLTOUTHomerBuffer(const AliHLTUInt8_t* pBuffer, int size) : AliHLTOUT(), + fpManager(new AliHLTHOMERLibManager), fpBuffer(pBuffer), fSize(size), - fpReader(NULL), - fpManager(new AliHLTHOMERLibManager) + fpReader(NULL) { // see header file for class documentation // or @@ -131,8 +131,8 @@ int AliHLTOUTHomerBuffer::ScanReader(AliHLTHOMERReader* pReader, AliHLTUInt32_t HLTError("index range %#x exceeded for %d data blocks", nofBlocks, offset); iResult=-ERANGE; } - tmp2>>1; - tmp1<<1; + tmp2>>=1; + tmp1<<=1; } // loop over data blocks diff --git a/HLT/sim/AliHLTOUTComponent.cxx b/HLT/sim/AliHLTOUTComponent.cxx index bbefa948c01..a377f82da52 100644 --- a/HLT/sim/AliHLTOUTComponent.cxx +++ b/HLT/sim/AliHLTOUTComponent.cxx @@ -31,28 +31,44 @@ using namespace std; #endif +#include #include "AliHLTOUTComponent.h" +#include "AliHLTOUT.h" +#include "AliHLTHOMERWriter.h" +#include "AliDAQ.h" // euqipment Ids +#include "AliRawDataHeader.h" // Common Data Header +#include // seed for TRandom +#include // random int generation for DDL no /** ROOT macro for the implementation of ROOT specific class methods */ ClassImp(AliHLTOUTComponent) AliHLTOUTComponent::AliHLTOUTComponent() : - AliHLTOfflineDataSink() + AliHLTOfflineDataSink(), + fWriters(), + fNofDDLs(10), + fIdFirstDDL(4864), // 0x13<<8 + fWriteDigits(kTRUE), + fWriteRaw(kTRUE), + fBuffer() { // see header file for class documentation // or // refer to README to build package // or // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt + + // I guess DDL definitions should never change any more + assert(fNofDDLs==AliDAQ::NumberOfDdls("HLT")); + fNofDDLs=AliDAQ::NumberOfDdls("HLT"); + assert(fIdFirstDDL==AliDAQ::DdlIDOffset("HLT")); + fIdFirstDDL=AliDAQ::DdlIDOffset("HLT"); } AliHLTOUTComponent::~AliHLTOUTComponent() { // see header file for class documentation - - // file list and file name list are owner of their objects and - // delete all the objects } const char* AliHLTOUTComponent::GetComponentID() @@ -96,6 +112,17 @@ int AliHLTOUTComponent::DoInit( int argc, const char** argv ) if (iResult>=0) { } + int writerNo=0; + for (writerNo=0; writerNo::iterator element=fWriters.begin(); + while (element!= fWriters.end()) { + assert(*element); + if (*element!=NULL) delete *element; + element=fWriters.erase(element); + } return iResult; } @@ -114,16 +148,170 @@ int AliHLTOUTComponent::DumpEvent( const AliHLTComponentEventData& evtData, // see header file for class documentation int iResult=0; HLTInfo("write %d output blocks", evtData.fBlockCnt); - for (int n=0; n<(int)evtData.fBlockCnt; n++ ) { + fWriters.clear(); + if (iResult>=0) { + homer_uint64 homerHeader[kCount_64b_Words]; + HOMERBlockDescriptor homerDescriptor(homerHeader); + for (int n=0; n<(int)evtData.fBlockCnt; n++ ) { + memset( homerHeader, 0, sizeof(homer_uint64)*kCount_64b_Words ); + homerDescriptor.Initialize(); + homerDescriptor.SetType(reinterpret_cast(blocks[n].fDataType.fID)); + homerDescriptor.SetSubType1(reinterpret_cast(blocks[n].fDataType.fOrigin)); + homerDescriptor.SetSubType2(static_cast(blocks[n].fSpecification)); + int writerNo=ShuffleWriters(fWriters, blocks[n].fSize); + assert(writerNo>=0 && writerNoAddBlock(&homerDescriptor, blocks[n].fPtr); + } + } + + return iResult; +} + +int AliHLTOUTComponent::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* /*esd*/) +{ + // see header file for class documentation + int iResult=0; + if (fWriters.size()==0) return 0; + + // search for the writer with the biggest data volume in order to allocate the + // output buffer of sufficient size + AliHLTHOMERWriterPVector::iterator writer=fWriters.begin(); + vector sorted; + for (int i=0; i=0 && fWriters[i]->GetTotalMemorySize()>fWriters[sorted[0]]->GetTotalMemorySize()) { + sorted.insert(sorted.begin(), i); + } else { + sorted.push_back(i); + } + } + writer++; + } + + vector::iterator ddlno=sorted.begin(); + while (ddlno!=sorted.end()) { + const AliHLTUInt8_t* pBuffer=NULL; + int bufferSize=0; + + if ((bufferSize=FillOutputBuffer(eventNo, *writer, pBuffer))>0) { + if (fWriteDigits) WriteDigits(eventNo, runLoader, *ddlno, pBuffer, bufferSize); + if (fWriteRaw) WriteRawFile(eventNo, runLoader, *ddlno, pBuffer, bufferSize); + } + ddlno++; + } + return iResult; +} + +int AliHLTOUTComponent::ShuffleWriters(AliHLTHOMERWriterPVector &list, AliHLTUInt32_t size) +{ + // see header file for class documentation + int iResult=-ENOENT; + assert(list.size()>0); + if (list.size()==0) return iResult; + vector writers; + int i=0; + for (i=0; iGetTotalMemorySize()==0) + writers.push_back(i); + else if (iResult<0 || + list[i]->GetTotalMemorySize()GetTotalMemorySize()) + iResult=i; + + } + if (writers.size()>0) { + iResult=writers[0]; + if (writers.size()>0) { + // shuffle among the empty writers + TDatime dt; + TRandom rand; + rand.SetSeed(dt.Get()*(iResult+1)); + i=rand.Integer(writers.size()-1); + assert(i>0 && i=0); + } + return iResult; +} + +int AliHLTOUTComponent::FillOutputBuffer(int eventNo, AliHLTHOMERWriter* pWriter, const AliHLTUInt8_t* &pBuffer) +{ + // see header file for class documentation + int iResult=0; + int bufferSize=0; + + // space for common data header + bufferSize+=sizeof(AliRawDataHeader); + assert(sizeof(AliRawDataHeader)==24); + + // space for HLT event header + bufferSize+=sizeof(AliHLTOUT::AliHLTOUTEventHeader); + + // space for payload from the writer + if (pWriter) bufferSize+=pWriter->GetTotalMemorySize(); + + if (bufferSize>fBuffer.size()) + fBuffer.resize(bufferSize); + + if (bufferSize<=fBuffer.size()) { + AliRawDataHeader* pCDH=reinterpret_cast(&fBuffer[0]); + AliHLTOUT::AliHLTOUTEventHeader* pHLTH=reinterpret_cast(&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=pWriter->GetTotalMemorySize(); + // set status bit to indicate HLT payload + pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::fgkCDHStatusFlagsOffset+AliHLTOUT::fgkCDHFlagsHLTPayload); + } + pHLTH->fLength+=sizeof(AliHLTOUT::AliHLTOUTEventHeader); + pHLTH->fEventID=eventNo; + + pCDH->fSize=sizeof(AliRawDataHeader)+pHLTH->fLength; + pBuffer=&fBuffer[0]; + } else { + pBuffer=NULL; + iResult=-ENOMEM; } return iResult; } -int AliHLTOUTComponent::FillESD(int /*eventNo*/, AliRunLoader* /*runLoader*/, AliESDEvent* /*esd*/) +int AliHLTOUTComponent::WriteDigits(int eventNo, AliRunLoader* runLoader, int hltddl, const AliHLTUInt8_t* pBuffer, int bufferSize) { // see header file for class documentation int iResult=0; return iResult; } + +int AliHLTOUTComponent::WriteRawFile(int eventNo, AliRunLoader* runLoader, int hltddl, const AliHLTUInt8_t* pBuffer, int bufferSize) +{ + // see header file for class documentation + int iResult=0; + const char* fileName=AliDAQ::DdlFileName("HLT", hltddl); + TString filePath; + assert(fileName!=NULL); + if (fileName) { + ios::openmode filemode=(ios::openmode)0; + ofstream rawfile(filePath.Data(), filemode); + if (rawfile.good()) { + if (pBuffer && bufferSize>0) { + rawfile.write(reinterpret_cast(pBuffer), bufferSize); + } else { + HLTWarning("writing zero length raw data file %s"); + } + HLTDebug("wrote %d byte(s) to file %s", bufferSize, filePath.Data()); + } else { + HLTError("can not open file %s for writing", filePath.Data()); + iResult=-EBADF; + } + rawfile.close(); + } + return iResult; +} diff --git a/HLT/sim/AliHLTOUTComponent.h b/HLT/sim/AliHLTOUTComponent.h index 58cf4e82742..d7b957040eb 100644 --- a/HLT/sim/AliHLTOUTComponent.h +++ b/HLT/sim/AliHLTOUTComponent.h @@ -18,9 +18,13 @@ // or // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt +#include #include "AliHLTOfflineDataSink.h" #include +class AliHLTHOMERWriter; +typedef vector AliHLTHOMERWriterPVector; + /** * @class AliHLTOUTComponent * The HLTOUT data sink component which models the behavior of the HLTOUT @@ -76,6 +80,60 @@ class AliHLTOUTComponent : public AliHLTOfflineDataSink { /** assignment operator prohibited */ AliHLTOUTComponent& operator=(const AliHLTOUTComponent&); + int ShuffleWriters(AliHLTHOMERWriterPVector &list, AliHLTUInt32_t size); + + /** + * Fill the output buffer and allocate if neccessary. + * Assemble ouput buffer with Common Data Header, HLT header and data from the + * writer. Works on the same buffer witch is allocated once and eventually + * grown in order to avoid frequent allocs/deallocs. + * @param eventNo number of the event + * @param pWriter [IN] the HOMER writer + * @param pBuffer [OUT] target to receive the pointer to buffer + * @return size of the buffer + */ + int FillOutputBuffer(int eventNo, AliHLTHOMERWriter* pWriter, const AliHLTUInt8_t* &pBuffer); + + /** + * Write the digits for one DDL + * @param eventNo number of the event + * @param runLoader AliRoot run loader instance + * @param hltddl Number of DDL link within the range of HLT + * @param pBuffer buffer to write + * @param size size of the buffer + * @return neg. error if failed + */ + int WriteDigits(int eventNo, AliRunLoader* runLoader, int hltddl, const AliHLTUInt8_t* pBuffer, int size); + + /** + * Write the raw file for one DDL + * @param eventNo number of the event + * @param runLoader AliRoot run loader instance + * @param hltddl Number of DDL link within the range of HLT + * @param pBuffer buffer to write + * @param size size of the buffer + * @return neg. error if failed + */ + int WriteRawFile(int eventNo, AliRunLoader* runLoader, int hltddl, const AliHLTUInt8_t* pBuffer, int size); + + /** list of HOMER writers */ + AliHLTHOMERWriterPVector fWriters; //!transient + + /** number of DDLs used*/ + int fNofDDLs; //!transient + + /** equipment ID of first HLT DDL */ + int fIdFirstDDL; //!transient + + /** write digits or not */ + Bool_t fWriteDigits; //!transient + + /** write raw file or not */ + Bool_t fWriteRaw; //!transient + + /** output buffer, allocated once in order to avoid frequent alloc/dealloc */ + vector fBuffer; //!transient + ClassDef(AliHLTOUTComponent, 0) }; #endif -- 2.43.0