]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/rec/AliHLTEsdManagerImplementation.cxx
remove self-initializations from reinit ctors
[u/mrichter/AliRoot.git] / HLT / rec / AliHLTEsdManagerImplementation.cxx
index 1b256f7a43721255d28768d7fb595845e6156764..998cbc941f1dd5b0132076eab6a7b91bd85c1233 100644 (file)
@@ -1,11 +1,10 @@
 // $Id$
 
 //**************************************************************************
-//* This file is property of and copyright by the ALICE HLT Project        * 
+//* 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   *
 //* provided "as is" without express or implied warranty.                  *
 //**************************************************************************
 
-/** @file   AliHLTEsdManagerImplementation.cxx
-    @author Matthias Richter
-    @date   
-    @brief  Manager for merging and writing of HLT ESDs
-*/
+/// @file   AliHLTEsdManagerImplementation.cxx
+/// @author Matthias Richter
+/// @date   
+/// @brief  Manager for merging and writing of HLT ESDs
+///         This is an implementation of the abstract interface AliHLTEsdManager
 
 #include "AliHLTEsdManagerImplementation.h"
 #include "AliHLTComponent.h"
 #include "AliHLTMessage.h"
 #include "AliESDEvent.h"
 #include "AliESDtrack.h"
+#include "AliESDFMD.h"
+#include "AliESDVZERO.h"
+#include "AliESDTZERO.h"
+#include "AliESDCaloCells.h"
+#include "AliMultiplicity.h"
+#include "AliESDACORDE.h"
+#include "AliESDTrdTrigger.h"
+#include "AliTOFHeader.h"
 #include "TFile.h"
 #include "TTree.h"
 #include "TClass.h"
 #include "TObject.h"
-#include "TObjectTable.h"
-#include "TSystem.h"
-#include "TChain.h"
 #include "TList.h"
 
+const float kAliESDVZERODefaultTime = -1024.;
+const float kAliESDVZERODefaultTimeGlitch = 1e-6;
+const float kAliESDZDCDefaultEMEnergy = 0.;
+const float kAliESDZDCDefaultEMEnergyGlitch = 1e-6;
+
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTEsdManagerImplementation)
 
@@ -44,6 +53,7 @@ AliHLTEsdManagerImplementation::AliHLTEsdManagerImplementation()
   :
   fESDs()
   , fDirectory()
+  , fTreeName()
   , fWriteLocal(false)
 {
   // see header file for class documentation
@@ -51,11 +61,13 @@ AliHLTEsdManagerImplementation::AliHLTEsdManagerImplementation()
   // refer to README to build package
   // or
   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+
+  CheckClassConditions();
 }
 
 AliHLTEsdManagerImplementation::~AliHLTEsdManagerImplementation()
 {
-  // see header file for class documentation
+  // destructor
   for (unsigned int i=0; i<fESDs.size(); i++) {
     if (fESDs[i]) {
       delete fESDs[i];
@@ -66,7 +78,7 @@ AliHLTEsdManagerImplementation::~AliHLTEsdManagerImplementation()
 
 int AliHLTEsdManagerImplementation::SetOption(const char* option)
 {
-  // see header file for class documentation
+  // set options
   int iResult=0;
   TString strOptions=option;
   TObjArray* pTokens=strOptions.Tokenize(" ");
@@ -81,6 +93,9 @@ int AliHLTEsdManagerImplementation::SetOption(const char* option)
        } else if (data.Contains("-directory=")) {
          data.ReplaceAll("-directory=", "");
          SetDirectory(data.Data());
+       } else if (data.Contains("-treename=")) {
+         data.ReplaceAll("-treename=", "");
+         fTreeName=data;
        } else {
          HLTError("unknown argument %s", data.Data());
          iResult=-EINVAL;
@@ -95,7 +110,7 @@ int AliHLTEsdManagerImplementation::SetOption(const char* option)
 
 AliHLTEsdManagerImplementation::AliHLTEsdListEntry* AliHLTEsdManagerImplementation::Find(AliHLTComponentDataType dt) const
 {
-  // see header file for class documentation
+  // find a list entry
   AliHLTEsdListEntry* pEntry=NULL;
   for (unsigned int i=0; i<fESDs.size(); i++) {
     if (fESDs[i] && *(fESDs[i])==dt) {
@@ -108,8 +123,8 @@ AliHLTEsdManagerImplementation::AliHLTEsdListEntry* AliHLTEsdManagerImplementati
 int AliHLTEsdManagerImplementation::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size,
                               AliHLTComponentDataType dt, AliESDEvent* tgtesd, int eventno)
 {
-  // see header file for class documentation
-  if (!pBuffer && size<=0) return -EINVAL;
+  // main funtion: write the ESD object
+  if (pBuffer==NULL || size<4) return -EINVAL;
   int iResult=0;
   AliHLTUInt32_t firstWord=*((AliHLTUInt32_t*)pBuffer);
   if (firstWord==size-sizeof(AliHLTUInt32_t)) {
@@ -145,20 +160,15 @@ int AliHLTEsdManagerImplementation::WriteESD(const AliHLTUInt8_t* pBuffer, AliHL
            if (!fDirectory.IsNull()) {
              entry->SetDirectory(fDirectory);
            }
+           if (!fTreeName.IsNull()) {
+             entry->SetTreeName(fTreeName);
+           }
            fESDs.push_back(entry);
          }
        }
        if (entry) {
          if (tgtesd) {
-#if !defined(HAVE_NOT_ESD_COPY)
            Merge(tgtesd, pESD);
-#else //HAVE_NOT_ESD_COPY
-           static bool warningPrinted=false;
-           if (!warningPrinted) {
-             HLTWarning("old version of AliESDEvent does not provide assignment operator, skip merging to global hltEsd");
-           }
-           warningPrinted=true;
-#endif //HAVE_NOT_ESD_COPY
          }
 
          // Matthias 2009-06-06: writing of individual ESD files for the different origins was a
@@ -192,7 +202,7 @@ int AliHLTEsdManagerImplementation::WriteESD(const AliHLTUInt8_t* pBuffer, AliHL
 
 int AliHLTEsdManagerImplementation::PadESDs(int eventno)
 {
-  // see header file for class documentation
+  // insert a number of empty ESDs to keep event no synchronized
   int iResult=0;
   for (unsigned int i=0; i<fESDs.size(); i++) {
     if (fESDs[i]) {
@@ -205,7 +215,7 @@ int AliHLTEsdManagerImplementation::PadESDs(int eventno)
 
 void AliHLTEsdManagerImplementation::SetDirectory(const char* directory)
 {
-  // see header file for class documentation
+  // set the target directory for ESD files
   if (!directory) return;
   fDirectory=directory;
   for (unsigned int i=0; i<fESDs.size(); i++) {
@@ -217,6 +227,7 @@ void AliHLTEsdManagerImplementation::SetDirectory(const char* directory)
 
 TString AliHLTEsdManagerImplementation::GetFileNames(AliHLTComponentDataType dt) const
 {
+  // get a list of file names matching the data type
   TString result;
   for (unsigned int i=0; i<fESDs.size(); i++) {
     if (fESDs[i] && *(fESDs[i])==dt) {
@@ -229,20 +240,12 @@ TString AliHLTEsdManagerImplementation::GetFileNames(AliHLTComponentDataType dt)
 
 TTree* AliHLTEsdManagerImplementation::EmbedIntoTree(AliESDEvent* pESD, const char* name, const char* title)
 {
-  // see header file for class documentation
-  int iResult=0;
+  // create a new TTree object and embed the ESD
   TTree* pTree=new TTree(name, title);
   if (pTree) {
     pESD->WriteToTree(pTree);
     pTree->Fill();
     pTree->GetUserInfo()->Add(pESD);
-  } else {
-    iResult=-ENOMEM;
-  }
-
-  if (iResult<0) {
-    pTree->GetUserInfo()->Clear();
-    delete pTree;
   }
 
   return pTree;
@@ -256,14 +259,15 @@ AliHLTEsdManagerImplementation::AliHLTEsdListEntry::AliHLTEsdListEntry(AliHLTCom
   fpFile(NULL),
   fpTree(NULL),
   fpEsd(NULL),
-  fPrefix()
+  fPrefix(),
+  fTreeName("esdTree")
 {
-  // see header file for class documentation
+  // consructor
 }
 
 AliHLTEsdManagerImplementation::AliHLTEsdListEntry::~AliHLTEsdListEntry()
 {
-  // see header file for class documentation
+  // destructor
   if (fpEsd) delete fpEsd;
   fpEsd=NULL;
 
@@ -279,16 +283,15 @@ AliHLTEsdManagerImplementation::AliHLTEsdListEntry::~AliHLTEsdListEntry()
 
 bool AliHLTEsdManagerImplementation::AliHLTEsdListEntry::operator==(AliHLTComponentDataType dt) const
 {
-  // see header file for class documentation
+  // comparison operator
   return fDt==dt;
 }
 
-int AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteESD(AliESDEvent* pSrcESD, int eventno)
+int AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteESD(const AliESDEvent* pSrcESD, int eventno)
 {
-  // see header file for class documentation
+  // write ESD object
   int iResult=0;
 
-#ifndef HAVE_NOT_ESD_COPY
   if (fName.IsNull()) {
     // this is the first event, create the file name
     fName="";
@@ -310,10 +313,10 @@ int AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteESD(AliESDEvent* pS
     }
 
     fpFile=new TFile(fName, "RECREATE");
-    fpTree=new TTree("esdTree", "Tree with HLT ESD objects");
-    fpTree->SetDirectory(0);
+    fpTree=new TTree(fTreeName, "Tree with HLT ESD objects");
     fpEsd=new AliESDEvent;
-    if (fpEsd) {
+    if (fpEsd && fpTree) {
+      fpTree->SetDirectory(0);
       fpEsd->CreateStdContent();
       *fpEsd=*pSrcESD;
       if (fpTree) {
@@ -343,7 +346,7 @@ int AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteESD(AliESDEvent* pS
        // the branch layout has been created earlier.
        // Create new tree with the additional branches, copy the entries
        // of the current tree into the new tree, and continue.
-       TTree* pNewTree=new TTree("esdTree", "Tree with HLT ESD objects");
+       TTree* pNewTree=new TTree(fTreeName, "Tree with HLT ESD objects");
        pNewTree->SetDirectory(0);
        AliESDEvent* readESD=new AliESDEvent;
        readESD->CreateStdContent();
@@ -377,258 +380,16 @@ int AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteESD(AliESDEvent* pS
       fpTree->GetUserInfo()->Clear();
     }
   }
-#else //HAVE_NOT_ESD_COPY
-  // this is the old workaround, necessary for older AliRoot versions
-  // version<=v4-12-Release
-
-  // we need to copy the ESD, I did not find an approptiate
-  // method, the workaround is to save the ESD in a temporary
-  // tree, read the content back into the ESD structure
-  // used for filling.
-  // Unfortunately the following code crashes at the second event.
-  // The expert on the ESD (Christian Klein Boesig) does not have
-  // a solution either. It seems to be a problem in ROOT.
-  //  TTree* dummy=new TTree("dummy","dummy");
-  //  dummy->SetDirectory(0);
-  //  pESD->WriteToTree(dummy);
-  //  dummy->Fill();
-  //  dummy->GetUserInfo()->Add(pESD);
-  //  fpEsd->ReadFromTree(dummy);
-  //  dummy->GetEvent(0);
-  //  fpEsd->WriteToTree(fpTree);
-  //  fpTree->Fill();
-  //  dummy->GetUserInfo()->Clear();
-  //  delete dummy;
-  //
-  // The only way is via TChain, which is working on files only at the
-  // time of writing.
-  // We use temporary files for the new event to be copied into the
-  // existing tree.
-  //
-  if (fName.IsNull()) {
-    // this is the first event, create the file on disk and write ESD
-    TString origin;
-    origin.Insert(0, fDt.fOrigin, kAliHLTComponentDataTypefOriginSize);
-    origin.Remove(TString::kTrailing, ' ');
-    origin.ToUpper();
-    fName="";
-    if (!fDirectory.IsNull()) {
-      fName+=fDirectory; fName+="/";
-    }
-    fName+="AliHLT"; fName+=origin;
-    if (fDt!=kAliHLTDataTypeESDObject &&
-       fDt!=kAliHLTDataTypeESDTree) {
-
-      HLTWarning("non-standard ESD type %s", AliHLTComponent::DataType2Text(fDt).c_str());
-      TString id;
-      id.Insert(0, fDt.fID, kAliHLTComponentDataTypefIDsize);
-      id.Remove(TString::kTrailing, ' ');
-      id.ToUpper();
-      fName+="_"; fName+=id; fName+=".root";
-    } else {
-      fName+="ESDs.root";
-    }
-
-    if (!gSystem->AccessPathName(fName)) {
-      // file exists, delete
-      TString shellcmd="rm -f ";
-      shellcmd+=fName;
-      gSystem->Exec(shellcmd);
-    }
-  }
-
-  TChain chain("esdTree");
-  TList cleanup;
-  cleanup.SetOwner();
-
-  int nofCurrentEvents=0;
-  if (iResult>=0) {
-    if (!gSystem->AccessPathName(fName)) {
-      // these are the other events, use the target file and temporary files to merge
-      // with TChain
-      chain.Add(fName);
-
-      if (eventno>=0) {
-       TFile file(fName);
-       if (!file.IsZombie()) {
-         TTree* pSrcTree;
-         file.GetObject("esdTree", pSrcTree);
-         if (pSrcTree) {
-           nofCurrentEvents=pSrcTree->GetEntries();
-         }
-         file.Close();
-       }
-      }
-    }
-  }
-
-  // synchronize and add empty events
-  if (nofCurrentEvents<eventno) {
-    iResult=1; // indicate files to merge
-    TTree* pTgtTree=new TTree("esdTree", "Tree with HLT ESD objects");
-    if (pTgtTree) {
-      pTgtTree->SetDirectory(0);
-      AliESDEvent* pTmpESD=new AliESDEvent;
-      if (pTmpESD) {
-       TString tmpfilename;
-       FILE* pTmpFile=gSystem->TempFileName(tmpfilename);
-       if (pTmpFile) {
-         fclose(pTmpFile);
-         pTmpFile=NULL;
-         cleanup.Add(new TObjString(tmpfilename));
-         TFile emptyevents(tmpfilename, "RECREATE");
-         if (!emptyevents.IsZombie()) {
-           pTmpESD->CreateStdContent();
-           pTmpESD->WriteToTree(pTgtTree);
-           HLTDebug("adding %d empty events to file %s", eventno-nofCurrentEvents, fName.Data());
-           for (int i=nofCurrentEvents; i<eventno; i++) {
-             pTgtTree->Fill();
-           }
-           pTgtTree->GetUserInfo()->Add(pTmpESD);
-           emptyevents.cd();
-           pTgtTree->Write();
-           emptyevents.Close();
-           chain.Add(tmpfilename);
-           pTgtTree->GetUserInfo()->Clear();
-         }
-       }
-       delete pTmpESD;
-      } else {
-       iResult=-ENOMEM;
-      }
-      delete pTgtTree;
-    } else {
-      iResult=-ENOMEM;
-    }
-  }
-
-  if (iResult>=0 && pSrcESD) {
-    // add the new event to the chain
-    iResult=1; // indicate files to merge
-    TString tmpfilename=WriteTempFile(pSrcESD);
-    if (!tmpfilename.IsNull()) {
-      chain.Add(tmpfilename);
-      cleanup.Add(new TObjString(tmpfilename));
-    }
-  }
-
-  if (iResult>0) {
-    // build temporary file name for chain output
-    TString tgtName;
-    FILE* pTmpFile=gSystem->TempFileName(tgtName);
-    if (pTmpFile) {
-      fclose(pTmpFile);
-      pTmpFile=NULL;
-
-      // there have been problems with the memory consumption when using
-      // TChain::Merge
-      // but using a separate loop soemtimes crashes in AliESDEvent::ReadFromTree
-      // since this is for backward compatiblity only, we take the TChain::Merge
-      chain.Merge(tgtName);
-//       TFile tgtFile(tgtName, "RECREATE");
-//       TTree* pTgtTree=new TTree("esdTree", "Tree with HLT ESD objects");
-//       AliESDEvent* pTgtESD=new AliESDEvent;
-//       if (pTgtTree && pTgtESD) {
-//     pTgtESD->ReadFromTree(&chain);
-//     pTgtESD->WriteToTree(pTgtTree);
-
-//     int nofEvents=chain.GetEntries();
-//     for (int event=0; event<nofEvents; event++) {
-//       chain.GetEntry(event);
-//       pTgtTree->Fill();
-//     }
-
-//     pTgtTree->GetUserInfo()->Add(pTgtESD);
-//     tgtFile.cd();
-//     pTgtTree->Write();
-//     pTgtTree->GetUserInfo()->Clear();
-//       } else {
-//     iResult=-ENOMEM;
-//       }
-
-//       if (pTgtTree) delete pTgtTree;
-//       if (pTgtESD) delete pTgtESD;
-//       tgtFile.Close();
-
-      // rename the merged file to the original file
-      TString shellcmd="mv ";
-      shellcmd+=tgtName + " " + fName;
-      if (gSystem->Exec(shellcmd)==0) {
-       HLTDebug("renaming %s to %s", tgtName.Data(), fName.Data());
-      } else {
-       HLTError("can not rename temporary file %s to %s", tgtName.Data(), fName.Data());
-      }
-    } else {
-      HLTError("can not get temporary file name from system");
-      iResult=-EBADF;
-    }
-  }
 
-  // delete temporary files
-  // the list objects are cleaned up by the TList destructor as the
-  // list is owner
-  TIter entry(&cleanup);
-  while (TObject* pObj=entry.Next()) {
-    if (dynamic_cast<TObjString*>(pObj)) {
-      TString shellcmd="rm -f ";
-      shellcmd+=(dynamic_cast<TObjString*>(pObj))->GetString();
-      gSystem->Exec(shellcmd);
-    }
-  }
-#endif //HAVE_NOT_ESD_COPY
+  // FIXME: use auto_ptr for the tree and ESD event and add proper
+  // cleanup if something fails
 
   return iResult;
 }
 
-TString AliHLTEsdManagerImplementation::AliHLTEsdListEntry::WriteTempFile(AliESDEvent* pESD) const
-{
-  // see header file for class documentation
-  int iResult=0;
-  TString tmpfilename;
-  FILE* pTmpFile=gSystem->TempFileName(tmpfilename);
-  if (pTmpFile) {
-    fclose(pTmpFile);
-    pTmpFile=NULL;
-
-    TFile file(tmpfilename, "RECREATE");
-    if (!file.IsZombie()) {
-      TTree* pTree=AliHLTEsdManagerImplementation::EmbedIntoTree(pESD);
-      if (pTree) {
-       file.cd();
-       if (pTree->Write()>0) {
-       } else {
-         HLTError("can not write esd tree to temporary file %s", tmpfilename.Data());
-       }
-
-       pTree->GetUserInfo()->Clear();
-       delete pTree;
-      } else {
-       iResult=-ENOMEM;
-      }
-      file.Close();
-    } else {
-      HLTError("can not open file %s", tmpfilename.Data());
-      iResult=-EBADF;
-    }
-  } else {
-    HLTError("can not get temporary file name from system");
-    iResult=-EBADF;
-  }
-
-  if (iResult<0) {
-    if (gSystem->AccessPathName(tmpfilename)==0) {
-      TString shellcmd="rm -f ";
-      shellcmd+=tmpfilename;
-      gSystem->Exec(shellcmd);
-    }
-    tmpfilename="";
-  }
-  return tmpfilename;
-}
-
 void AliHLTEsdManagerImplementation::AliHLTEsdListEntry::SetDirectory(const char* directory)
 {
-  // see header file for class documentation
+  // set the target directory
   if (!directory) return;
   if (!fName.IsNull()) {
     HLTWarning("ESD entry already in writing mode (%s), ignoring directory", fName.Data());
@@ -637,27 +398,15 @@ void AliHLTEsdManagerImplementation::AliHLTEsdListEntry::SetDirectory(const char
   fDirectory=directory;
 }
 
-void AliHLTEsdManagerImplementation::AliHLTEsdListEntry::Delete()
-{
-  // see header file for class documentation
-  if (fName.IsNull()) return;
-  if (gSystem->AccessPathName(fName)!=0) return;
-
-  TString shellcmd="rm -f ";
-  shellcmd+=fName;
-  gSystem->Exec(shellcmd);
-  fName="";
-}
-
 const char* AliHLTEsdManagerImplementation::AliHLTEsdListEntry::GetFileName() const
 {
-  // see header file for class documentation
+  // get the file name
   return fName.Data();
 }
 
 const char* AliHLTEsdManagerImplementation::AliHLTEsdListEntry::GetPrefix()
 {
-  // see header file for class documentation
+  // get prefix from data origin
   if (fPrefix.IsNull()) {
     fPrefix.Insert(0, fDt.fOrigin, kAliHLTComponentDataTypefOriginSize);
     fPrefix.Remove(TString::kTrailing, ' ');
@@ -671,7 +420,11 @@ const char* AliHLTEsdManagerImplementation::AliHLTEsdListEntry::GetPrefix()
 
 int AliHLTEsdManagerImplementation::Merge(AliESDEvent* pTgt, AliESDEvent* pSrc) const
 {
-  // see header file for class documentation
+  // merge two ESDs, this method implements specifc handling for different
+  // types of ESD content in order to avoid overwriting of data in the target ESD
+  // by empty/default data of the source ESD
+  // - arrays: just check if there are entries
+  // - other objects: see below
   int iResult=0;
   if (!pTgt || !pSrc) return -EINVAL;
 
@@ -681,8 +434,65 @@ int AliHLTEsdManagerImplementation::Merge(AliESDEvent* pTgt, AliESDEvent* pSrc)
   while ((pSrcObject=next())) {
     if(!pSrcObject->InheritsFrom("TCollection")){
       // simple objects
+      // for every type of object we have to find out whether it is empty or not
+      // objects are only copied if non-empty, otherwise valid content would be
+      // overridden by empty objects during the merging
+      bool copy=false;
       TString name=pSrcObject->GetName();
       if(pSrcObject->InheritsFrom("AliHLTTriggerDecision")){
+       copy=true;
+      } else if (pSrcObject->IsA()==AliESDRun::Class()) {
+       AliESDRun* pESDRun=dynamic_cast<AliESDRun*>(pSrcObject);
+       // zero might be a valid run no in simulation, so we check also whether the CTP trigger classes are set
+       copy=(pESDRun && (pESDRun->GetRunNumber()>0 || !pESDRun->GetActiveTriggerClasses().IsNull()));
+      } else if (pSrcObject->IsA()==AliESDHeader::Class()) {
+       AliESDHeader* pESDHeader=dynamic_cast<AliESDHeader*>(pSrcObject);
+       copy=(pESDHeader && pESDHeader->GetTriggerMask()!=0);
+      } else if (pSrcObject->IsA()==AliESDVertex::Class()) {
+       AliESDVertex* pESDVertex=dynamic_cast<AliESDVertex*>(pSrcObject);
+       copy=(pESDVertex && pESDVertex->GetNContributors()>0);
+      } else if (pSrcObject->IsA()==AliESDTZERO::Class()) {
+       AliESDTZERO* pESDTZero=dynamic_cast<AliESDTZERO*>(pSrcObject);
+       copy=(pESDTZero && (pESDTZero->GetT0zVertex()!=0.0 || pESDTZero->GetT0()!=0.0));
+      } else if (pSrcObject->IsA()==AliESDVZERO::Class()) {
+       AliESDVZERO* pESDVZERO=dynamic_cast<AliESDVZERO*>(pSrcObject);
+       // object contains data if one of the times exceeds the default value
+       copy=pESDVZERO &&
+         (pESDVZERO->GetV0ATime() > kAliESDVZERODefaultTime+kAliESDVZERODefaultTimeGlitch ||
+          pESDVZERO->GetV0CTime() > kAliESDVZERODefaultTime+kAliESDVZERODefaultTimeGlitch);
+      } else if (pSrcObject->IsA()==AliESDFMD::Class()) {
+       AliESDFMD* pESDFMD=dynamic_cast<AliESDFMD*>(pSrcObject);
+       copy=(pESDFMD && false); // have to find an easy valid condition
+      } else if (pSrcObject->IsA()==AliESDZDC::Class()) {
+       AliESDZDC* pESDZDC=dynamic_cast<AliESDZDC*>(pSrcObject);
+       // object contains data if the EM energies are different from the default value
+       copy=pESDZDC &&
+         (TMath::Abs(pESDZDC->GetZDCEMEnergy(0)-kAliESDZDCDefaultEMEnergy) > kAliESDZDCDefaultEMEnergyGlitch ||
+          TMath::Abs(pESDZDC->GetZDCEMEnergy(1)-kAliESDZDCDefaultEMEnergy) > kAliESDZDCDefaultEMEnergyGlitch);
+      } else if (pSrcObject->IsA()==AliMultiplicity::Class()) {
+       AliMultiplicity* pMultiplicity=dynamic_cast<AliMultiplicity*>(pSrcObject);
+       copy=(pMultiplicity && pMultiplicity->GetNumberOfTracklets()>0);
+      } else if (pSrcObject->IsA()==AliESDCaloTrigger::Class()) {
+       AliESDCaloTrigger* pESDCaloTrigger=dynamic_cast<AliESDCaloTrigger*>(pSrcObject);
+       copy=(pESDCaloTrigger && false); // have to find an easy valid condition
+      } else if (pSrcObject->IsA()==AliESDCaloCells::Class()) {
+       AliESDCaloCells* pESDCaloCells=dynamic_cast<AliESDCaloCells*>(pSrcObject);
+       copy=(pESDCaloCells && false); // have to find an easy valid condition
+      } else if (pSrcObject->IsA()==AliESDACORDE::Class()) {
+       AliESDACORDE* pESDACORDE=dynamic_cast<AliESDACORDE*>(pSrcObject);
+       copy=(pESDACORDE && false); // have to find an easy valid condition
+      } else if (pSrcObject->IsA()==AliESDTrdTrigger::Class()) {
+       AliESDTrdTrigger* pESDTrdTrigger=dynamic_cast<AliESDTrdTrigger*>(pSrcObject);
+       copy=(pESDTrdTrigger && false); // have to find an easy valid condition
+      } else if (pSrcObject->IsA()==AliTOFHeader::Class()) {
+       copy=false; // no TOF in HLT (there are no links)
+      } else if (!AliHLTESDEventHelper::IsStdContent(name)) {
+       // this is likely to be ok as long as it is not any object of the std content.
+       copy=true;
+      } else {
+       HLTError("no merging implemented for object %s, omitting", name.Data());
+      }
+      if (copy) {
        //pSrcObject->Print();
        TObject* pTgtObject=pTgt->FindListObject(name);
        if (pTgtObject) {
@@ -690,8 +500,6 @@ int AliHLTEsdManagerImplementation::Merge(AliESDEvent* pTgt, AliESDEvent* pSrc)
        } else {
          pTgt->AddObject(pSrcObject->Clone());
        }
-      } else {
-       // TODO: implement the handling of other objects, some kind of mapping
       }
     } else if(pSrcObject->InheritsFrom("TClonesArray")){
       TClonesArray* pTClA=dynamic_cast<TClonesArray*>(pSrcObject);
@@ -748,3 +556,85 @@ int AliHLTEsdManagerImplementation::Merge(AliESDEvent* pTgt, AliESDEvent* pSrc)
   }
   return iResult;
 }
+
+bool AliHLTEsdManagerImplementation::AliHLTESDEventHelper::IsStdContent(const char* key)
+{
+  // check if the key denotes a std object
+  TString needle=key;
+  for (int i=0; i<kESDListN; i++) {
+    if (needle.CompareTo(fgkESDListName[i])==0) return true;
+  }
+  return false;
+}
+
+int AliHLTEsdManagerImplementation::CheckClassConditions() const
+{
+  // this is a helper method which checks if some thing in the default
+  // object initialization changes during the evolution of the source code
+  // which is necessary for checking the validity of data in the object
+
+  // check AliESDVZERO
+  AliESDVZERO vzerodummy;
+  if (TMath::Abs(vzerodummy.GetV0ATime()-kAliESDVZERODefaultTime) > kAliESDVZERODefaultTimeGlitch ||
+      TMath::Abs(vzerodummy.GetV0CTime()-kAliESDVZERODefaultTime) > kAliESDVZERODefaultTimeGlitch) {
+    HLTWarning("initialization of AliESDVZERO has changed, default time values now %f/%f, "
+              "revision of condition might be needed",
+              vzerodummy.GetV0ATime(), vzerodummy.GetV0CTime());
+  }
+
+  // check AliESDZDC
+  AliESDZDC zdcdummy;
+  if (TMath::Abs(zdcdummy.GetZDCEMEnergy(0)-kAliESDZDCDefaultEMEnergy) > kAliESDZDCDefaultEMEnergyGlitch ||
+      TMath::Abs(zdcdummy.GetZDCEMEnergy(1)-kAliESDZDCDefaultEMEnergy) > kAliESDZDCDefaultEMEnergyGlitch) {
+    HLTWarning("initialization of AliESDZDC has changed, default em energy values now %f/%f, "
+              "revision of condition might be needed",
+              zdcdummy.GetZDCEMEnergy(0), zdcdummy.GetZDCEMEnergy(1));
+  }
+
+  return 0;
+}
+
+TObject* AliHLTEsdManagerImplementation::CreateEsdEvent(bool bCreateStdContent) const
+{
+  // create ESDEvent object and optionally initialize standard content
+  AliESDEvent* pESD=new AliESDEvent;
+  if (pESD && bCreateStdContent) pESD->CreateStdContent();
+  return pESD;
+}
+
+int AliHLTEsdManagerImplementation::DestroyEsdEvent(TObject* pESDInstance) const
+{
+  // destroy specified ESD object, pointer is invalid afterwords
+  if (!pESDInstance) return -EINVAL;
+  AliESDEvent* pESD=dynamic_cast<AliESDEvent*>(pESDInstance);
+  if (!pESD) return -EINVAL;
+  delete pESD;
+  return 0;
+}
+
+int AliHLTEsdManagerImplementation::AddObject(TObject* pESDInstance, const TObject* pObject, const char* branchname) const
+{
+  // add object to the list of ESD contributors
+  if (!pESDInstance || !pObject) return -EINVAL;
+  AliESDEvent* pESD=dynamic_cast<AliESDEvent*>(pESDInstance);
+  if (!pESD) return -EINVAL;
+  TObject* pESDObject=pESD->FindListObject(branchname);
+  if (pESDObject) {
+    // copy the content to the already existing object
+    pObject->Copy(*pESDObject);
+  } else {
+    // add a new object
+    pESD->AddObject(pObject->Clone());
+  }
+  return 0;
+}
+
+int AliHLTEsdManagerImplementation::ResetEsdEvent(TObject* pESDInstance) const
+{
+  // reset the specified ESD object
+  if (!pESDInstance) return -EINVAL;
+  AliESDEvent* pESD=dynamic_cast<AliESDEvent*>(pESDInstance);
+  if (!pESD) return -EINVAL;
+  pESD->Reset();
+  return 0;
+}