further work on HLTOUT component;CDH and HLT OUT Event header;bugfixes in AliHLTOUTHo...
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 29 Oct 2007 18:54:03 +0000 (18:54 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Mon, 29 Oct 2007 18:54:03 +0000 (18:54 +0000)
HLT/BASE/AliHLTOUT.cxx
HLT/BASE/AliHLTOUT.h
HLT/BASE/AliHLTOUTHomerBuffer.cxx
HLT/sim/AliHLTOUTComponent.cxx
HLT/sim/AliHLTOUTComponent.h

index 5bdde9a..0641d8d 100644 (file)
@@ -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
index 7cb94fc..4586b44 100644 (file)
@@ -110,6 +110,30 @@ class AliHLTOUT : public AliHLTLogging {
   };
 
   /**
+   * 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.
    */
   class AliHLTOUTBlockDescriptor {
index 73c6bf3..b93514b 100644 (file)
@@ -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
index bbefa94..a377f82 100644 (file)
 using namespace std;
 #endif
 
+#include <cassert>
 #include "AliHLTOUTComponent.h"
+#include "AliHLTOUT.h"
+#include "AliHLTHOMERWriter.h"
+#include "AliDAQ.h" // euqipment Ids
+#include "AliRawDataHeader.h" // Common Data Header 
+#include <TDatime.h> // seed for TRandom
+#include <TRandom.h> // 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<fNofDDLs; writerNo++) {
+    AliHLTHOMERWriter* pWriter=new AliHLTHOMERWriter;
+    if (pWriter) {
+      fWriters.push_back(pWriter);
+    } else {
+      iResult=-ENOMEM;
+      break;
+    }
+  }
+
   return iResult;
 }
 
@@ -103,6 +130,13 @@ int AliHLTOUTComponent::DoDeinit()
 {
   // see header file for class documentation
   int iResult=0;
+
+  vector<AliHLTHOMERWriter*>::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<homer_uint64>(blocks[n].fDataType.fID));
+      homerDescriptor.SetSubType1(reinterpret_cast<homer_uint64>(blocks[n].fDataType.fOrigin));
+      homerDescriptor.SetSubType2(static_cast<homer_uint64>(blocks[n].fSpecification));
+      int writerNo=ShuffleWriters(fWriters, blocks[n].fSize);
+      assert(writerNo>=0 && writerNo<fWriters.size());
+      fWriters[writerNo]->AddBlock(&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<int> sorted;
+  for (int i=0; i<fWriters.size(); i++) {
+    assert(fWriters[i]);
+    if (fWriters[i]) {
+      if (sorted.size()>=0 && fWriters[i]->GetTotalMemorySize()>fWriters[sorted[0]]->GetTotalMemorySize()) {
+       sorted.insert(sorted.begin(), i);
+      } else {
+       sorted.push_back(i);
+      }
+    }
+    writer++;
+  }
+
+  vector<int>::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<int> writers;
+  int i=0;
+  for (i=0; i<list.size(); i++) {
+    if (list[i]->GetTotalMemorySize()==0)
+      writers.push_back(i);
+    else if (iResult<0 ||
+            list[i]->GetTotalMemorySize()<list[iResult]->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<writers.size()-1);
+      iResult=writers[i];
+    }
+  } else {
+    // take the writer with the least data volume
+    assert(iResult>=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<AliRawDataHeader*>(&fBuffer[0]);
+    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=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<const char*>(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;
+}
index 58cf4e8..d7b9570 100644 (file)
 // or
 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
 
+#include <vector>
 #include "AliHLTOfflineDataSink.h"
 #include <TString.h>
 
+class AliHLTHOMERWriter;
+typedef vector<AliHLTHOMERWriter*> 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<AliHLTUInt8_t> fBuffer; //!transient
+
   ClassDef(AliHLTOUTComponent, 0)
 };
 #endif