]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/sim/AliHLTOUTComponent.cxx
removing the HLT autoconf build system, however keep on using that for the
[u/mrichter/AliRoot.git] / HLT / sim / AliHLTOUTComponent.cxx
index 0d674102d7a6eb95567e31cad51767326cdb1d2b..7d0b309ddf25f7f9b5aaebe07a0dfd21b21f6e90 100644 (file)
 //* provided "as is" without express or implied warranty.                  *
 //**************************************************************************
 
-/** @file   AliHLTOUTComponent.cxx
-    @author Matthias Richter
-    @date   
-    @brief  The HLTOUT data sink component similar to HLTOUT nodes
-*/
+/ @file   AliHLTOUTComponent.cxx
+//  @author Matthias Richter
+//  @date   
+//  @brief  The HLTOUT data sink component similar to HLTOUT nodes
+//  @note   Used in the AliRoot environment only.
 
 #if __GNUC__>= 3
 using namespace std;
@@ -32,6 +32,7 @@ using namespace std;
 #include "AliHLTOUT.h"
 #include "AliHLTHOMERLibManager.h"
 #include "AliHLTHOMERWriter.h"
+#include "AliHLTErrorGuard.h"
 #include "AliDAQ.h" // equipment Ids
 #include "AliRawDataHeader.h" // Common Data Header 
 #include <TDatime.h> // seed for TRandom
@@ -39,23 +40,26 @@ using namespace std;
 #include <TFile.h>
 #include <TTree.h>
 #include <TArrayC.h>
+#include <TSystem.h>
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTOUTComponent)
 
-AliHLTOUTComponent::AliHLTOUTComponent()
-  :
-  AliHLTOfflineDataSink(),
-  fWriters(),
-  fNofDDLs(10),
-  fIdFirstDDL(7680), // 0x1e<<8
-  fBuffer(),
-  fpLibManager(NULL),
-  fpDigitFile(NULL),
-  fpDigitTree(NULL),
-  fppDigitArrays(NULL),
-  fReservedWriter(-1),
-  fReservedData(0)
+AliHLTOUTComponent::AliHLTOUTComponent(EType type)
+  : AliHLTOfflineDataSink()
+  , fWriters()
+  , fNofDDLs(10)
+  , fIdFirstDDL(7680) // 0x1e<<8
+  , fBuffer()
+  , fpLibManager(NULL)
+  , fOptions(0)
+  , fDigitFileName("HLT.Digits.root")
+  , fpDigitFile(NULL)
+  , fpDigitTree(NULL)
+  , fppDigitArrays(NULL)
+  , fReservedWriter(-1)
+  , fReservedData(0)
+  , fType(type)
 {
   // see header file for class documentation
   // or
@@ -71,6 +75,10 @@ AliHLTOUTComponent::AliHLTOUTComponent()
   assert(fIdFirstDDL==AliDAQ::DdlIDOffset("HLT"));
   fIdFirstDDL=AliDAQ::DdlIDOffset("HLT");
   */
+
+  if (fType!=kGlobal && fType!=kDigits && fType!=kRaw) {
+    ALIHLTERRORGUARD(1, "invalid component type %d", fType);
+  }
 }
 
 int AliHLTOUTComponent::fgOptions=kWriteRawFiles|kWriteDigits;
@@ -85,7 +93,14 @@ AliHLTOUTComponent::~AliHLTOUTComponent()
 const char* AliHLTOUTComponent::GetComponentID()
 {
   // see header file for class documentation
-  return "HLTOUT";
+  switch (fType) {
+  case kDigits: return "HLTOUTdigits";
+  case kRaw:    return "HLTOUTraw";
+  case kGlobal:
+  default:
+    return "HLTOUT";
+  }
+  return NULL;
 }
 
 void AliHLTOUTComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
@@ -98,43 +113,38 @@ void AliHLTOUTComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& lis
 AliHLTComponent* AliHLTOUTComponent::Spawn()
 {
   // see header file for class documentation
-  return new AliHLTOUTComponent;
+  return new AliHLTOUTComponent(fType);
 }
 
 int AliHLTOUTComponent::DoInit( int argc, const char** argv )
 {
   // see header file for class documentation
   int iResult=0;
-  TString argument="";
-  int bMissingParam=0;
-  for (int i=0; i<argc && iResult>=0; i++) {
-    argument=argv[i];
-    if (argument.IsNull()) continue;
-
-    // -links
-    if (argument.CompareTo("-links")==0) {
-      if ((bMissingParam=(++i>=argc))) break;
-      TString parameter(argv[i]);
-      parameter.Remove(TString::kLeading, ' '); // remove all blanks
-      if (parameter.IsDigit()) {
-       fNofDDLs=parameter.Atoi();
-      } else {
-       HLTError("wrong parameter for argument %s, number expected", argument.Data());
-       iResult=-EINVAL;
-      }
-    } else {
-      HLTError("unknown argument %s", argument.Data());
-      iResult=-EINVAL;
-      break;
-    }
-  }
-  if (bMissingParam) {
-    HLTError("missing parameter for argument %s", argument.Data());
-    iResult=-EINVAL;
-  }
-  if (iResult>=0) {
+
+  switch (fType) {
+  case kDigits:
+    fOptions|=kWriteDigits; fOptions&=~kWriteRawFiles;
+    HLTInfo("initializing HLTOUT component for digits generation");
+    break;
+  case kRaw:
+    fOptions|=kWriteRawFiles; fOptions&=~kWriteDigits;
+    HLTInfo("initializing HLTOUT component for raw data generation");
+    break;
+  case kGlobal:
+  default:
+    fOptions=fgOptions;
   }
 
+  if ((iResult=ConfigureFromArgumentString(argc, argv))<0) return iResult;
+
+  // Make sure there is no library manager before we try and create a new one.
+  if (fpLibManager) {
+    delete fpLibManager;
+    fpLibManager=NULL;
+  }
+  
+  // Create a new library manager and allocate the appropriate number of
+  // HOMER writers for the HLTOUT component.
   fpLibManager=new AliHLTHOMERLibManager;
   if (fpLibManager) {
     int writerNo=0;
@@ -156,6 +166,78 @@ int AliHLTOUTComponent::DoInit( int argc, const char** argv )
   return iResult;
 }
 
+int AliHLTOUTComponent::ScanConfigurationArgument(int argc, const char** argv)
+{
+  // see header file for class documentation
+  if (argc<=0) return 0;
+  int i=0;
+  TString argument=argv[i];
+  const char* key="";
+
+  // -links n
+  // specify number of ddl links
+  if (argument.CompareTo("-links")==0) {
+    if (++i>=argc) return -EPROTO;
+    TString parameter(argv[i]);
+    parameter.Remove(TString::kLeading, ' '); // remove all blanks
+    if (parameter.IsDigit()) {
+      fNofDDLs=parameter.Atoi();
+    } else {
+      HLTError("wrong parameter for argument %s, number expected", argument.Data());
+      return -EINVAL;
+    }
+
+    return 2;
+  } 
+
+  // -digitfile name
+  if (argument.CompareTo("-digitfile")==0) {
+    if (++i>=argc) return -EPROTO;
+    fDigitFileName=argv[i];
+
+    return 2;
+  }
+
+  // -rawout
+  key="-rawout";
+  if (argument.Contains(key)) {
+    argument.ReplaceAll(key, "");
+    if (argument.IsNull()) {
+      fOptions|=kWriteRawFiles;
+    } else if (argument.CompareTo("=off")==0) {
+      fOptions&=~kWriteRawFiles;
+    } else if (argument.CompareTo("=on")==0) {
+      fOptions|=kWriteRawFiles;
+    } else {
+      HLTError("invalid parameter for argument %s: possible %s=off/%s=on", key, key, key);
+      return -EPROTO;
+    }
+
+    return 1;
+  }
+
+  // -digitout
+  key="-digitout";
+  if (argument.Contains(key)) {
+    argument.ReplaceAll(key, "");
+    if (argument.IsNull()) {
+      fOptions|=kWriteDigits;
+    } else if (argument.CompareTo("=off")==0) {
+      fOptions&=~kWriteDigits;
+    } else if (argument.CompareTo("=on")==0) {
+      fOptions|=kWriteDigits;
+    } else {
+      HLTError("invalid parameter for argument %s: possible %s=off/%s=on", key, key, key);
+      return -EPROTO;
+    }
+
+    return 1;
+  }
+
+  // unknown argument
+  return -EINVAL;
+}
+
 int AliHLTOUTComponent::DoDeinit()
 {
   // see header file for class documentation
@@ -167,11 +249,19 @@ int AliHLTOUTComponent::DoDeinit()
       assert(*element);
       // wanted to have a dynamic_cast<AliHLTHOMERWriter*> here, but this results into
       // undefined symbol when loading the library
-      (*element)->Clear();
-      if (*element!=NULL) fpLibManager->DeleteWriter((AliHLTHOMERWriter*)(*element));
+      if (*element!=NULL) {
+       (*element)->Clear();
+       fpLibManager->DeleteWriter((AliHLTHOMERWriter*)(*element));
+      } else {
+       HLTError("writer instance is NULL");
+      }
       element=fWriters.erase(element);
     }
   }
+  if (fpLibManager) {
+    delete fpLibManager;
+    fpLibManager=NULL;
+  }
 
   if (fpDigitTree) {
     delete fpDigitTree;
@@ -203,6 +293,7 @@ int AliHLTOUTComponent::DumpEvent( const AliHLTComponentEventData& evtData,
   int iResult=0;
   HLTInfo("write %d output block(s)", evtData.fBlockCnt);
   int writerNo=0;
+  int blockCount=0;
   AliHLTUInt32_t eventType=gkAliEventTypeUnknown;
   bool bIsDataEvent=IsDataEvent(&eventType);
   if (iResult>=0) {
@@ -257,12 +348,19 @@ int AliHLTOUTComponent::DumpEvent( const AliHLTComponentEventData& evtData,
       // different fields in the homer header, which is an array of 64 bit
       // words.
       fWriters[writerNo]->AddBlock(homerHeader, blocks[n].fPtr);
+      blockCount++;
     }
   }
 
-  if (iResult>=0 && !bIsDataEvent) {
+  if (iResult>=0 && !bIsDataEvent && fNofDDLs>=2) {
     // data blocks from a special event are kept to be added to the
-    // following event.
+    // following event. In the current implementation at least 2 DDLs
+    // are required to allow to keep the blocks of the SOR event and
+    // include it in the first event. If only one writer is available
+    // the blocks are ignored. For the moment this is not expexted to
+    // be a problem since components should not gererate anything on
+    // SOR/EOR. The only case is the list of AliHLTComponentTableEntry
+    // transmitted for component statistics in debug mode.
     if (fReservedWriter>=0) {
       HLTWarning("overriding previous buffer of non-data event data blocks");
     }
@@ -271,26 +369,41 @@ int AliHLTOUTComponent::DumpEvent( const AliHLTComponentEventData& evtData,
     // TODO: not yet clear whether it is smart to send the event id of
     // this special event or if it should be set from the id of the
     // following event where the data will be added
-    if ((bufferSize=FillOutputBuffer(evtData.fEventID, fWriters[writerNo], pBuffer))>0) {
+    if (blockCount>0 && (bufferSize=FillOutputBuffer(evtData.fEventID, fWriters[writerNo], pBuffer))>0) {
       fReservedWriter=writerNo;
       fReservedData=bufferSize;
     }
     fWriters[writerNo]->Clear();
+  } else if (iResult>=0 && !bIsDataEvent && fNofDDLs<2 && blockCount>0) {
+    HLTWarning("ignoring %d block(s) for special event of type %d: at least 2 DDLs are required", blockCount, eventType);
+  }
+
+  if (iResult>=0 && bIsDataEvent) {
+    iResult=Write(GetEventCount(), GetRunLoader());
   }
 
   return iResult;
 }
 
-int AliHLTOUTComponent::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEvent* /*esd*/)
+
+int AliHLTOUTComponent::FillESD(int /*eventNo*/, AliRunLoader* /*runLoader*/, AliESDEvent* /*esd*/)
+{
+  // see header file for class documentation
+  // 2010-04-14 nothing to do any more. The data is written at the end of
+  // DumpEvent
+  return 0;
+}
+
+int AliHLTOUTComponent::Write(int eventNo, AliRunLoader* runLoader)
 {
   // see header file for class documentation
   int iResult=0;
 
   if (fWriters.size()==0) return 0;
-  
+
   if (fReservedWriter>=0) {
-    if (fgOptions&kWriteDigits) WriteDigitArray(fReservedWriter, &fBuffer[0], fReservedData);
-    if (fgOptions&kWriteRawFiles) WriteRawFile(eventNo, runLoader, fReservedWriter, &fBuffer[0], fReservedData);
+    if (fOptions&kWriteDigits) WriteDigitArray(fReservedWriter, &fBuffer[0], fReservedData);
+    if (fOptions&kWriteRawFiles) WriteRawFile(eventNo, runLoader, fReservedWriter, &fBuffer[0], fReservedData);
     fReservedData=0;
   }
 
@@ -316,13 +429,13 @@ int AliHLTOUTComponent::FillESD(int eventNo, AliRunLoader* runLoader, AliESDEven
     int bufferSize=0;
     
     if ((bufferSize=FillOutputBuffer(eventNo, fWriters[*ddlno], pBuffer))>0) {
-      if (fgOptions&kWriteDigits) WriteDigitArray(*ddlno, pBuffer, bufferSize);
-      if (fgOptions&kWriteRawFiles) WriteRawFile(eventNo, runLoader, *ddlno, pBuffer, bufferSize);
+      if (fOptions&kWriteDigits) WriteDigitArray(*ddlno, pBuffer, bufferSize);
+      if (fOptions&kWriteRawFiles) WriteRawFile(eventNo, runLoader, *ddlno, pBuffer, bufferSize);
     }
     fWriters[*ddlno]->Clear();
     ddlno++;
   }
-  if (fgOptions&kWriteDigits) WriteDigits(eventNo, runLoader);
+  if (fOptions&kWriteDigits) WriteDigits(eventNo, runLoader);
   return iResult;
 }
 
@@ -406,7 +519,7 @@ int AliHLTOUTComponent::FillOutputBuffer(int eventNo, AliHLTMonitoringWriter* pW
     // version does not really matter since we do not add decision data
     pHLTH->fVersion=AliHLTOUT::kVersion1;
 
-    pCDH->fSize=sizeof(AliRawDataHeader)+pHLTH->fLength;
+    pCDH->fSize=bufferSize;
     pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::kCDHStatusFlagsOffset + AliHLTOUT::kCDHFlagsHLTPayload);
     
     pBuffer=&fBuffer[0];
@@ -446,9 +559,8 @@ int AliHLTOUTComponent::WriteDigits(int /*eventNo*/, AliRunLoader* /*runLoader*/
 {
   // see header file for class documentation
   int iResult=0;
-  const char* digitFileName="HLT.Digits.root";
   if (!fpDigitFile) {
-    fpDigitFile=new TFile(digitFileName, "RECREATE");
+    fpDigitFile=new TFile(fDigitFileName, "RECREATE");
   }
   if (fpDigitFile && !fpDigitFile->IsZombie()) {
     if (!fpDigitTree) {
@@ -461,11 +573,17 @@ int AliHLTOUTComponent::WriteDigits(int /*eventNo*/, AliRunLoader* /*runLoader*/
       }
     }
     if (fpDigitTree) {
+#ifdef __DEBUG
       int res=fpDigitTree->Fill();
       HLTDebug("writing digit tree: %d", res);
       fpDigitFile->cd();
       res=fpDigitTree->Write("",TObject::kOverwrite);
       HLTDebug("writing digit tree: %d", res);
+#else
+      fpDigitTree->Fill();
+      fpDigitFile->cd();
+      fpDigitTree->Write("",TObject::kOverwrite);
+#endif
       if (fppDigitArrays) for (int i=0; i<fNofDDLs; i++) {
        if (fppDigitArrays[i]) fppDigitArrays[i]->Set(0);
       }
@@ -476,7 +594,7 @@ int AliHLTOUTComponent::WriteDigits(int /*eventNo*/, AliRunLoader* /*runLoader*/
       errorMsg=" (suppressing further error messages)";
     }
     if (GetEventCount()<5) {
-      HLTError("can not open HLT digit file %s%s", digitFileName, errorMsg);
+      HLTError("can not open HLT digit file %s%s", fDigitFileName.Data(), errorMsg);
     }
     iResult=-EBADF;
   }
@@ -491,6 +609,10 @@ int AliHLTOUTComponent::WriteRawFile(int eventNo, AliRunLoader* /*runLoader*/, i
   assert(fileName!=NULL);
   TString filePath;
   filePath.Form("raw%d/", eventNo);
+  if (gSystem->AccessPathName(filePath)) {
+    TString command="mkdir "; command+=filePath;
+    gSystem->Exec(command);
+  }
   filePath+=fileName;
   if (fileName) {
     ios::openmode filemode=(ios::openmode)0;
@@ -522,3 +644,9 @@ void AliHLTOUTComponent::ClearGlobalOption(unsigned int options)
   // see header file for class documentation
   fgOptions&=~options;
 }
+
+bool AliHLTOUTComponent::TestGlobalOption(unsigned int option)
+{
+  // see header file for class documentation
+  return (fgOptions&option)!=0;
+}