]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
- workaround for copying and merging of ESDs: The HLTOUT contains ESDs for every...
authorrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 18 Apr 2008 06:53:35 +0000 (06:53 +0000)
committerrichterm <richterm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 18 Apr 2008 06:53:35 +0000 (06:53 +0000)
  which need to be merged and copied. There is no other way to copy ESDs than writing
  to a temporary tree and reading it back into the target, even that might cause a crash
  in the subsequent TRee::Fill -> workaround: TChain and temporary files
- correct initialization of the magnetic field in TPC ESD writer/converter

HLT/BASE/AliHLTSystem.cxx
HLT/TPCLib/AliHLTTPCEsdWriterComponent.cxx
HLT/TPCLib/AliHLTTPCEsdWriterComponent.h
HLT/rec/AliHLTEsdManager.cxx
HLT/rec/AliHLTEsdManager.h
HLT/sim/AliHLTSimulation.cxx

index 510b8f42a691ab2e0938f5c7e3be6375eb0e1c4e..7939458e72ca8ac7400357c3b6ab846ba73f5d47 100644 (file)
@@ -71,7 +71,8 @@ AliHLTSystem::AliHLTSystem()
   fChains(),
   fStopwatches(new TObjArray),
   fEventCount(-1),
-  fGoodEvents(-1)
+  fGoodEvents(-1),
+  bWriteGlobalEsd(false)
 {
   // see header file for class documentation
   // or
@@ -707,6 +708,14 @@ int AliHLTSystem::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd)
 
   HLTDebug("processing %d HLT data blocks", pHLTOUT->GetNofDataBlocks());
   AliHLTOUT::AliHLTOUTHandlerListEntryVector esdHandlers;
+
+  // first come first serve: the ESD of the first handler is also filled into
+  // the main ESD. Has to be changed later.
+  // currently, merging to the provided ESDs crashes at the level of the
+  // TTree::Fill in AliReconstruction, furthermore, the wrong ESD is passed
+  // by the framework
+  AliESDEvent* pMasterESD=NULL;
+  if (bWriteGlobalEsd) pMasterESD=esd;
   for (iResult=pHLTOUT->SelectFirstDataBlock();
        iResult>=0;
        iResult=pHLTOUT->SelectNextDataBlock()) {
@@ -733,6 +742,10 @@ int AliHLTSystem::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd)
          AliHLTUInt32_t size=0;
          if (pHLTOUT->GetDataBuffer(pBuffer, size)>=0) {
            pHLTOUT->WriteESD(pBuffer, size, dt);
+           if (pMasterESD) {
+             pHLTOUT->WriteESD(pBuffer, size, dt, pMasterESD);
+             pMasterESD=NULL;
+           }
            pHLTOUT->ReleaseDataBuffer(pBuffer);
          }
        }
@@ -780,9 +793,6 @@ int AliHLTSystem::ProcessHLTOUT(AliHLTOUT* pHLTOUT, AliESDEvent* esd)
 
   AliHLTOUT::AliHLTOUTHandlerListEntryVector::iterator esdHandler;
   // write all postponed esd data blocks
-  // first come first serve: the ESD of the first handler is also filled into
-  // the main ESD. Has to be changed later.
-  AliESDEvent* pMasterESD=esd;
   for (esdHandler=esdHandlers.begin(); esdHandler!=esdHandlers.end() && iResult>=0; esdHandler++) {
     AliHLTOUTHandler* pHandler=*esdHandler;
     const AliHLTUInt8_t* pBuffer=NULL;
@@ -937,6 +947,8 @@ int AliHLTSystem::ScanOptions(const char* options)
              HLTWarning("wrong argument for option \'libmode=\', use \'static\' or \'dynamic\'");
            }
          }
+       } else if (token.Contains("globalesd")) {
+         bWriteGlobalEsd=true;
        } else if (token.BeginsWith("lib") && token.EndsWith(".so")) {
          libs+=token;
          libs+=" ";
index 7e92e3af3714081a5b223fbc8c7f926f42aaa342..8e054d25fa96c1652d4bfadb8740bbdfdfd279d1 100644 (file)
@@ -33,6 +33,8 @@
 #include "AliHLTTPCEsdWriterComponent.h"
 #include "AliESDEvent.h"
 #include "AliESDtrack.h"
+#include "AliCDBEntry.h"
+#include "AliCDBManager.h"
 #include "TTree.h"
 #include "TList.h"
 #include "AliHLTTPCTrack.h"
@@ -45,6 +47,8 @@
 ClassImp(AliHLTTPCEsdWriterComponent)
 
 AliHLTTPCEsdWriterComponent::AliHLTTPCEsdWriterComponent()
+  :
+  fSolenoidBz(0)
 {
   // see header file for class documentation
   // or
@@ -101,6 +105,11 @@ int AliHLTTPCEsdWriterComponent::AliWriter::InitWriter()
   if (fTree==NULL) {
     iResult=-ENOMEM;
   }
+
+  if (iResult>=0) {
+    iResult=fBase->Reconfigure(NULL, NULL);
+  }
+
   return iResult;
 }
 
@@ -164,6 +173,7 @@ int AliHLTTPCEsdWriterComponent::ProcessBlocks(TTree* pTree, AliESDEvent* pESD,
   // see header file for class documentation
   int iResult=0;
   if (pESD && blocks) {
+      pESD->SetMagneticField(fSolenoidBz);
       const AliHLTComponentBlockData* iter = NULL;
       AliHLTTPCTrackletData* inPtr=NULL;
       int bIsTrackSegs=0;
@@ -246,6 +256,72 @@ int AliHLTTPCEsdWriterComponent::Tracks2ESD(AliHLTTPCTrackArray* pTracks, AliESD
   return iResult;
 }
 
+int AliHLTTPCEsdWriterComponent::Configure(const char* arguments)
+{
+  // see header file for class documentation
+  int iResult=0;
+  if (!arguments) return iResult;
+
+  TString allArgs=arguments;
+  TString argument;
+  int bMissingParam=0;
+
+  TObjArray* pTokens=allArgs.Tokenize(" ");
+  if (pTokens) {
+    for (int i=0; i<pTokens->GetEntries() && iResult>=0; i++) {
+      argument=((TObjString*)pTokens->At(i))->GetString();
+      if (argument.IsNull()) continue;
+      
+      if (argument.CompareTo("-solenoidBz")==0) {
+       if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;
+       HLTInfo("Magnetic Field set to: %s", ((TObjString*)pTokens->At(i))->GetString().Data());
+       fSolenoidBz=((TObjString*)pTokens->At(i))->GetString().Atof();
+       continue;
+      } else {
+       HLTError("unknown argument %s", argument.Data());
+       iResult=-EINVAL;
+       break;
+      }
+    }
+    delete pTokens;
+  }
+  if (bMissingParam) {
+    HLTError("missing parameter for argument %s", argument.Data());
+    iResult=-EINVAL;
+  }
+
+  return iResult;
+}
+
+int AliHLTTPCEsdWriterComponent::Reconfigure(const char* cdbEntry, const char* chainId)
+{
+  // see header file for class documentation
+  int iResult=0;
+  const char* path="HLT/ConfigHLT/SolenoidBz";
+  const char* defaultNotify="";
+  if (cdbEntry) {
+    path=cdbEntry;
+    defaultNotify=" (default)";
+  }
+  if (path) {
+    HLTInfo("reconfigure from entry %s%s, chain id %s", path, defaultNotify,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
+    AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path/*,GetRunNo()*/);
+    if (pEntry) {
+      TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
+      if (pString) {
+       HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
+       iResult=Configure(pString->GetString().Data());
+      } else {
+       HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
+      }
+    } else {
+      HLTError("can not fetch object \"%s\" from CDB", path);
+    }
+  }
+  
+  return iResult;
+}
+
 AliHLTTPCEsdWriterComponent::AliConverter::AliConverter()
   :
   fBase(new AliHLTTPCEsdWriterComponent),
@@ -313,6 +389,10 @@ int AliHLTTPCEsdWriterComponent::AliConverter::DoInit(int argc, const char** arg
     iResult=-EINVAL;
   }
 
+  if (iResult>=0) {
+    iResult=fBase->Reconfigure(NULL, NULL);
+  }
+
   return iResult;
 }
 
index 431ac097d025b9e9fdb167ef6ba88a4e9ed84db8..f8c633b8fb41db3eb75aa75ee7acedb88854225c 100644 (file)
@@ -240,6 +240,23 @@ class AliHLTTPCEsdWriterComponent : public AliHLTLogging
   /** assignment operator prohibited */
   AliHLTTPCEsdWriterComponent& operator=(const AliHLTTPCEsdWriterComponent&);
 
-  ClassDef(AliHLTTPCEsdWriterComponent, 1)
+  /**
+   * (Re)Configure from the CDB
+   * Loads the following objects:
+   * - HLT/ConfigHLT/SolenoidBz
+   */
+  int Reconfigure(const char* cdbEntry, const char* chainId);
+
+  /**
+   * Configure the component.
+   * Parse a string for the configuration arguments and set the component
+   * properties.
+   */  
+  int Configure(const char* arguments);
+
+  /** solenoid b field */
+  Double_t fSolenoidBz; //! transient
+
+  ClassDef(AliHLTTPCEsdWriterComponent, 2)
 };
 #endif
index ed22b38584d291584ee77040f2e226341d6539fd..9f6e4f02ce9a0852ae2a4061cfab0572a6f7b450 100644 (file)
 #include "TClass.h"
 #include "TObject.h"
 #include "TObjectTable.h"
+#include "TSystem.h"
+#include "TChain.h"
+#include "TList.h"
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 ClassImp(AliHLTEsdManager)
 
 AliHLTEsdManager::AliHLTEsdManager()
   :
-  fESDs()
+  fESDs(),
+  fDirectory()
 {
   // see header file for class documentation
   // or
@@ -107,10 +111,23 @@ int AliHLTEsdManager::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size
        AliHLTEsdListEntry* entry=Find(dt);
        if (!entry) {
          AliHLTEsdListEntry* newEntry=new AliHLTEsdListEntry(dt);
+         if (!fDirectory.IsNull()) {
+           newEntry->SetDirectory(fDirectory);
+         }
          fESDs.push_back(newEntry);
        }
        if (tgtesd) {
-       }
+         TTree* pTmpTree=AliHLTEsdManager::EmbedIntoTree(pESD);
+         if (pTmpTree) {
+           tgtesd->ReadFromTree(pTmpTree);
+           pTmpTree->GetEvent(0);
+           pTmpTree->GetUserInfo()->Clear();
+           delete pTmpTree;
+           HLTDebug("data block %s written to target ESD", AliHLTComponent::DataType2Text(dt).c_str());
+         } else {
+           iResult=-ENOMEM;
+         }
+       } else {
        entry=Find(dt);
        if (entry) {
          entry->WriteESD(pESD, eventno);
@@ -118,6 +135,7 @@ int AliHLTEsdManager::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size
          HLTError("internal mismatch, can not create list entry");
          iResult=-ENOMEM;
        }
+       }
       } else {
        HLTWarning("data block %s is not of class type AliESDEvent, ignoring ...", AliHLTComponent::DataType2Text(dt).c_str());
       }
@@ -134,39 +152,76 @@ int AliHLTEsdManager::WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size
   return iResult;
 }
 
-AliHLTEsdManager::AliHLTEsdListEntry::AliHLTEsdListEntry(AliHLTComponentDataType dt)
-  :
-  fName(),
-  fpFile(NULL),
-  fpTree(NULL),
-  fpEsd(NULL),
-  fDt(dt)
+int AliHLTEsdManager::PadESDs(int eventno)
 {
   // see header file for class documentation
+  int iResult=0;
+  for (unsigned int i=0; i<fESDs.size(); i++) {
+    if (fESDs[i]) {
+      int res=fESDs[i]->WriteESD(NULL, eventno);
+      if (res<0 && iResult>=0) iResult=res;
+    }
+  }
+  return iResult;
 }
 
-AliHLTEsdManager::AliHLTEsdListEntry::~AliHLTEsdListEntry()
+void AliHLTEsdManager::SetDirectory(const char* directory)
 {
   // see header file for class documentation
-  if (fpTree) {
-    fpTree->GetUserInfo()->Clear();
-    delete fpTree;
-    fpTree=NULL;
+  if (!directory) return;
+  fDirectory=directory;
+  for (unsigned int i=0; i<fESDs.size(); i++) {
+    if (fESDs[i]) {
+      fESDs[i]->SetDirectory(directory);
+    }
+  }
+}
+
+TString AliHLTEsdManager::GetFileNames(AliHLTComponentDataType dt) const
+{
+  TString result;
+  for (unsigned int i=0; i<fESDs.size(); i++) {
+    if (fESDs[i] && *(fESDs[i])==dt) {
+      if (!result.IsNull()) result+=" ";
+      result+=fESDs[i]->GetFileName();
+    }
   }
+  return result;
+}
 
-  // due to the Root garbage collection the ESD object might already be
-  // deleted since the pTree->GetUserInfo()->Add(pESD) adds the ESD object to
-  // an internal list which is cleaned when the tree is deleted
-  if (fpEsd && gObjectTable->PtrIsValid(fpEsd)) {
-    delete fpEsd;
+TTree* AliHLTEsdManager::EmbedIntoTree(AliESDEvent* pESD, const char* name, const char* title)
+{
+  // see header file for class documentation
+  int iResult=0;
+  TTree* pTree=new TTree(name, title);
+  if (pTree) {
+    pESD->WriteToTree(pTree);
+    pTree->Fill();
+    pTree->GetUserInfo()->Add(pESD);
+  } else {
+    iResult=-ENOMEM;
   }
-  fpEsd=NULL;
 
-  if (fpFile) {
-    fpFile->Close();
-    delete fpFile;
-    fpFile=NULL;
+  if (iResult<0) {
+    pTree->GetUserInfo()->Clear();
+    delete pTree;
   }
+
+  return pTree;
+}
+
+AliHLTEsdManager::AliHLTEsdListEntry::AliHLTEsdListEntry(AliHLTComponentDataType dt)
+  :
+  fName(),
+  fDirectory(),
+  fDt(dt)
+{
+  // see header file for class documentation
+}
+
+AliHLTEsdManager::AliHLTEsdListEntry::~AliHLTEsdListEntry()
+{
+  // see header file for class documentation
 }
 
 bool AliHLTEsdManager::AliHLTEsdListEntry::operator==(AliHLTComponentDataType dt) const
@@ -175,17 +230,44 @@ bool AliHLTEsdManager::AliHLTEsdListEntry::operator==(AliHLTComponentDataType dt
   return fDt==dt;
 }
 
-int AliHLTEsdManager::AliHLTEsdListEntry::WriteESD(AliESDEvent* pESD, int eventno)
+int AliHLTEsdManager::AliHLTEsdListEntry::WriteESD(AliESDEvent* pSrcESD, int eventno)
 {
-  // see header file for class documentation
-  if (!pESD) return -EINVAL;
+  // 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.
+  //
   int iResult=0;
-  if (!fpFile) {
+  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="AliHLT"; fName+=origin;
+    fName="";
+    if (!fDirectory.IsNull()) {
+      fName+=fDirectory; fName+="/";
+    }
+    fName+="AliHLT"; fName+=origin;
     if (fDt!=kAliHLTDataTypeESDObject &&
        fDt!=kAliHLTDataTypeESDTree) {
 
@@ -197,69 +279,199 @@ int AliHLTEsdManager::AliHLTEsdListEntry::WriteESD(AliESDEvent* pESD, int eventn
       fName+="_"; fName+=id; fName+=".root";
     } else {
       fName+="ESDs.root";
-      fpFile=new TFile(fName, "RECREATE");
+    }
+
+    if (!gSystem->AccessPathName(fName)) {
+      // file exists, delete
+      TString shellcmd="rm -f ";
+      shellcmd+=fName;
+      gSystem->Exec(shellcmd);
     }
   }
-  if (fpFile && !fpFile->IsZombie() && iResult>=0) {
-    if (!fpTree) {
-      fpTree=new TTree("esdTree", "Tree with HLT ESD objects");
-      if (!fpTree) {
-       iResult=-ENOMEM;
-      } else {
-       fpTree->SetDirectory(0);
+
+  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();
+       }
       }
     }
-    if (fpTree && iResult>=0) {
-      if (!fpEsd) {
-       // create the ESD structure for filling into the tree
-       fpEsd=new AliESDEvent;
-       if (fpEsd) {
-         fpEsd->CreateStdContent();
-         fpTree->GetUserInfo()->Add(fpEsd);
-       } else {
-         iResult=-ENOMEM;
+  }
+
+  // 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 {
-       fpEsd->ResetStdContent();
+       iResult=-ENOMEM;
       }
-      if (eventno>=0) {
-       // synchronize and add empty events
-       for (int i=fpTree->GetEntries(); i<eventno; i++) {
-         fpTree->Fill();
-       }
-       if (fpTree->GetEntries()>eventno) {
-         HLTWarning("event %d ESD of type %s already written, skipping additional data block", eventno, AliHLTComponent::DataType2Text(fDt).c_str());
-       }
+      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;
+
+      chain.Merge(tgtName);
+      // 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());
       }
-      if (fpEsd) {
-       // 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
-       TTree* dummy=new TTree("dummy","dummy");
-       if (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;
+    } else {
+      HLTError("can not get temporary file name from system");
+      iResult=-EBADF;
+    }
+  }
+
+  // delete temporary files
+  // the list objects are cleaned up be 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);
+    }
+  }
+
+  return iResult;
+}
+
+TString AliHLTEsdManager::AliHLTEsdListEntry::WriteTempFile(AliESDEvent* pESD) const
+{
+  // see header file for class documentation
+  int iResult;
+  TString tmpfilename;
+  FILE* pTmpFile=gSystem->TempFileName(tmpfilename);
+  if (pTmpFile) {
+    fclose(pTmpFile);
+    pTmpFile=NULL;
+
+    TFile file(tmpfilename, "RECREATE");
+    if (!file.IsZombie()) {
+      TTree* pTree=AliHLTEsdManager::EmbedIntoTree(pESD);
+      if (pTree) {
+       file.cd();
+       if (pTree->Write()>0) {
        } else {
-         iResult=-ENOMEM;
+         HLTError("can not write esd tree to temporary file %s", tmpfilename.Data());
        }
+
+       pTree->GetUserInfo()->Clear();
+       delete pTree;
       } else {
        iResult=-ENOMEM;
       }
-      if (iResult>=0) {
-       fpTree->Write("",TObject::kOverwrite);
-      }
+      file.Close();
+    } else {
+      HLTError("can not open file %s", tmpfilename.Data());
     }
+  } else {
+    HLTError("can not get temporary file name from system");
+    iResult=-EBADF;
   }
-  return iResult;
+
+  if (iResult<0) {
+    if (gSystem->AccessPathName(tmpfilename)==0) {
+      TString shellcmd="rm -f ";
+      shellcmd+=tmpfilename;
+      gSystem->Exec(shellcmd);
+    }
+    tmpfilename="";
+  }
+  return tmpfilename;
+}
+
+void AliHLTEsdManager::AliHLTEsdListEntry::SetDirectory(const char* directory)
+{
+  // see header file for class documentation
+  if (!directory) return;
+  if (!fName.IsNull()) {
+    HLTWarning("ESD entry already in writing mode (%s), ignoring directory", fName.Data());
+    return;
+  }
+  fDirectory=directory;
+}
+
+void AliHLTEsdManager::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* AliHLTEsdManager::AliHLTEsdListEntry::GetFileName() const
+{
+  // see header file for class documentation
+  return fName.Data();
 }
index b02f02003e42577a91f4248971fa3de2bed82e2e..ace5212b6e925d9f31ca6cbbb5675ffd37c8379d 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "AliHLTDataTypes.h"
 #include "AliHLTLogging.h"
+#include "TString.h"
 #include <vector>
 
 class AliESDEvent;
@@ -47,6 +48,32 @@ class AliHLTEsdManager : public AliHLTLogging {
   int WriteESD(const AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size, AliHLTComponentDataType dt,
               AliESDEvent* tgtesd=NULL, int eventno=-1);
 
+  /**
+   * Align all ESD to the same number of events.
+   * The function adds empty events to all ESD files if their event number
+   * does not match the specified one.
+   * @param eventno     the desired event no
+   * @return neg. error code if failed
+   */
+  int PadESDs(int eventno);
+
+  /**
+   * Set the target directory for the ESD files.
+   */
+  void SetDirectory(const char* directory);
+
+  /**
+   * Get the list of the internally created files.
+   * Returns a blank separated list of the file names.
+   */
+  TString GetFileNames(AliHLTComponentDataType dt=kAliHLTAnyDataType) const;
+
+  /**
+   * Embed an ESD into a TTree object.
+   * The tree object needs to be deleted by the caller.
+   */
+  static TTree* EmbedIntoTree(AliESDEvent* pESD, const char* name="esdTree", const char* title="Tree with HLT ESD objects");
+
  protected:
 
  private:
@@ -73,6 +100,21 @@ class AliHLTEsdManager : public AliHLTLogging {
      */
     int WriteESD(AliESDEvent* pESD, int eventno=-1);
 
+    /**
+     * Set the target directory for the ESD file.
+     */
+    void SetDirectory(const char* directory);
+
+    /**
+     * Delete the ESD file.
+     */
+    void Delete();
+
+    /**
+     * Get name of the ESD file.
+     */
+    const char* GetFileName() const;
+
     bool operator==(AliHLTComponentDataType dt) const;
 
   private:
@@ -81,14 +123,19 @@ class AliHLTEsdManager : public AliHLTLogging {
     /** assignment operator prohibited */
     AliHLTEsdListEntry& operator=(const AliHLTEsdListEntry& src);
 
+    /**
+     * Write ESD to temporary file.
+     * The ESD is embedded into a tree and saved to a temporary file.
+     * The file name is retrieved by TSystem::GetTempFileName and returned
+     * on success.
+     * @return file name, empty on failure
+     */
+    TString WriteTempFile(AliESDEvent* pESD) const;
+
     /** root file name */
     TString fName; //!transient
-    /** the root file for this esd */
-    TFile* fpFile; //!transient
-    /** the tree for this esd */
-    TTree* fpTree; //!transient
-    /** the esd to fill into the tree */
-    AliESDEvent* fpEsd; //!transient
+    /** target directory */
+    TString fDirectory; //!transient
     /** data type of the corresponding block */
     AliHLTComponentDataType fDt; //!transient
   };
@@ -103,6 +150,10 @@ class AliHLTEsdManager : public AliHLTLogging {
   /** the list of the ESDs */
   AliHLTEsdPList fESDs; //!transient
 
+  /** target directory */
+  TString fDirectory; //!transient
+
   ClassDef(AliHLTEsdManager, 0)
 };
+
 #endif
index 252a8903d96abdce4db07e9b770b2e034a4f4374..f29b2d1bbfbda600d86c07b0479c0736da1fcad2 100644 (file)
 #include "TObjString.h"
 #include "AliHLTSimulation.h"
 #include "AliLog.h"
+#include "AliRun.h"
 #include "AliRunLoader.h"
+#include "AliHeader.h"
+#include "AliTracker.h"
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
+#include "AliCDBPath.h"
+#include "AliCDBId.h"
+#include "AliCDBMetaData.h"
 #include "AliHLTSystem.h"
 #include "AliRawReaderFile.h"
 #include "AliRawReaderDate.h"
@@ -146,6 +154,32 @@ int AliHLTSimulation::Init(AliRunLoader* pRunLoader, const char* options)
     delete pTokens;
   }
 
+  // init solenoid field
+  Bool_t bUniformField=kTRUE;
+  AliTracker::SetFieldMap(pRunLoader->GetAliRun()->Field(),bUniformField);
+  Double_t solenoidBz=AliTracker::GetBz();
+  AliCDBManager* man = AliCDBManager::Instance();
+  if (man && man->IsDefaultStorageSet())
+  {
+    const char* cdbSolenoidPath="HLT/ConfigHLT/SolenoidBz";
+    int runNo=pRunLoader->GetHeader()->GetRun();
+    TString cdbSolenoidParam;
+    cdbSolenoidParam.Form("-solenoidBz %f", solenoidBz);
+
+    // check if the entry is already there
+    AliCDBEntry *pEntry = man->Get(cdbSolenoidPath, runNo);
+    TObjString* pString=NULL;
+    if (pEntry) pString=dynamic_cast<TObjString*>(pEntry->GetObject());
+
+    if (!pEntry || !pString || pString->GetString().CompareTo(cdbSolenoidParam)!=0) {
+      TObjString obj(cdbSolenoidParam);
+      AliCDBPath cdbSolenoidEntry(cdbSolenoidPath);
+      AliCDBId cdbSolenoidId(cdbSolenoidEntry, runNo, runNo);
+      AliCDBMetaData cdbMetaData;
+      man->Put(&obj, cdbSolenoidId, &cdbMetaData);
+    }
+  }
+
   // scan options
   if (fpSystem->ScanOptions(sysOp.Data())<0) {
     AliError("error setting options for HLT system");