Fixing various dependecies
authoragrigora <alina.grigoras@cern.ch>
Mon, 10 Nov 2014 14:27:33 +0000 (15:27 +0100)
committeragrigora <alina.grigoras@cern.ch>
Mon, 15 Dec 2014 12:51:54 +0000 (13:51 +0100)
ANALYSIS/ANALYSIS/CMakeLists.txt
ANALYSIS/ANALYSISalice/CMakeLists.txt
ANALYSIS/ANALYSIScalib/CMakeLists.txt
ANALYSIS/ESDfilter/CMakeLists.txt
ANALYSIS/EventMixing/CMakeLists.txt
ANALYSIS/Tender/CMakeLists.txt
ANALYSIS/TenderSupplies/CMakeLists.txt
HLT/BASE/AliHLTOUTComponent.cxx [new file with mode: 0644]
HLT/BASE/AliHLTOUTComponent.h [new file with mode: 0644]
STEER/STEER/AliHLTSimulation.cxx [new file with mode: 0644]
STEER/STEER/AliHLTSimulation.h [new file with mode: 0644]

index 8e8a853..a4dc248 100644 (file)
@@ -20,8 +20,7 @@ set(MODULE ANALYSIS)
 include_directories(${AliRoot_SOURCE_DIR}/ANALYSIS/${MODULE})
 
 # Additional include folders in alphabetical order except ROOT
-include_directories(${ROOT_INCLUDE_DIRS} 
-                    ${AliRoot_SOURCE_DIR}/STEER/STEERBase
+include_directories(${AliRoot_SOURCE_DIR}/STEER/STEERBase
                    )
 
 # Sources in alphabetical order
@@ -47,7 +46,7 @@ generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${HDRS}" "${incdirs}")
 
 # Generate the ROOT map
 # Dependecies
-set(LIBDEPS STEERBase XMLParser)
+set(LIBDEPS STEERBase Core Gpad Hist Net RIO Tree XMLParser)
 generate_rootmap("${MODULE}" "${LIBDEPS}" "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}LinkDef.h")
 
 # Add a library to the project using the specified source files
index 83a3228..3d9963f 100644 (file)
@@ -89,11 +89,12 @@ generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${HDRS}" "${incdirs}")
 
 # Generate the ROOT map
 # Dependecies
-set(LIBDEPS ANALYSIS OADB AOD ESD STEERBase Net)
+set(LIBDEPS ANALYSIS OADB AOD ESD STEERBase Core EG Gpad Gui Hist MathCore Matrix Net Physics RIO TreePlayer Tree XMLIO)
 generate_rootmap("${MODULE}" "${LIBDEPS}" "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}LinkDef.h")
 
 # Add a library to the project using the specified source files
 add_library(${MODULE} SHARED ${SRCS} G__${MODULE}.cxx)
+target_link_libraries(${MODULE} STEERBase OADB AOD ESD ANALYSIS Core EG Gpad Gui Hist MathCore Matrix Net Physics RIO TreePlayer Tree XMLIO)
 
 # Additional compilation flags
 set_target_properties(${MODULE} PROPERTIES COMPILE_FLAGS "-O -g")
index 53c41f4..78aa3eb 100644 (file)
@@ -46,12 +46,12 @@ generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${HDRS}" "${incdirs}")
 
 # Generate the ROOT map
 # Dependecies
-set(LIBDEPS ANALYSIS ESD STEERBase)
+set(LIBDEPS ANALYSIS ESD STEERBase Core Hist MathCore Net RIO Tree)
 generate_rootmap("${MODULE}" "${LIBDEPS}" "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}LinkDef.h")
 
-
 # Add a library to the project using the specified source files
 add_library(${MODULE} SHARED ${SRCS} G__${MODULE}.cxx)
+target_link_libraries(${MODULE} ANALYSIS ESD STEERBase Core Hist MathCore Net RIO Tree)
 
 # Additional compilation flags
 set_target_properties(${MODULE} PROPERTIES COMPILE_FLAGS "-O -g")
index 3f87568..c9ebdfd 100644 (file)
@@ -45,12 +45,12 @@ generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${HDRS}" "${incdirs}")
 
 # Generate the ROOT map
 # Dependecies
-set(LIBDEPS ANALYSIS ANALYSISalice OADB AOD ESD STEERBase EMCALUtils)
+set(LIBDEPS ANALYSIS ANALYSISalice OADB AOD ESD STEERBase EMCALUtils Core EG Hist MathCore Physics RIO Tree)
 generate_rootmap("${MODULE}" "${LIBDEPS}" "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}LinkDef.h")
 
-
 # Add a library to the project using the specified source files
 add_library(${MODULE} SHARED ${SRCS} G__${MODULE}.cxx)
+target_link_libraries(${MODULE} ANALYSIS ANALYSISalice OADB AOD ESD STEERBase EMCALUtils Core EG Hist MathCore Physics RIO Tree)
 
 # Additional compilation flags
 set_target_properties(${MODULE} PROPERTIES COMPILE_FLAGS "-O -g")
index 29aad43..219146d 100644 (file)
@@ -48,11 +48,12 @@ generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${HDRS}" "${incdirs}")
 
 # Generate the ROOT map
 # Dependecies
-set(LIBDEPS ANALYSIS ANALYSISalice AOD ESD STEERBase)
+set(LIBDEPS ANALYSIS ANALYSISalice AOD ESD STEERBase Core Gpad Hist RIO Tree)
 generate_rootmap("${MODULE}" "${LIBDEPS}" "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}LinkDef.h")
 
 # Add a library to the project using the specified source files
 add_library(${MODULE} SHARED ${SRCS} G__${MODULE}.cxx)
+target_link_libraries(${MODULE} ANALYSIS ANALYSISalice AOD ESD STEERBase Core Gpad Hist RIO Tree)
 
 # Additional compilation flags
 set_target_properties(${MODULE} PROPERTIES COMPILE_FLAGS "-O -g")
index 560adbb..2982e3f 100644 (file)
@@ -44,11 +44,12 @@ generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${HDRS}" "${incdirs}")
 
 # Generate the ROOT map
 # Dependecies
-set(LIBDEPS ANALYSIS ANALYSISalice CDB ESD STEERBase)
+set(LIBDEPS ANALYSIS ANALYSISalice CDB ESD STEERBase Core RIO)
 generate_rootmap("${MODULE}" "${LIBDEPS}" "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}LinkDef.h")
 
 # Add a library to the project using the specified source files
 add_library(${MODULE} SHARED ${SRCS} G__${MODULE}.cxx)
+target_link_libraries(${MODULE} ANALYSIS ANALYSISalice CDB ESD STEERBase Core RIO)
 
 # Additional compilation flags
 set_target_properties(${MODULE} PROPERTIES COMPILE_FLAGS "-O -g")
index 39b59a8..9a8f75d 100644 (file)
@@ -24,13 +24,11 @@ include_directories(${ROOT_INCLUDE_DIRS}
                     ${AliRoot_SOURCE_DIR}/ANALYSIS/ANALYSIS
                     ${AliRoot_SOURCE_DIR}/ANALYSIS/ANALYSISalice
                     ${AliRoot_SOURCE_DIR}/ANALYSIS/Tender
-                    ${AliRoot_SOURCE_DIR}/EMCAL
                     ${AliRoot_SOURCE_DIR}/EMCAL/EMCALbase
                     ${AliRoot_SOURCE_DIR}/EMCAL/EMCALrec
                     ${AliRoot_SOURCE_DIR}/EMCAL/EMCALUtils
                     ${AliRoot_SOURCE_DIR}/CORRFW
                     ${AliRoot_SOURCE_DIR}/OADB
-                    ${AliRoot_SOURCE_DIR}/PHOS
                     ${AliRoot_SOURCE_DIR}/PHOS/PHOSbase
                     ${AliRoot_SOURCE_DIR}/PHOS/PHOSrec
                     ${AliRoot_SOURCE_DIR}/PHOS/PHOSUtils
@@ -39,18 +37,12 @@ include_directories(${ROOT_INCLUDE_DIRS}
                     ${AliRoot_SOURCE_DIR}/STEER/ESD
                     ${AliRoot_SOURCE_DIR}/STEER/STEER
                     ${AliRoot_SOURCE_DIR}/STEER/STEERBase
-                    ${AliRoot_SOURCE_DIR}/T0
                     ${AliRoot_SOURCE_DIR}/T0/T0rec
-                    ${AliRoot_SOURCE_DIR}/TOF/
                     ${AliRoot_SOURCE_DIR}/TOF/TOFbase
                     ${AliRoot_SOURCE_DIR}/TOF/TOFrec
-                    ${AliRoot_SOURCE_DIR}/TPC
                     ${AliRoot_SOURCE_DIR}/TPC/Base
                     ${AliRoot_SOURCE_DIR}/TPC/TPCbase
-                    ${AliRoot_SOURCE_DIR}/TRD
-                    ${AliRoot_SOURCE_DIR}/TRD/Cal
                     ${AliRoot_SOURCE_DIR}/TRD/TRDbase
-                    ${AliRoot_SOURCE_DIR}/VZERO
                     ${AliRoot_SOURCE_DIR}/VZERO/VZERObase
                     ${AliRoot_SOURCE_DIR}/VZERO/VZEROrec
                    )
@@ -81,11 +73,12 @@ generate_dictionary("${MODULE}" "${MODULE}LinkDef.h" "${HDRS}" "${incdirs}")
 
 # Generate the ROOT map
 # Dependecies
-set(LIBDEPS ANALYSIS ANALYSISalice Tender EMCAL EMCALbase EMCALrec EMCALUtils CORRFW OADB PHOS PHOSbase PHOSrec PHOSUtils AOD CDB ESD STEER STEERBase T0 T0rec TOF TOFbase TOFrec TPC TPCBase TRD TRDCal TRDBase VZERO VZEROBase VZEROrec)
+set(LIBDEPS ANALYSIS ANALYSISalice Tender EMCALbase EMCALrec EMCALUtils CORRFW OADB PHOSbase PHOSrec PHOSUtils AOD CDB ESD STEER STEERBase T0rec TOFbase TOFrec TPCbase TRDbase VZERObase VZEROrec Core Geom Gpad Graf Hist MathCore Matrix Physics RIO Tree)
 generate_rootmap("${MODULE}" "${LIBDEPS}" "${CMAKE_CURRENT_SOURCE_DIR}/${MODULE}LinkDef.h")
 
 # Add a library to the project using the specified source files
 add_library(${MODULE} SHARED ${SRCS} G__${MODULE}.cxx)
+target_link_libraries(${MODULE} ANALYSIS ANALYSISalice Tender EMCALbase EMCALrec EMCALUtils CORRFW OADB PHOSbase PHOSrec PHOSUtils AOD CDB ESD STEER STEERBase T0rec TOFbase TOFrec TPCbase TRDbase VZERObase VZEROrec Core Geom Gpad Graf Hist MathCore Matrix Physics RIO Tree)
 
 # Additional compilation flags
 set_target_properties(${MODULE} PROPERTIES COMPILE_FLAGS "-O -g")
diff --git a/HLT/BASE/AliHLTOUTComponent.cxx b/HLT/BASE/AliHLTOUTComponent.cxx
new file mode 100644 (file)
index 0000000..71eb1fb
--- /dev/null
@@ -0,0 +1,667 @@
+// $Id$
+
+//**************************************************************************
+//* This file is property of and copyright by the                          * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+//*                  for The ALICE HLT Project.                            *
+//*                                                                        *
+//* Permission to use, copy, modify and distribute this software and its   *
+//* documentation strictly for non-commercial purposes is hereby granted   *
+//* without fee, provided that the above copyright notice appears in all   *
+//* copies and that both the copyright notice and this permission notice   *
+//* appear in the supporting documentation. The authors make no claims     *
+//* about the suitability of this software for any purpose. It is          *
+//* 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
+/// @note   Used in the AliRoot environment only.
+
+#include <cassert>
+//#include <iostream>
+#include "AliHLTOUTComponent.h"
+#include "AliHLTOUT.h"
+#include "AliHLTHOMERLibManager.h"
+#include "AliHLTHOMERWriter.h"
+#include "AliHLTErrorGuard.h"
+#include "AliDAQ.h" // equipment Ids
+#include "AliRawDataHeaderV3.h" // Common Data Header 
+#include <TDatime.h> // seed for TRandom
+#include <TRandom.h> // random int generation for DDL no
+#include <TFile.h>
+#include <TTree.h>
+#include <TArrayC.h>
+#include <TSystem.h>
+
+using namespace std;
+
+/** ROOT macro for the implementation of ROOT specific class methods */
+ClassImp(AliHLTOUTComponent)
+
+AliHLTOUTComponent::AliHLTOUTComponent(EType type)
+  : AliHLTDataSink()
+  , 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)
+  , fRoundRobinCounter(0)
+{
+  // The HLTOUT data sink component which models the behavior of the HLTOUT
+  // nodes of the HLT cluster.
+  // The HLTOUT component is attached at the end of a chain. It stores all input
+  // block in the HOMER format, distributed over a number of DDL link. The data
+  // is stored in a digit file or in raw ddl files.
+  fIdFirstDDL=AliDAQ::DdlIDOffset("HLT");
+  fNofDDLs=AliDAQ::NumberOfDdls("HLT");
+  
+  if (fType!=kGlobal && fType!=kDigits && fType!=kRaw) {
+    ALIHLTERRORGUARD(1, "invalid component type %d", fType);
+  }
+}
+
+int AliHLTOUTComponent::fgOptions=kWriteRawFiles|kWriteDigits;
+
+AliHLTOUTComponent::~AliHLTOUTComponent()
+{
+  // destructor
+  if (fpLibManager) delete fpLibManager;
+  fpLibManager=NULL;
+}
+
+const char* AliHLTOUTComponent::GetComponentID()
+{
+  // overloaded from AliHLTComponent: get component id
+  switch (fType) {
+  case kDigits: return "HLTOUTdigits";
+  case kRaw:    return "HLTOUTraw";
+  case kGlobal:
+  default:
+    return "HLTOUT";
+  }
+  return NULL;
+}
+
+void AliHLTOUTComponent::GetInputDataTypes( AliHLTComponentDataTypeList& list)
+{
+  // overloaded from AliHLTComponent: indicate input data types
+  list.clear();
+  list.push_back(kAliHLTAnyDataType);
+}
+
+AliHLTComponent* AliHLTOUTComponent::Spawn()
+{
+  // overloaded from AliHLTComponent: create instance
+  return new AliHLTOUTComponent(fType);
+}
+
+int AliHLTOUTComponent::DoInit( int argc, const char** argv )
+{
+  // overloaded from AliHLTComponent: initialization
+  int 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;
+
+  // Create a new library manager and allocate the appropriate number of
+  // HOMER writers for the HLTOUT component.
+  if (!fpLibManager) fpLibManager=new AliHLTHOMERLibManager;
+  if (fpLibManager) {
+    int writerNo=0;
+    for (writerNo=0; writerNo<fNofDDLs; writerNo++) {
+      AliHLTMonitoringWriter* pWriter=fpLibManager->OpenWriter();
+      if (pWriter) {
+       HLTDebug("HOMER writer %p added", pWriter);
+       fWriters.push_back(pWriter);
+      } else {
+       HLTError("can not open HOMER writer");
+       iResult=-ENODEV;
+       break;
+      }
+    }
+  } else {
+    iResult=-ENOMEM;
+  }
+
+  return iResult;
+}
+
+int AliHLTOUTComponent::ScanConfigurationArgument(int argc, const char** argv)
+{
+  // overloaded from AliHLTComponent: argument scan
+  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;
+  }
+
+  // -distribute-blocks
+  key="-distribute-blocks";
+  if (argument.CompareTo(key)==0) {
+    fRoundRobinCounter=-1;
+
+    return 1;
+  }
+
+  // unknown argument
+  return -EINVAL;
+}
+
+int AliHLTOUTComponent::DoDeinit()
+{
+  // overloaded from AliHLTComponent: cleanup
+  int iResult=0;
+
+  if (fpLibManager) {
+    AliHLTMonitoringWriterPVector::iterator element=fWriters.begin();
+    while (element!= fWriters.end()) {
+      assert(*element);
+      // wanted to have a dynamic_cast<AliHLTHOMERWriter*> here, but this results into
+      // undefined symbol when loading the library
+      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;
+    fpDigitTree=NULL;
+  }
+
+  if (fpDigitFile) {
+    fpDigitFile->Close();
+    delete fpDigitFile;
+    fpDigitFile=NULL;
+  }
+
+  if (fppDigitArrays) {
+    for (int i=0; i<fNofDDLs; i++) {
+      if (fppDigitArrays[i]) delete fppDigitArrays[i];
+    }
+    delete[] fppDigitArrays;
+    fppDigitArrays=NULL;
+  }
+  
+  return iResult;
+}
+
+int AliHLTOUTComponent::DumpEvent( const AliHLTComponentEventData& evtData,
+                        const AliHLTComponentBlockData* blocks, 
+                        AliHLTComponentTriggerData& /*trigData*/ )
+{
+  // overloaded from AliHLTDataSink: event processing
+  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) {
+    homer_uint64 homerHeader[kCount_64b_Words];
+    HOMERBlockDescriptor homerDescriptor(homerHeader);
+    for (int n=0; n<(int)evtData.fBlockCnt; n++ ) {
+      if (blocks[n].fDataType==kAliHLTDataTypeEvent ||
+         blocks[n].fDataType==kAliHLTDataTypeSOR ||
+         blocks[n].fDataType==kAliHLTDataTypeEOR ||
+         blocks[n].fDataType==kAliHLTDataTypeComConf ||
+         blocks[n].fDataType==kAliHLTDataTypeUpdtDCS)
+       {
+         // the special events have to be ignored.
+         continue;
+       }
+      if (!bIsDataEvent &&
+         (blocks[n].fDataType!=kAliHLTDataTypeComponentTable))
+       {
+         // In simulation, there are no SOR and EOR events created. Thats
+         // why all data blocks of those events are currently ignored.
+         // Strictly speaking, components should not create output blocks
+         // on the SOR/EOR event
+         //
+         // Exeptions: some blocks are added, the buffer must be prepared and
+         // kept since the pointers will be invalid
+         // - kAliHLTDataTypeComponentTable component table entries
+         continue;
+       }
+      memset( homerHeader, 0, sizeof(homer_uint64)*kCount_64b_Words );
+      homerDescriptor.Initialize();
+      // 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::ByteSwap64(id));
+      homerDescriptor.SetSubType1(AliHLTOUT::ByteSwap64(origin));
+      homerDescriptor.SetSubType2(blocks[n].fSpecification);
+      homerDescriptor.SetBlockSize(blocks[n].fSize);
+      if (bIsDataEvent) {
+       writerNo=ShuffleWriters(fWriters, blocks[n].fSize);
+      }
+      assert(writerNo>=0 && writerNo<(int)fWriters.size());
+      // I'm puzzled by the different headers, buffers etc. used in the
+      // HOMER writer/data. In additional, there is no type check as there
+      // are void pointers used and names mixed.
+      // It seems that HOMERBlockDescriptor is just a tool to set the
+      // 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 && fNofDDLs>=2) {
+    // data blocks from a special event are kept to be added to the
+    // 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");
+    }
+    const AliHLTUInt8_t* pBuffer=NULL;
+    int bufferSize=0;
+    // 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 (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());
+  }
+
+  if (fRoundRobinCounter>=0) {
+    if (++fRoundRobinCounter>=fNofDDLs) fRoundRobinCounter=0;
+  }
+
+  return iResult;
+}
+
+int AliHLTOUTComponent::Write(int eventNo)
+{
+  // write digits and raw files for the current event
+  int iResult=0;
+
+  if (fWriters.size()==0) return 0;
+
+  if (fReservedWriter>=0) {
+    if (fOptions&kWriteDigits) WriteDigitArray(fReservedWriter, &fBuffer[0], fReservedData);
+    if (fOptions&kWriteRawFiles) WriteRawFile(eventNo, fReservedWriter, &fBuffer[0], fReservedData);
+    fReservedData=0;
+  }
+
+  // search for the writer with the biggest data volume in order to allocate the
+  // output buffer of sufficient size
+  vector<int> sorted;
+  for (size_t i=0; i<fWriters.size(); i++) {
+    if ((int)i==fReservedWriter) continue;    
+    assert(fWriters[i]);
+    if (fWriters[i]) {
+      if (sorted.size()==0 || fWriters[i]->GetTotalMemorySize()<=fWriters[sorted[0]]->GetTotalMemorySize()) {
+       sorted.push_back(i);
+      } else {
+       sorted.insert(sorted.begin(), i);
+      }
+    }
+  }
+  fReservedWriter=-1;
+
+  vector<int>::iterator ddlno=sorted.begin();
+  while (ddlno!=sorted.end()) {
+    const AliHLTUInt8_t* pBuffer=NULL;
+    int bufferSize=0;
+    
+    if ((bufferSize=FillOutputBuffer(eventNo, fWriters[*ddlno], pBuffer))>0) {
+      if (fOptions&kWriteDigits) WriteDigitArray(*ddlno, pBuffer, bufferSize);
+      if (fOptions&kWriteRawFiles &&
+         (fRoundRobinCounter<0 || fRoundRobinCounter==*ddlno))
+       WriteRawFile(eventNo, *ddlno, pBuffer, bufferSize);
+    }
+    fWriters[*ddlno]->Clear();
+    ddlno++;
+  }
+  if (fOptions&kWriteDigits) WriteDigits(eventNo);
+  return iResult;
+}
+
+int AliHLTOUTComponent::ShuffleWriters(AliHLTMonitoringWriterPVector &list, AliHLTUInt32_t /*size*/)
+{
+  /// get a writer for the next block
+  /// in round robin mode (like the online HLTOUT) all blocks of one event go to the same link
+  /// this is now also the default behavior of the HLTOUTComponent and indicated by
+  /// fRoundRobinCounter>=0
+  /// Writers are selected randomly otherwise.
+  if (fRoundRobinCounter>=0) {
+    if (fRoundRobinCounter==fReservedWriter) {
+      if (++fRoundRobinCounter>=fNofDDLs) fRoundRobinCounter=0;
+      if (fRoundRobinCounter==fReservedWriter) {
+       HLTWarning("there are not enough links to use a reserved writer, discarding data in reserved writer %d (total %d)",
+                  fReservedWriter, fNofDDLs);
+       fReservedWriter=-1;
+      }
+    }
+    return fRoundRobinCounter;
+  }
+
+  int iResult=-ENOENT;
+  assert(list.size()>0);
+  if (list.size()==0) return iResult;
+  vector<int> writers;
+  size_t i=0;
+  for (i=0; i<list.size(); i++) {
+    if ((int)i==fReservedWriter) continue;
+    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, AliHLTMonitoringWriter* pWriter, const AliHLTUInt8_t* &pBuffer)
+{
+  // prepare the output buffer for writing, consists of
+  // - CDH
+  // - HLTOUT header
+  // - HOMER data
+  // buffer is allocated internally and data is valid until next call
+  int iResult=0;
+  unsigned int bufferSize=0;
+
+  // space for common data header
+  bufferSize+=sizeof(AliRawDataHeaderV3);
+
+  // space for HLT event header
+  bufferSize+=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
+
+  // space for payload from the writer
+  if (pWriter) bufferSize+=pWriter->GetTotalMemorySize();
+
+  // payload data must be aligned to 32bit
+  bufferSize=(bufferSize+3)/4;
+  bufferSize*=4;
+
+  if (bufferSize>fBuffer.size())
+    fBuffer.resize(bufferSize);
+
+  // reset the last 32bit word, rest will be overwritten
+  memset(&fBuffer[bufferSize-4], 0, 4);
+
+  if (bufferSize<=fBuffer.size()) {
+    AliRawDataHeaderV3* pCDH=reinterpret_cast<AliRawDataHeaderV3*>(&fBuffer[0]);
+    AliHLTOUT::AliHLTOUTEventHeader* pHLTH=reinterpret_cast<AliHLTOUT::AliHLTOUTEventHeader*>(&fBuffer[sizeof(AliRawDataHeaderV3)]);
+    *pCDH = AliRawDataHeaderV3();  // Fill with default values.
+    memset(pHLTH, 0, sizeof(AliHLTOUT::AliHLTOUTEventHeader));
+
+    if (pWriter) {
+      // copy payload
+      pWriter->Copy(&fBuffer[sizeof(AliRawDataHeaderV3)+sizeof(AliHLTOUT::AliHLTOUTEventHeader)], 0, 0, 0, 0);
+      pHLTH->fLength=pWriter->GetTotalMemorySize();
+      // set status bit to indicate HLT payload
+      pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::kCDHStatusFlagsOffset+AliHLTOUT::kCDHFlagsHLTPayload);
+    }
+    pHLTH->fLength+=sizeof(AliHLTOUT::AliHLTOUTEventHeader);
+    // pHLTH->fEventIDLow is already set to zero in memset above.
+    pHLTH->fEventIDLow = eventNo;
+    // version does not really matter since we do not add decision data
+    pHLTH->fVersion=AliHLTOUT::kVersion1;
+
+    pCDH->fSize=bufferSize;
+    pCDH->fStatusMiniEventID|=0x1<<(AliHLTOUT::kCDHStatusFlagsOffset + AliHLTOUT::kCDHFlagsHLTPayload);
+    
+    pBuffer=&fBuffer[0];
+    iResult=(int)bufferSize;
+  } else {
+    pBuffer=NULL;
+    iResult=-ENOMEM;
+  }
+
+  return iResult;
+}
+
+int AliHLTOUTComponent::WriteDigitArray(int hltddl, const AliHLTUInt8_t* pBuffer, unsigned int bufferSize)
+{
+  // wite a buffer to the associated digit array
+  int iResult=0;
+  assert(hltddl<fNofDDLs);
+  if (hltddl>=fNofDDLs) return -ERANGE;
+
+  if (!fppDigitArrays) {
+    fppDigitArrays=new TArrayC*[fNofDDLs];
+    if (fppDigitArrays) {
+      for (int i=0; i<fNofDDLs; i++) {
+       fppDigitArrays[i]=new TArrayC(0);
+      }
+    }
+  }
+  if (fppDigitArrays && fppDigitArrays[hltddl]) {
+    fppDigitArrays[hltddl]->Set(bufferSize, reinterpret_cast<const Char_t*>(pBuffer));
+  } else {
+    iResult=-ENOMEM;    
+  }
+  return iResult;
+}
+
+int AliHLTOUTComponent::WriteDigits(int /*eventNo*/)
+{
+  // fill tree with digit arrays and write to file
+  // all links must be written, even in round robin mode, where all links but one
+  // do not contain any data blocks.
+  // This is a limitation of storing the links in a tree
+  int iResult=0;
+  if (!fpDigitFile) {
+    fpDigitFile=new TFile(fDigitFileName, "RECREATE");
+  }
+  if (fpDigitFile && !fpDigitFile->IsZombie()) {
+    if (!fpDigitTree) {
+      fpDigitTree=new TTree("rawhltout","HLTOUT raw data");
+      if (fpDigitTree && fppDigitArrays) {
+       for (int i=0; i<fNofDDLs; i++) {
+         const char* branchName=AliDAQ::DdlFileName("HLT", i);
+         if (fppDigitArrays[i]) fpDigitTree->Branch(branchName, "TArrayC", &fppDigitArrays[i], 32000/*just as the default*/, 0);
+       }
+      }
+    }
+    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);
+      }
+    }
+  } else {
+    const char* errorMsg="";
+    if (GetEventCount()==5) {
+      errorMsg=" (suppressing further error messages)";
+    }
+    if (GetEventCount()<5) {
+      HLTError("can not open HLT digit file %s%s", fDigitFileName.Data(), errorMsg);
+    }
+    iResult=-EBADF;
+  }
+  return iResult;
+}
+
+int AliHLTOUTComponent::WriteRawFile(int eventNo, int hltddl, const AliHLTUInt8_t* pBuffer, unsigned int bufferSize)
+{
+  // write buffer to raw file in the current directory
+  // creates the event raw directories in the current directory
+  int iResult=0;
+  const char* fileName=AliDAQ::DdlFileName("HLT", hltddl);
+  assert(fileName!=NULL);
+  TString filePath;
+  filePath.Form("raw%d/", eventNo);
+  if (gSystem->AccessPathName(filePath)!=0) {
+    // note: AccessPathName return 0 if the path is existing
+    TString command="mkdir "; command+=filePath;
+    gSystem->Exec(command);
+  }
+  filePath+=fileName;
+  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;
+}
+
+void AliHLTOUTComponent::SetGlobalOption(unsigned int options)
+{
+  // set the global options
+  fgOptions|=options;
+}
+
+void AliHLTOUTComponent::ClearGlobalOption(unsigned int options)
+{
+  // reset the global options
+  fgOptions&=~options;
+}
+
+bool AliHLTOUTComponent::TestGlobalOption(unsigned int option)
+{
+  // check option
+  return (fgOptions&option)!=0;
+}
diff --git a/HLT/BASE/AliHLTOUTComponent.h b/HLT/BASE/AliHLTOUTComponent.h
new file mode 100644 (file)
index 0000000..bd30ba1
--- /dev/null
@@ -0,0 +1,253 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+#ifndef ALIHLTOUTCOMPONENT_H
+#define ALIHLTOUTCOMPONENT_H
+//* This file is property of and copyright by the                          * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//* See cxx source for full Copyright notice                               *
+
+/// @file   AliHLTOUTComponent.h
+/// @author Matthias Richter
+/// @date   
+/// @brief  The HLTOUT data sink component similar to HLTOUT nodes.
+/// @note   Used in the AliRoot environment only.
+
+#include "AliHLTDataSink.h"
+
+class AliHLTHOMERLibManager;
+class AliHLTMonitoringWriter;
+class TFile;
+class TTree;
+typedef vector<AliHLTMonitoringWriter*> AliHLTMonitoringWriterPVector;
+
+/**
+ * @class AliHLTOUTComponent
+ * The HLTOUT data sink component which models the behavior of the HLTOUT
+ * nodes of the HLT cluster.
+ * <h2>General properties:</h2>
+ * The HLTOUT component is attached at the end of a chain. It stores all input
+ * block in the HOMER format, distributed over a number of DDL link. The data
+ * is stored in a digit file or in raw ddl files.
+ *
+ * Component ID: \b HLTOUT <br>
+ * Library: \b libHLTrec.so     <br>
+ * Input Data Types: @ref kAliHLTAnyDataType <br>
+ * Output Data Types: none (offline data sink) <br>
+ *
+ * <h2>Mandatory arguments:</h2>
+ * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formatting -->
+ *
+ * <h2>Optional arguments:</h2>
+ * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formatting -->
+ * \li -links      <i> n   </i> <br>
+ *      number of output ddl links
+ * \li -digitfile  <i> name   </i> <br>
+ *      name of the digit file to write (default HLT.Digits.root)
+ * \li -rawout[=on,off]  <br>
+ *      switch raw output on/off (default on)
+ * \li -digitout[=on,off]  <br>
+ *      switch digit output on/off (default on)
+ *
+ * <h2>Configuration:</h2>
+ * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formatting -->
+ * none
+ *
+ * <h2>Default CDB entries:</h2>
+ * none
+ *
+ * <h2>Performance:</h2>
+ * The component does not any event data processing.
+ *
+ * <h2>Memory consumption:</h2>
+ * The component does not any event data processing.
+ *
+ * <h2>Output size:</h2>
+ * The component is an offline sink component and has no output data.
+ *
+ * The component can be used to write data in the same format as
+ * the HLTOUT on the real HLT. In case of AliRoot simulation, the
+ * component is automatically added to the chain if the specified
+ * chains have output data. By that means, the HLT output is added
+ * to the simulation.
+ *
+ * @ingroup alihlt_aliroot_simulation
+ */
+class AliHLTOUTComponent : public AliHLTDataSink  {
+ public:
+  /// type of the HLTOUT component
+  enum EType {
+    kGlobal = 0, // generate according to global flags
+    kDigits = 1, // generate only digits: ID HLTOUTdigits
+    kRaw    = 2  // generate only raw:    ID HLTOUTraw
+  };
+  /// constructor for different component types
+  AliHLTOUTComponent(EType type=kGlobal);
+  /** destructor */
+  virtual ~AliHLTOUTComponent();
+
+  const char* GetComponentID();
+  void GetInputDataTypes( AliHLTComponentDataTypeList& list);
+  AliHLTComponent* Spawn();
+
+  /**
+   * Enable global options valid for all instances of the component
+   * @param options   bit field
+   */
+  static void SetGlobalOption(unsigned int options);
+
+  /**
+   * Disable global options valid for all instances of the component
+   * @param options   bit field
+   */
+  static void ClearGlobalOption(unsigned int options);
+
+  /**
+   * Test one of the global options
+   */
+  static bool TestGlobalOption(unsigned int option);
+
+  enum {
+    /** write the raw files of the HLT links */
+    kWriteRawFiles = 0x1,
+    /** write the digit file */
+    kWriteDigits = 0x2
+  };
+
+ protected:
+  /**
+   * Init method.
+   */
+  int DoInit( int argc, const char** argv );
+
+  /// inherited from AliHLTComponent,  component specific argument scan
+  int ScanConfigurationArgument(int argc, const char** argv);
+
+  /**
+   * Deinit method.
+   */
+  int DoDeinit();
+
+  /**
+   * Data processing method for the component.
+   * The function can be overloaded by other file writer components.
+   * @param evtData       event data structure
+   * @param blocks        input data block descriptors
+   * @param trigData     trigger data structure
+   */
+  int DumpEvent( const AliHLTComponentEventData& evtData,
+                const AliHLTComponentBlockData* blocks, 
+                AliHLTComponentTriggerData& trigData );
+
+  using AliHLTDataSink::DumpEvent;
+
+  /**
+   * Write the ecoded HLTOUT data to raw and digits files.
+   * Originally data was written in the FillESD function of the
+   * AliHLTOfflineInterface. Mainly for the sake of availability of the
+   * AliLoader. This concept has not turned out to be succesful and the
+   * development went a slightly different direction with the concept of
+   * HLTOUT handlers.
+   * 2010-04-14 change the original FillESD() to Write(), keep the body
+   * of the function
+   *
+   * @param eventNo       event No. \em Note: this is an internal enumeration of the
+   *                      processed events.
+   * @param runLoader     the AliRoot runloader
+   * @return neg. error code if failed 
+   */
+  int Write(int eventNo);
+
+ private:
+  /** copy constructor prohibited */
+  AliHLTOUTComponent(const AliHLTOUTComponent&);
+  /** assignment operator prohibited */
+  AliHLTOUTComponent& operator=(const AliHLTOUTComponent&);
+
+  int ShuffleWriters(AliHLTMonitoringWriterPVector &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, AliHLTMonitoringWriter* pWriter, const AliHLTUInt8_t* &pBuffer);
+
+  /**
+   * Write data for a DDL link.
+   * @param hltddl     Number of DDL link within the range of HLT
+   * @param pBuffer    buffer to write
+   * @param bufferSize size of the buffer
+   */
+  int WriteDigitArray(int hltddl, const AliHLTUInt8_t* pBuffer, unsigned int bufferSize);
+
+  /**
+   * Write the digits for one DDL
+   * @param eventNo    number of the event
+   * @return neg. error if failed
+   */
+  int WriteDigits(int eventNo);
+
+  /**
+   * Write the raw file for one DDL
+   * @param eventNo    number of the event
+   * @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, int hltddl, const AliHLTUInt8_t* pBuffer, unsigned int size);
+
+  /** list of HOMER writers */
+  AliHLTMonitoringWriterPVector fWriters; //!transient
+
+  /** number of DDLs used*/
+  int fNofDDLs; //!transient
+
+  /** equipment ID of first HLT DDL */
+  int fIdFirstDDL; //!transient
+
+  /** output buffer, allocated once in order to avoid frequent alloc/dealloc */
+  vector<AliHLTUInt8_t> fBuffer; //!transient
+
+  /** instance of the HOMER library manager */
+  AliHLTHOMERLibManager* fpLibManager; // !transient
+
+  /** global options for all instances */
+  static int fgOptions; //! transient
+
+  /// component options set from component type or global options at DoInit
+  int fOptions; //! transient
+
+  /** digit file name */
+  TString fDigitFileName; //! transient
+
+  /** the root file for the HLT 'digit' output */
+  TFile* fpDigitFile; //!transient
+
+  /** the tree for the HLT 'digit' output */
+  TTree* fpDigitTree; //!transient
+
+  /** array of TArrayC output buffers and branches */
+  TArrayC** fppDigitArrays; //!transient
+
+  /** Id of HOMER writer kept from previous event */
+  int fReservedWriter; //!transient
+
+  /** Data size kept in the internal buffer */
+  int fReservedData; //!transient
+
+  /// type of the component
+  EType fType; //! type of the component
+
+  /// counter for round robin usage of HLTOUT links
+  int fRoundRobinCounter; //! counter for round robin usage of HLTOUT links
+
+  ClassDef(AliHLTOUTComponent, 0)
+};
+#endif
diff --git a/STEER/STEER/AliHLTSimulation.cxx b/STEER/STEER/AliHLTSimulation.cxx
new file mode 100644 (file)
index 0000000..c48ea89
--- /dev/null
@@ -0,0 +1,400 @@
+// $Id$
+
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project        * 
+//* ALICE Experiment at CERN, All rights reserved.                         *
+//*                                                                        *
+//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+//*                  for The ALICE HLT Project.                            *
+//*                                                                        *
+//* Permission to use, copy, modify and distribute this software and its   *
+//* documentation strictly for non-commercial purposes is hereby granted   *
+//* without fee, provided that the above copyright notice appears in all   *
+//* copies and that both the copyright notice and this permission notice   *
+//* appear in the supporting documentation. The authors make no claims     *
+//* about the suitability of this software for any purpose. It is          *
+//* provided "as is" without express or implied warranty.                  *
+//**************************************************************************
+
+/** @file   AliHLTSimulation.cxx
+    @author Matthias Richter
+    @date   
+    @brief  Binding class for HLT simulation in AliRoot. */
+
+#include <cassert>
+#include <cerrno>
+#include "TObjArray.h"
+#include "TObjString.h"
+#include "AliHLTSimulation.h"
+#include "AliSimulation.h"
+#include "AliLog.h"
+#include "AliRun.h"
+#include "AliRunLoader.h"
+#include "AliHeader.h"
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
+#include "AliCDBPath.h"
+#include "AliCDBId.h"
+#include "AliCDBMetaData.h"
+#include "AliCDBStorage.h"
+#include "AliGRPObject.h"
+#include "AliGRPManager.h"
+#include "AliHLTSystem.h"
+#include "AliHLTConfigurationHandler.h"
+#include "AliHLTPluginBase.h"
+#include "AliRawReaderFile.h"
+#include "AliRawReaderDate.h"
+#include "AliRawReaderRoot.h"
+#include "AliESDEvent.h"
+#include "AliHLTOUTComponent.h"
+#include "AliTracker.h"
+#include "TGeoGlobalMagField.h"
+#include "TSystem.h"
+#include "TMath.h"
+#include "TGeoGlobalMagField.h"
+
+#if ALIHLTSIMULATION_LIBRARY_VERSION != LIBHLTSIM_VERSION
+#error library version in header file and lib*.pkg do not match
+#endif
+
+/** ROOT macro for the implementation of ROOT specific class methods */
+ClassImp(AliHLTSimulation);
+
+AliHLTSimulation::AliHLTSimulation()
+  : fOptions()
+  , fpPluginBase(new AliHLTPluginBase)
+  , fpRawReader(NULL)
+  , fNEvents(-1)
+{
+  // see header file for class documentation
+  // or
+  // refer to README to build package
+  // or
+  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+}
+
+AliHLTSimulation::~AliHLTSimulation()
+{
+  // see header file for function documentation
+  if (fpPluginBase) delete fpPluginBase;
+  fpPluginBase=NULL;
+
+  if (fpRawReader) {
+    delete fpRawReader;
+  }
+  fpRawReader=NULL;
+}
+
+AliHLTSimulation* AliHLTSimulation::CreateInstance()
+{
+  // see header file for function documentation
+  return new AliHLTSimulation;
+}
+
+int AliHLTSimulation::DeleteInstance(AliHLTSimulation* pSim)
+{
+  // see header file for function documentation
+  assert(pSim!=NULL);
+  delete pSim;
+  return 0;
+}
+
+int AliHLTSimulation::Init(AliRunLoader* pRunLoader, const char* options)
+{
+  // init the simulation
+  fOptions=options;
+  TString sysOp;
+
+  if(!fpPluginBase) {
+    AliError("internal initialization failed");
+    return -EINVAL;
+  }
+
+  AliHLTSystem* pSystem=fpPluginBase->GetInstance();
+  if (!pSystem) {
+    AliError("can not get AliHLTSystem instance");
+    return -ENOMEM;
+  }
+  if (pSystem->CheckStatus(AliHLTSystem::kError)) {
+    AliError("HLT system in error state");
+    return -EFAULT;
+  }
+
+  // scan options for specific entries
+  TObjArray* pTokens=fOptions.Tokenize(" ");
+  if (pTokens) {
+    int iEntries=pTokens->GetEntries();
+    for (int i=0; i<iEntries; i++) {
+      TString token=(((TObjString*)pTokens->At(i))->GetString());
+      if (token.Contains("rawfile=")) {
+       TString param=token.ReplaceAll("rawfile=", "");
+       if (param.EndsWith("/")) {
+         AliInfo(Form("creating AliRawReaderFile (%s)", param.Data()));
+         fpRawReader = new AliRawReaderFile(param);
+       } else if (param.EndsWith(".root")) {
+         AliInfo(Form("creating AliRawReaderRoot (%s)", param.Data()));
+         fpRawReader = new AliRawReaderRoot(param);
+       } else if (!param.IsNull()) {
+         AliInfo(Form("creating AliRawReaderDate (%s)", param.Data()));
+         fpRawReader = new AliRawReaderDate(param);
+       }
+       if (fpRawReader) {
+           fpRawReader->RewindEvents();
+           int count=0;
+           for ( ; fpRawReader->NextEvent(); count++) {/* empty body */};
+           if (count!=pRunLoader->GetNumberOfEvents()) {
+             AliError(Form("mismatch in event count: runloader %d, rawreader %d; ignoring rawreader", 
+                           pRunLoader->GetNumberOfEvents(), count));
+             count=0;
+           }
+           if (count>0) {
+             fpRawReader->RewindEvents();
+             fpRawReader->NextEvent();
+           } else {
+             delete fpRawReader;
+             fpRawReader=NULL;
+           }
+       }
+      } else if (token.Contains("writerawfiles=")) {
+       if (!token.ReplaceAll("writerawfiles=", "").Contains("HLT")) {
+         if (TestBit(kOneChain) && AliHLTOUTComponent::TestGlobalOption(AliHLTOUTComponent::kWriteRawFiles)) {
+           AliWarning("empty argument 'writerawfiles=' disables HLTOUTComponent mode 'raw' which was set by argument 'hltout-mode'");
+         }
+         AliHLTOUTComponent::ClearGlobalOption(AliHLTOUTComponent::kWriteRawFiles);
+       }
+      } else if (token.BeginsWith("hltout-mode=")) {
+       // this is a legacy mode to emulate the behavior before Dec 2010 where only
+       // one chain was executed on either digits or simulated raw data and the output
+       // was controlled via global flags
+       // add to the arguments for AliHLTSystem as also there the information is needed
+       if (sysOp.Length()>0) sysOp+=" ";
+       sysOp+=token;
+       TString param=token.ReplaceAll("hltout-mode=", "");
+       SetBit(kOneChain);
+       if (param.CompareTo("raw")==0) {
+         // please note that this option
+         AliHLTOUTComponent::SetGlobalOption(AliHLTOUTComponent::kWriteRawFiles);
+         AliHLTOUTComponent::ClearGlobalOption(AliHLTOUTComponent::kWriteDigits);
+       } else if (param.CompareTo("digits")==0) {
+         // please note that this option
+         AliHLTOUTComponent::ClearGlobalOption(AliHLTOUTComponent::kWriteRawFiles);
+         AliHLTOUTComponent::SetGlobalOption(AliHLTOUTComponent::kWriteDigits);
+       } else if (param.CompareTo("legacy")==0) {
+         AliHLTOUTComponent::SetGlobalOption(AliHLTOUTComponent::kWriteRawFiles);
+         AliHLTOUTComponent::SetGlobalOption(AliHLTOUTComponent::kWriteDigits);
+       } else {
+         AliError(Form("invalid parameter for argument 'hltout-mode=' %s, allowed: raw, digits, legacy ... ignoring argument  and using the standard simulation", param.Data()));
+         ResetBit(kOneChain);
+       }
+      } else if (token.Contains("events=")) {
+       fNEvents=token.ReplaceAll("events=", "").Atoi();
+      } else {
+       if (sysOp.Length()>0) sysOp+=" ";
+       sysOp+=token;
+      }
+    }
+    delete pTokens;
+  }
+  // only store the options for AliHLTSystem
+  fOptions=sysOp;
+
+  // if no specific hltout-mode has been chosen set the split mode for
+  // running separate chains for digits and raw data
+  if (!fOptions.Contains("hltout-mode=")) fOptions+=" hltout-mode=split";
+
+  AliCDBManager* man = AliCDBManager::Instance();
+  if (man && man->IsDefaultStorageSet())
+  {
+    // init solenoid field
+    // 2009-11-07 magnetic field handling fo HLT components has been switched to the
+    // global AliMagF instance, the HLT/ConfigHLT/SolenoidBz entry is obsolete
+    // The global instance is either established by the AliRoot environment or the
+    // component external interface.
+    if (TGeoGlobalMagField::Instance()->GetField()) {
+      AliDebug(0, Form("magnetic field: %f", AliTracker::GetBz()));
+    } else {
+      // workaround for bug #51285
+      AliGRPManager grpman;
+      if (grpman.ReadGRPEntry() &&
+         grpman.SetMagField()) {
+       // nothing to do any more
+      }
+      AliError(Form("can not get the AliMagF instance, falling back to GRP entry (%f)", AliTracker::GetBz()));
+    }
+  } else if (man) {
+    AliError("OCDB default storage not yet set, can not prepare OCDB entries");    
+  } else {
+    AliError("unable to get instance of AliCDBMetaData, can not prepare OCDB entries");    
+  }
+
+  // configure the main HLTSystem instance for digit simulation (pRawReader NULL)
+  return ConfigureHLTSystem(pSystem, fOptions.Data(), pRunLoader, TestBit(kOneChain)?fpRawReader:NULL);
+}
+
+int AliHLTSimulation::ConfigureHLTSystem(AliHLTSystem* pSystem, const char* options, AliRunLoader* pRunLoader, AliRawReader* pRawReader) const
+{
+  // scan options and configure AliHLTSystem
+  if (pSystem->ScanOptions(options)<0) {
+    AliError("error setting options for HLT system");
+    return -EINVAL;    
+  }
+
+  if (!pSystem->CheckStatus(AliHLTSystem::kReady)) {
+    if ((pSystem->Configure(pRawReader, pRunLoader))<0) {
+      AliError("error during HLT system configuration");
+      return -EFAULT;
+    }
+  }
+
+  return 0;
+}
+
+int AliHLTSimulation::Run(AliRunLoader* pRunLoader)
+{
+  // HLT reconstruction for simulated data  
+  if(!fpPluginBase) {
+    AliError("internal initialization failed");
+    return -EINVAL;
+  }
+
+  if(!pRunLoader) {
+    AliError("Missing RunLoader! 0x0");
+    return -EINVAL;
+  }
+
+  int iResult=0;
+
+  AliHLTSystem* pSystem=fpPluginBase->GetInstance();
+  if (!pSystem) {
+    AliError("can not get AliHLTSystem instance");
+    return -ENOMEM;
+  }
+
+  if (pSystem->CheckStatus(AliHLTSystem::kError)) {
+    AliError("HLT system in error state");
+    return -EFAULT;
+  }
+
+  // run the main HLTSystem instance for digit simulation (pRawReader NULL)
+  // in legacy mode only one chain is run and the output is controlled via
+  // global flags
+  if (!TestBit(kOneChain)) AliInfo("running HLT simulation for digits");
+  iResult=RunHLTSystem(pSystem, pRunLoader, TestBit(kOneChain)?fpRawReader:NULL);
+
+  // now run once again with the raw data as input, a completely new HLT system
+  // with new configurations is used
+  if (fpRawReader && !TestBit(kOneChain)) {
+    AliInfo("running HLT simulation for raw data");
+    int iLocalResult=0;
+    AliHLTConfigurationHandler* confHandler=new AliHLTConfigurationHandler;
+    // note that the configuration handler is owned by the
+    // AliHLTSystem instance from now on
+    AliHLTSystem rawSimulation(kHLTLogDefault, "", NULL, confHandler);
+    if ((iLocalResult=ConfigureHLTSystem(&rawSimulation, fOptions.Data(), pRunLoader, fpRawReader))>=0) {
+      iLocalResult=RunHLTSystem(&rawSimulation, pRunLoader, fpRawReader);
+    }
+    if (iResult>=0) iResult=iLocalResult;
+  }
+
+  return iResult;
+}
+
+int AliHLTSimulation::RunHLTSystem(AliHLTSystem* pSystem, AliRunLoader* pRunLoader, AliRawReader* pRawReader) const
+{
+  // run reconstruction cycle for AliHLTSystem
+  int nEvents = (fNEvents<0 || fNEvents>pRunLoader->GetNumberOfEvents())?pRunLoader->GetNumberOfEvents():fNEvents;
+  int iResult=0;
+
+  // Note: the rawreader is already placed at the first event
+  if ((iResult=pSystem->Reconstruct(1, pRunLoader, pRawReader))>=0) {
+    pSystem->FillESD(0, pRunLoader, NULL);
+    for (int i=1; i<nEvents; i++) {
+      if (pRawReader && !pRawReader->NextEvent()) {
+       AliError("mismatch in event count, rawreader corrupted");
+       break;
+      }
+      pSystem->Reconstruct(1, pRunLoader, pRawReader);
+      pSystem->FillESD(i, pRunLoader, NULL);
+    }
+    // send specific 'event' to execute the stop sequence
+    pSystem->Reconstruct(0, NULL, NULL);
+  }
+  return iResult;
+}
+
+AliHLTSimulation* AliHLTSimulationCreateInstance()
+{
+  // see header file for function documentation
+  return AliHLTSimulation::CreateInstance();
+}
+
+int AliHLTSimulationDeleteInstance(AliHLTSimulation* pSim)
+{
+  // see header file for function documentation
+  return AliHLTSimulation::DeleteInstance(pSim);
+}
+
+int AliHLTSimulationInit(AliHLTSimulation* pSim, AliRunLoader* pRunLoader, const char* options)
+{
+  assert(pSim!=NULL);
+  if (pSim) {
+    return pSim->Init(pRunLoader, options);
+  }
+  return -ENODEV;
+}
+
+int AliHLTSimulationRun(AliHLTSimulation* pSim, AliRunLoader* pRunLoader)
+{
+  assert(pSim!=NULL);
+  if (pSim) {
+    return pSim->Run(pRunLoader);
+  }
+  return -ENODEV;
+}
+
+int AliHLTSimulationGetLibraryVersion()
+{
+  // see header file for function documentation
+  return LIBHLTSIM_VERSION;
+}
+
+int AliHLTSimulationSetup(AliHLTSimulation* /*pHLTSim*/, AliSimulation* pSim, const char* specificObjects)
+{
+  // see header file for function documentation
+
+  // this is an attempt to solve issue #48360
+  // since there are many jobs running in parallel during the production,
+  // all the jobs want to put entries into the OCDB. The solution is to
+  // make them temporary, since they are only used to propagate information
+  // from the simulation to the reconstruction.
+
+  if (!pSim) return -EINVAL;
+  const char* entries[]={
+    NULL
+  };
+
+  TString specificStorage; 
+  specificStorage.Form("local://%s",gSystem->pwd());
+  for (const char** pEntry=entries; *pEntry!=NULL; pEntry++) {
+    const char* pObject=specificObjects?strstr(specificObjects, *pEntry):NULL;
+    if (pObject) {
+      // skip this entry if it is found in the list and either
+      // last one or separated by a blank
+      pObject+=strlen(*pEntry);
+      if (*pObject==0 || *pObject==' ') continue;
+    }
+    pSim->SetSpecificStorage(*pEntry, specificStorage.Data());
+  }
+
+  return 0;
+}
+
+#ifndef HAVE_COMPILEINFO
+extern "C" void CompileInfo(const char*& date, const char*& time)
+{
+  // the fall back compile info of the HLTsim library
+  // this is not up-to-date if other files have been changed and recompiled
+  date=__DATE__; time=__TIME__;
+  return;
+}
+#endif
diff --git a/STEER/STEER/AliHLTSimulation.h b/STEER/STEER/AliHLTSimulation.h
new file mode 100644 (file)
index 0000000..edbac7f
--- /dev/null
@@ -0,0 +1,192 @@
+//-*- Mode: C++ -*-
+// $Id$
+
+#ifndef ALIHLTSIMULATION_H
+#define ALIHLTSIMULATION_H
+/* This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ * See cxx source for full Copyright notice                               */
+
+/// @file   AliHLTSimulation.h
+/// @author Matthias Richter
+/// @date   
+/// @brief  Binding class for HLT simulation in AliRoot
+///
+
+/**
+ * @defgroup alihlt_aliroot_simulation HLT simulation in AliRoot
+ * This section describes the the simulation of the HLT in AliRoot.
+ *
+ * @section alihlt_aliroot_simulation_intro General Remarks
+ * HLT has a special role in the normal data flow  of simulation and
+ * reconstruction. Since the HLT reconstruction and analysis runs on-line
+ * on the HLT farm, the raw data produced by HLT as a detector contains
+ * already reconstructed events. Consequently, the HLT response has to be
+ * simulated as well as the data of all other detectors. Since the detector
+ * data is needed, the HLT simulation is run at the end of AliSimulation.
+ * As a matter of fact, HLT always reconstructs data, <em><b>HLT simulation
+ * </b></em> means <em><b>HLT reconstruction embedded into AliRoot</b></em>.
+ *
+ * @section alihlt_aliroot_simulation_steering Steering
+ * The AliHLTSimulation class is the steering class called from AliSimulation.
+ * An instance of AliHLTSystem is used to run the chains defined by the
+ * available libraries or a AliHLTConfiguration configuration macro.
+ *
+ * The libraries to be loaded can be specified as an option to AliSimulation.
+ * <pre>
+ * AliSimulation sim;
+ * sim.SetRunHLT("libAliHLTSample.so");
+ * </pre>
+ * @see AliHLTSimulation for further details
+ *
+ * @section alihlt_aliroot_simulation_running Running
+ * The actual chains to be run depend on the HLT library modules which 
+ * are loaded to the system. There is a default collection of libraries 
+ * defined in AliHLTSystem::fgkHLTDefaultLibs. The default libraries are 
+ * loaded if nothing else is specified. The libraries implement \em agents 
+ * (AliHLTModuleAgent childs) describing the properties of a module.
+ *
+ * @section alihlt_aliroot_simulation_examples Examples
+ * - @ref tut_simulation 
+ *
+ * @ingroup alihlt_system
+ */
+
+#include "TObject.h"
+#include "TString.h"
+class AliRunLoader;
+class AliHLTPluginBase;
+class AliRawReader;
+class AliSimulation;
+class AliHLTSystem;
+
+/**
+ * @class AliHLTSimulation
+ * Plugin for HLT reconstruction embedded into <tt>AliSimulation</tt>.
+ *
+ * The libraries to be loaded can be specified as an option to AliSimulation.
+ * <pre>
+ * AliSimulation sim;
+ * sim.SetRunHLT("libAliHLTSample.so");
+ * </pre>
+ * will only load <tt>libAliHLTSample.so</tt>
+ *
+ * Other available options:
+ * \li loglevel=<i>level</i>                                            <br>
+ *     logging level for this processing, default level is 0x79 filtering
+ *     out everything below level 'warning'. 0x7c allows info messages as
+ *     well, 0x3f is the highest loglevel.
+ * \li alilog=off                                                       <br>
+ *     disable redirection of log messages to AliLog class
+ * \li config=<i>macro</i>                                              <br>
+ *     configuration macro: normal ROOT macro defining HLT component
+ *     configurations by means of AliHLTConfiguration.
+ * \li chains=<i>configuration</i>                                      <br>
+ *     comma separated list of configurations to be run during simulation
+ * \li events=<i>n</i>
+ *     number of events to simulate
+ *
+ *  @ingroup alihlt_aliroot_simulation
+ */
+class AliHLTSimulation : public TObject {
+ public:
+  /** create an instance of the class */
+  static AliHLTSimulation* CreateInstance();
+
+  /** delete an instance */
+  static int DeleteInstance(AliHLTSimulation* pSim);
+
+  /** init simulation */
+  int Init(AliRunLoader* pRunLoader, const char* options);
+
+  int ConfigureHLTSystem(AliHLTSystem* pSystem, const char* options, AliRunLoader* pRunLoader, AliRawReader* pRawReader) const;
+
+  /** run simulation with an instance of the run loader */
+  int Run(AliRunLoader* pRunLoader);
+
+  /// run reconstruction cycle for AliHLTSystem
+  int RunHLTSystem(AliHLTSystem* pSystem, AliRunLoader* pRunLoader, AliRawReader* pRawReader) const;
+
+  enum EOptions {
+    // indicate that only one chain should be run, behavior before Dec 2010
+    kOneChain = BIT(15)
+  };
+
+ private:
+  /** standard constructor */
+  AliHLTSimulation();
+  /** copy constructor prohibited */
+  AliHLTSimulation(const AliHLTSimulation&);
+  /** assignment operator prohibited */
+  AliHLTSimulation& operator=(const AliHLTSimulation&);
+  /** standard destructor */
+  ~AliHLTSimulation();
+
+  /* current options */
+  TString fOptions;                                                   //!transient
+
+  /** base class for AliRoot HLT plugins */
+  AliHLTPluginBase* fpPluginBase;                                     //!transient
+
+  /** RAW reader instance for chains which need RAW data as input */
+  AliRawReader* fpRawReader;                                          //!transient
+
+  /// number of events to run
+  int fNEvents; //! number of events
+
+  ClassDef(AliHLTSimulation, 0)
+};
+
+#define ALIHLTSIMULATION_LIBRARY             "libHLTsim.so"
+#define ALIHLTSIMULATION_LIBRARY_VERSION     1
+#define ALIHLTSIMULATION_CREATE_INSTANCE     "AliHLTSimulationCreateInstance"
+#define ALIHLTSIMULATION_DELETE_INSTANCE     "AliHLTSimulationDeleteInstance"
+#define ALIHLTSIMULATION_SETUP               "AliHLTSimulationSetup"
+#define ALIHLTSIMULATION_INIT                "AliHLTSimulationInit"
+#define ALIHLTSIMULATION_RUN                 "AliHLTSimulationRun"
+#define ALIHLTSIMULATION_GET_LIBRARY_VERSION "AliHLTSimulationGetLibraryVersion"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  typedef AliHLTSimulation* (*AliHLTSimulationCreateInstance_t)();
+  typedef int (*AliHLTSimulationDeleteInstance_t)(AliHLTSimulation* pSim);
+  typedef int (*AliHLTSimulationSetup_t)(AliHLTSimulation* pHLTSim, AliSimulation* pSim, const char* options);
+  typedef int (*AliHLTSimulationInit_t)(AliHLTSimulation* pSim, AliRunLoader* pRunLoader, const char* options);
+  typedef int (*AliHLTSimulationRun_t)(AliHLTSimulation* pSim, AliRunLoader* pRunLoader);
+  typedef int (*AliHLTSimulationGetLibraryVersion_t)();
+  typedef int (*AliHLTSimulationInitOCDB_t)(AliHLTSimulation* pSim);
+
+  /**
+   * Create an instance of the AliHLTSimulation class
+   */
+  AliHLTSimulation* AliHLTSimulationCreateInstance();
+  /**
+   * Delete an instance of the AliHLTSimulation class
+   */
+  int AliHLTSimulationDeleteInstance(AliHLTSimulation* pSim);
+  /**
+   * Setup the HLT simulation.
+   * Setup is done right after the creation. To be called before
+   * the actual AliSimulation starts when the OCDB is not yet locked.
+   */
+  int AliHLTSimulationSetup(AliHLTSimulation* pHLTSim, AliSimulation* pSim, const char* options);
+  /**
+   * Set options for an instance.
+   * Init is invoked right before running HLT simulation, i.e. after all
+   * the other AliSimulation was done
+   */
+  int AliHLTSimulationInit(AliHLTSimulation* pSim, AliRunLoader* pRunLoader, const char* options);
+  /**
+   * Run simulation for an instance and run loader
+   */
+  int AliHLTSimulationRun(AliHLTSimulation* pSim, AliRunLoader* pRunLoader);
+  /**
+   * Get version no of the library/class interface
+   */
+  int AliHLTSimulationGetLibraryVersion();
+#ifdef __cplusplus
+}
+#endif
+
+#endif