]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliRunDigitizer.cxx
Replacing Header with Id
[u/mrichter/AliRoot.git] / STEER / AliRunDigitizer.cxx
index 4aef248481b69f9ab7aabe69f442ea2f4dae99bf..f263d0c317ee597c8abf2598b965c90dc93a324a 100644 (file)
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/
 
-/*
-$Log$
-Revision 1.2  2001/07/28 10:44:32  hristov
-Loop variable declared once; typos corrected
-
-Revision 1.1  2001/07/27 12:59:00  jchudoba
-Manager class for merging/digitization
-
-*/
+/* $Id$ */
 
 ////////////////////////////////////////////////////////////////////////
 //
@@ -33,331 +25,361 @@ Manager class for merging/digitization
 // Sdigits into Digits. 
 //
 // Only one instance of this class is created in the macro:
-//   AliRunDigitizer * manager = new AliRunDigitizer();
+//   AliRunDigitizer * manager = 
+//      new AliRunDigitizer(nInputStreams,SPERB);
+// where nInputStreams is number of input streams and SPERB is
+// signals per background variable, which determines how combinations
+// of signal and background events are generated.
 // Then instances of specific detector digitizers are created:
 //   AliMUONDigitizer *dMUON  = new AliMUONDigitizer(manager)
-// and the manager is configured (you have to specify input files 
-// and an output file). The manager generates a combination of input 
-// events according to an option set by SetCombinationType. Then it
-// connects appropriate trees from the input files, creates TreeD 
-// in the output and runs once per event Digitize method of all existing 
-// AliDetDigitizers (without any option). AliDetDigitizers ask manager
-// for a TTree with input (manager->GetNextTreeH(TTree *) 
-// or manager->GetNextTreeS(TTree *),
+// and the I/O configured (you have to specify input files 
+// and an output file). The manager connects appropriate trees from 
+// the input files according a combination returned by AliMergeCombi 
+// class. It creates TreeD in the output and runs once per 
+// event Digitize method of all existing AliDetDigitizers 
+// (without any option). AliDetDigitizers ask manager
+// for a TTree with input (manager->GetInputTreeS(Int_t i),
 // merge all inputs, digitize it, and save it in the TreeD 
 // obtained by manager->GetTreeD(). Output events are stored with 
 // numbers from 0, this default can be changed by 
 // manager->SetFirstOutputEventNr(Int_t) method. The particle numbers
 // in the output are shifted by MASK, which is taken from manager.
 //
-// Single input file is permitted. Maximum MAXFILESTOMERGE can be merged.
+// The default output is to the signal file (stream 0). This can be 
+// changed with the SetOutputFile(TString fn)  method.
+//
+// Single input file is permitted. Maximum kMaxStreamsToMerge can be merged.
 // Input from the memory (on-the-fly merging) is not yet 
 // supported, as well as access to the input data by invoking methods
 // on the output data.
 //
-// Access to the geometrical data is via gAlice for now (supposing the 
-// same geometry in all input files), gAlice is taken from the defined 
-// input file.
+// Access to the some data is via gAlice for now (supposing the 
+// same geometry in all input files), gAlice is taken from the first 
+// input file on the first stream.
 //
-// Example with MUON digitizer:
+// Example with MUON digitizer, no merging, just digitization
 //
-//   AliRunDigitizer * manager = new AliRunDigitizer();
-//   manager->SetInput("1track_10events_phi45_60.root");
-//   manager->SetInput("1track_10events_phi120_135.root");
-//   manager->SetOutputDir("/home/z2/jchudoba/batch/jobtmp");
-//   manager->SetOutputFile("digits.root");
-//   AliMUONDigitizer *dMUON  = new AliMUONDigitizer(manager);
-//   manager->SetNrOfEventsToWrite(3);
-//   manager->SetCopyTreesFromInput(1);
-//   manager->Digitize();
+//  AliRunDigitizer * manager = new AliRunDigitizer(1,1);
+//  manager->SetInputStream(0,"galice.root");
+//  AliMUONDigitizer *dMUON  = new AliMUONDigitizer(manager);
+//  manager->Exec("");
+//
+// Example with MUON digitizer, merge all events from 
+//   galice.root (signal) file with events from bgr.root 
+//   (background) file. Number of merged events is
+//   min(number of events in galice.root, number of events in bgr.root)
+//
+//  AliRunDigitizer * manager = new AliRunDigitizer(2,1);
+//  manager->SetInputStream(0,"galice.root");
+//  manager->SetInputStream(1,"bgr.root");
+//  AliMUONDigitizer *dMUON  = new AliMUONDigitizer(manager);
+//  manager->Exec("");
+//
+// Example with MUON digitizer, save digits in a new file digits.root,
+//   process only 1 event
+//
+//  AliRunDigitizer * manager = new AliRunDigitizer(2,1);
+//  manager->SetInputStream(0,"galice.root");
+//  manager->SetInputStream(1,"bgr.root");
+//  manager->SetOutputFile("digits.root");
+//  AliMUONDigitizer *dMUON  = new AliMUONDigitizer(manager);
+//  manager->SetNrOfEventsToWrite(1);
+//  manager->Exec("");
 //
 //////////////////////////////////////////////////////////////////////// 
 
 // system includes
 
-#include <iostream.h>
+#include <Riostream.h>
 
 // ROOT includes
 
 #include "TFile.h"
+#include "TList.h"
 #include "TTree.h"
 
 // AliROOT includes
 
-#include "AliRunDigitizer.h"
 #include "AliDigitizer.h"
+#include "AliMergeCombi.h"
 #include "AliRun.h"
-#include "AliHeader.h"
-#include "TParticle.h"
+#include "AliRunDigitizer.h"
+#include "AliStream.h"
 
 ClassImp(AliRunDigitizer)
 
-////////////////////////////////////////////////////////////////////////
+//_______________________________________________________________________
+AliRunDigitizer::AliRunDigitizer():
+  fkMASKSTEP(0),
+  fOutputFileName(0),
+  fOutputDirName(0),
+  fOutput(0),
+  fEvent(0),
+  fNrOfEventsToWrite(0),
+  fNrOfEventsWritten(0),
+  fCopyTreesFromInput(0),
+  fTreeD(0),
+  fTreeDTPC(0),
+  fTreeDTRD(0),
+  fTreeR(0),
+  fNinputs(0),
+  fNinputsGiven(0),
+  fInputStreams(0),
+  fTreeDTPCBaseName(0),
+  fTreeTPCSBaseName(0),
+  fCombi(0),
+  fCombination(0),
+  fCombinationFileName(0),
+  fDebug(0)
+{
+  //
+  // default ctor, where no new objects can be created
+  // do not use this ctor, it is supplied only for root needs
+  //
+  for (Int_t i=0;i<kMaxStreamsToMerge;i++) {
+    fArrayTreeS[i]=fArrayTreeH[i]=fArrayTreeTPCS[i]=fArrayTreeTRDS[i]=NULL;
+    fInputFiles[i]=0;
+  }
+}
 
-  AliRunDigitizer::AliRunDigitizer() : TNamed("AliRunDigitizer","")
+//_______________________________________________________________________
+AliRunDigitizer::AliRunDigitizer(const AliRunDigitizer& dig):
+  TTask(dig),
+  fkMASKSTEP(0),
+  fOutputFileName(0),
+  fOutputDirName(0),
+  fOutput(0),
+  fEvent(0),
+  fNrOfEventsToWrite(0),
+  fNrOfEventsWritten(0),
+  fCopyTreesFromInput(0),
+  fTreeD(0),
+  fTreeDTPC(0),
+  fTreeDTRD(0),
+  fTreeR(0),
+  fNinputs(0),
+  fNinputsGiven(0),
+  fInputStreams(0),
+  fTreeDTPCBaseName(0),
+  fTreeTPCSBaseName(0),
+  fCombi(0),
+  fCombination(0),
+  fCombinationFileName(0),
+  fDebug(0)
 {
-// default ctor
+  //
+  // Copy ctor
+  //
+  dig.Copy(*this);
+}
 
-  Int_t i;
+//_______________________________________________________________________
+void AliRunDigitizer::Copy(AliRunDigitizer&) const
+{
+  Fatal("Copy","Not installed\n");
+}
 
-  for (i=0;i<MAXDETECTORS;i++) fDigitizers[i]=0;
-  fNDigitizers = 0;
-  fNinputs = 0;
-  fOutputFileName = "digits.root";
-  fOutputDirName = "/tmp/";
-  fCombination.Set(MAXFILESTOMERGE);
-  for (i=0;i<MAXFILESTOMERGE;i++) {
-    fArrayTreeS[i]=fArrayTreeH[i]=fArrayTreeTPCS[i]=NULL;
+
+//_______________________________________________________________________
+AliRunDigitizer::AliRunDigitizer(Int_t nInputStreams, Int_t sperb):
+  TTask("AliRunDigitizer","The manager for Merging"),
+  fkMASKSTEP(10000000),
+  fOutputFileName(""),
+  fOutputDirName("."),
+  fOutput(0),
+  fEvent(0),
+  fNrOfEventsToWrite(-1),
+  fNrOfEventsWritten(0),
+  fCopyTreesFromInput(-1),
+  fTreeD(0),
+  fTreeDTPC(0),
+  fTreeDTRD(0),
+  fTreeR(0),
+  fNinputs(nInputStreams),
+  fNinputsGiven(0),
+  fInputStreams(new TClonesArray("AliStream",nInputStreams)),
+  fTreeDTPCBaseName("TreeD_75x40_100x60_150x60_"),
+  fTreeTPCSBaseName("TreeS_75x40_100x60_150x60_"),
+  fCombi(new AliMergeCombi(nInputStreams,sperb)),
+  fCombination(kMaxStreamsToMerge),
+  fCombinationFileName(0),
+  fDebug(0)
+{
+  //
+  // ctor which should be used to create a manager for merging/digitization
+  //
+  if (nInputStreams == 0) {
+    Error("AliRunDigitizer","Specify nr of input streams");
+    return;
+  }
+  for (Int_t i=0;i<kMaxStreamsToMerge;i++) {
+    fArrayTreeS[i]=fArrayTreeH[i]=fArrayTreeTPCS[i]=fArrayTreeTRDS[i]=NULL;
     fCombination[i]=-1;
   }
-  fkMASKSTEP = 10000000;
   fkMASK[0] = 0;
-  for (i=1;i<MAXFILESTOMERGE;i++) {
+  for (Int_t i=1;i<kMaxStreamsToMerge;i++) {
     fkMASK[i] = fkMASK[i-1] + fkMASKSTEP;
   }
-  fInputFileNames = new TClonesArray("TObjString",1);
-  fInputFiles = new TClonesArray("TFile",1);
-  fMinNEvents = 99999999;
-  fCombinationType=1;
-  fCombinationFileName = "combination.txt";
-  fOutput = 0;
-  fEvent = 0;
-  fNrOfEventsToWrite = 0;
-  fNrOfEventsWritten = 0;
-  fCopyTreesFromInput = -1;
-  fDebug = 3;
-  if (GetDebug()>2) 
-    cerr<<"AliRunDigitizer::AliRunDigitizer() called"<<endl;
-}
 
-////////////////////////////////////////////////////////////////////////
+  TClonesArray &lInputStreams = *fInputStreams;
+// the first Input is open RW to be output as well
+  new(lInputStreams[0]) AliStream("UPDATE");
+  for (Int_t i=1;i<nInputStreams;i++) {
+    new(lInputStreams[i]) AliStream("READ");
+  }
+
+  for (Int_t i=0; i<kMaxStreamsToMerge; i++) fInputFiles[i]=0;
+}
 
+//_______________________________________________________________________
 AliRunDigitizer::~AliRunDigitizer() {
 // dtor
 
-  if (fInputFiles) delete fInputFiles;
-  if (fInputFileNames) delete fInputFileNames;
+// do not delete subtasks, let the creator delete them
+  if (GetListOfTasks()) 
+    GetListOfTasks()->Clear("nodelete");
+  
+    delete fInputStreams;
+    delete fCombi;
 }
 
-////////////////////////////////////////////////////////////////////////
+//_______________________________________________________________________
 void AliRunDigitizer::AddDigitizer(AliDigitizer *digitizer)
 {
 // add digitizer to the list of active digitizers
-
-  if (fNDigitizers >= MAXDETECTORS) {
-    cerr<<"Too many detectors to digitize. Increase value of MAXDETECTORS"
-       <<" constant in AliRunDigitizer.h and recompile or decrease the"
-       <<" the number of detectors"<<endl;
-  } else {
-    fDigitizers[fNDigitizers++] = digitizer;
-  }
+  this->Add(digitizer);
 }
 
-////////////////////////////////////////////////////////////////////////
-
-Bool_t AliRunDigitizer::SetInput(char *inputFile)
+//_______________________________________________________________________
+void AliRunDigitizer::SetInputStream(Int_t i, const char *inputFile)
 {
-// receives the name of the input file. Opens it and stores pointer 
-// to it, returns kFALSE if fails
-// if inputFile = MEMORY, uses pointers from gAlice - not yet implemented
-
-// input cannot be output - open READ only
-  TFile *file = new((*fInputFiles)[fNinputs]) TFile(inputFile,"READ"); 
-
-  if (GetDebug()>2) cerr<<"AliRunDigitizer::SetInput: file = "<<file<<endl;
-  if (!file->IsOpen()) {
-    cerr<<"ERROR: AliRunDigitizer::SetInput: cannot open file "
-       <<inputFile<<endl;
-    return kFALSE;
-  }
-
-// find Header and get nr of events there
-  TTree * te = (TTree *) file->Get("TE") ;
-  if (!te) {
-    cerr<<"ERROR: AliRunDigitizer::SetInput:  input file does "
-       <<"not contain TE"<<endl;
-    return kFALSE;
-  }
-  Int_t nEntries = (Int_t) te->GetEntries();
-
-  if (GetDebug()>2) cerr<<"AliRunDigitizer::SetInput: nEntries = "
-                       <<nEntries<<endl;
-  if (nEntries < 1) {
-    cerr<<"ERROR: AliRunDigitizer::SetInput:  input file does "
-       <<"not contain any event"<<endl;
-    return kFALSE;
-  }
-
-  if (nEntries < fMinNEvents) fNrOfEventsToWrite = fMinNEvents = nEntries;
-
-// find gAlice object if it is a first input file
-//  this is only temporary solution, we need gAlice to access detector
-//  geometry parameters. Unfortunately I have to include AliRun header file.
-  if (fNinputs == 0) {
-    gAlice = (AliRun*)file->Get("gAlice");
-    if (GetDebug() > 2) cerr<<"gAlice taken from the first input: "
-                           <<gAlice<<endl;
-    if (!gAlice) {
-      cerr<<"ERROR: AliRunDigitizer::SetInput:  first input file "
-         <<"does not contain gAlice object"<<endl;
-      return kFALSE;
-    }
-  }
-    
-// store this file name if it is OK
-  new((*fInputFileNames)[fNinputs])  TObjString(inputFile);
-  fNinputs++;
-  if (GetDebug() > 2) cerr<<"fNinputs = "<<fNinputs<<endl;
-  return kTRUE;
-}
-
-////////////////////////////////////////////////////////////////////////
-Bool_t AliRunDigitizer::MakeCombination()
-{
-// make a new combination of events from different files
-
-  Int_t type = fCombinationType;
-  if (fNrOfEventsWritten >= fNrOfEventsToWrite) return kFALSE;
-
-  switch (type) {
-       
-  case 1:
-// type = 1:  1-1-1 - take the same event number from each file
-    if (fCombination[0]<fMinNEvents-1) {       
-      for (Int_t i=0;i<fNinputs;i++) fCombination[i]++;
-      return kTRUE;
-    }
-    if (GetDebug()>2)
-      cerr<<"AliRunDigitizer::MakeCombination: Warning: "
-         <<"maximum number of Events in an input file "
-         <<"was reached."<<endl;
-    break;
-
-  case 2:
-// type = 2: read from the file combinations.ascii
-//  not yet implemented 100% correctly - requires 4 entries in the row
-    static FILE *fp ;
-    static Int_t linesRead;
-    if (!fp) {
-      fp = fopen(fCombinationFileName.Data(),"r");
-      linesRead = 0;
-    }
-    if (!fp) {
-      cerr<<"AliRunDigitizer::MakeCombination ERROR: "
-         <<"Cannot open input file with combinations."<<endl;
-      return kFALSE;
-    }
-    Int_t var[4], nInputs;
-    char line[80];
-// since I do not close or rewind the file, the position should be correct
-    if (fgets(line,80,fp)) {
-      nInputs = sscanf(&line[0],"%d%d%d%d",&var[0],&var[1],&var[2],&var[3]);
-      if (nInputs != fNinputs) {
-       cerr<<"AliRunDigitizer::MakeCombination ERROR: "
-           <<"Nr. of input files is different from nr "
-           <<"integers defining the combination"<<endl;
-       return kFALSE;
-      }
-      while(nInputs--) {
-       fCombination[nInputs] = var[nInputs];
-      }
-      return kTRUE;
-    } else {
-      cerr<<"AliRunDigitizer::MakeCombination ERROR: "
-         <<"no more input in the file with combinations"<<endl;
-      return kFALSE;
-    }
-
-  default:
-    cerr<<"AliRunDigitizer::MakeCombination: ERROR: "
-       <<"wrong type of required combination type: "<<type<<endl;
-  }
-  return kFALSE;
-}
-
-////////////////////////////////////////////////////////////////////////
-void AliRunDigitizer::PrintCombination()
-{
-// debug method to print current combination
-
-  cerr<<"AliRunDigitizer::PrintCombination: Current events combination:"<<endl;
-  for (Int_t i=0;i<fNinputs;i++) {
-    cerr<<"File: "<<((TObjString *)fInputFileNames->At(i))->GetString()<<"\tEvent: "<<fCombination[i]<<endl;
+  //
+  // Sets the name of the input file
+  //
+  if (i > fInputStreams->GetLast()) {
+    Error("SetInputStream","Input stream number too high");
+    return;
   }
+  static_cast<AliStream*>(fInputStreams->At(i))->AddFile(inputFile);
 }
 
-////////////////////////////////////////////////////////////////////////
-void AliRunDigitizer::Digitize()
+//_______________________________________________________________________
+void AliRunDigitizer::Digitize(Option_t* option)
 {
 // get a new combination of inputs, connect input trees and loop 
 // over all digitizers
 
+// take gAlice from the first input file. It is needed to access
+//  geometry data
+// If gAlice is already in memory, use it
+  if (!gAlice) {
+    if (!static_cast<AliStream*>(fInputStreams->At(0))->ImportgAlice()) {
+      cerr<<"gAlice object not found in the first file of "
+         <<"the 1st stream"<<endl;
+      return;
+    }
+  }
   if (!InitGlobal()) {
     cerr<<"False from InitGlobal"<<endl;
     return;
   }
-// take gAlice from the first input file. It is needed to access
-//  geometry data
-  while (MakeCombination()) {
-    if (GetDebug()>2) PrintCombination();
-    ConnectInputTrees();
-    InitPerEvent();
+  Int_t eventsCreated = 0;
+// loop until there is anything on the input in case fNrOfEventsToWrite < 0
+  while ((eventsCreated++ < fNrOfEventsToWrite) || (fNrOfEventsToWrite < 0)) {
+    if (!ConnectInputTrees()) break;
+    InitEvent();
 // loop over all registered digitizers and let them do the work
-    for (Int_t i=0;i<fNDigitizers; i++) {
-      fDigitizers[i]->Digitize();
-    }
-    FinishPerEvent();
+    ExecuteTasks(option);
+    CleanTasks();
+    FinishEvent();
   }
   FinishGlobal();
 }
 
-////////////////////////////////////////////////////////////////////////
-void AliRunDigitizer::ConnectInputTrees()
+//_______________________________________________________________________
+Bool_t AliRunDigitizer::ConnectInputTrees()
 {
 // fill arrays fArrayTreeS, fArrayTreeH and fArrayTreeTPCS with 
 // pointers to the correct events according fCombination values
 // null pointers can be in the output, AliDigitizer has to check it
 
-  TFile *file;
   TTree *tree;
-  char treeName[20];
+  char treeName[50];
+  Int_t serialNr;
+  Int_t eventNr[kMaxStreamsToMerge], delta[kMaxStreamsToMerge];
+  fCombi->Combination(eventNr, delta);
   for (Int_t i=0;i<fNinputs;i++) {
-    file = (TFile*)(*fInputFiles)[i];
-    sprintf(treeName,"TreeS%d",fCombination[i]);
-    tree = (TTree *) file->Get(treeName);
-    fArrayTreeS[i] = tree;
-    sprintf(treeName,"TreeH%d",fCombination[i]);
-    tree = (TTree *) file->Get(treeName);
-    fArrayTreeH[i] = tree;
-    sprintf(treeName,"TreeD_75x40_100x60_%d",fCombination[i]);
-    tree = (TTree *) file->Get(treeName);
-    fArrayTreeTPCS[i] = tree;
-   }
+    if (delta[i] == 1) {
+      AliStream *iStream = static_cast<AliStream*>(fInputStreams->At(i));
+      if (!iStream->NextEventInStream(serialNr)) return kFALSE;
+      fInputFiles[i]=iStream->CurrentFile();
+      sprintf(treeName,"TreeS%d",serialNr);
+      tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
+      if (fArrayTreeS[i]) {
+       delete fArrayTreeS[i];
+       fArrayTreeS[i] = 0;
+      }
+      fArrayTreeS[i] = tree;
+      sprintf(treeName,"TreeH%d",serialNr);
+      tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
+      if (fArrayTreeH[i]) {
+       delete fArrayTreeH[i];
+       fArrayTreeH[i] = 0;
+      }
+      fArrayTreeH[i] = tree;
+      sprintf(treeName,"%s%d",fTreeTPCSBaseName,serialNr);
+      tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
+      if (fArrayTreeTPCS[i]) {
+       delete fArrayTreeTPCS[i];
+       fArrayTreeTPCS[i] = 0;
+      }
+      fArrayTreeTPCS[i] = tree;
+      sprintf(treeName,"TreeS%d_TRD",serialNr);
+      tree = static_cast<TTree*>(iStream->CurrentFile()->Get(treeName));
+      if (fArrayTreeTRDS[i]) {
+       delete fArrayTreeTRDS[i];
+       fArrayTreeTRDS[i] = 0;
+      }
+      fArrayTreeTRDS[i] = tree;
+    } else if (delta[i] != 0) {
+      Error("ConnectInputTrees","Only delta 0 or 1 is implemented");
+      return kFALSE;
+    }
+  }
+  return kTRUE;
 }
 
-////////////////////////////////////////////////////////////////////////
+//_______________________________________________________________________
 Bool_t AliRunDigitizer::InitGlobal()
 {
 // called once before Digitize() is called, initialize digitizers and output
 
-  if (!InitOutputGlobal()) return kFALSE;
-  for (Int_t i=0;i<fNDigitizers; i++) {
-    if (!fDigitizers[i]->Init()) return kFALSE;
-  }
+  TList* subTasks = GetListOfTasks();
+  if (subTasks) {
+    subTasks->ForEach(AliDigitizer,Init)();
+  }  
   return kTRUE;
 }
 
-////////////////////////////////////////////////////////////////////////
+//_______________________________________________________________________
+void AliRunDigitizer::SetOutputFile(TString fn)
+{
+  // the output will be to separate file, not to the signal file
+  fOutputFileName = fn;
+  (static_cast<AliStream*>(fInputStreams->At(0)))->ChangeMode("READ");
+  InitOutputGlobal();
+}
+
+//_______________________________________________________________________
 Bool_t AliRunDigitizer::InitOutputGlobal()
 {
-// Creates the output file, called once by InitGlobal()
+// Creates the output file, called by InitEvent()
 
   TString fn;
   fn = fOutputDirName + '/' + fOutputFileName;
-  fOutput = new TFile(fn,"recreate");
+  fOutput = new TFile(fn,"update");
   if (GetDebug()>2) {
-    cerr<<"file "<<fn.Data()<<" was opened"<<endl;
-    cerr<<"fOutput = "<<fOutput<<endl;
+    cerr<<"AliRunDigitizer::InitOutputGlobal(): file "<<fn.Data()<<" was opened"<<endl;
   }
   if (fOutput) return kTRUE;
   Error("InitOutputGlobal","Could not create output file.");
@@ -365,92 +387,68 @@ Bool_t AliRunDigitizer::InitOutputGlobal()
 }
 
 
-////////////////////////////////////////////////////////////////////////
-void AliRunDigitizer::InitPerEvent()
+//_______________________________________________________________________
+void AliRunDigitizer::InitEvent()
 {
 // Creates TreeDxx in the output file, called from Digitize() once for 
 //  each event. xx = fEvent
 
   if (GetDebug()>2) 
-    cerr<<"AliRunDigitizer::InitPerEvent: fEvent = "<<fEvent<<endl;
-  fOutput->cd();
-  char hname[30];
-  sprintf(hname,"TreeD%d",fEvent);
-  fTreeD = new TTree(hname,"Digits");
-//  fTreeD->Write();   // Do I have to write it here???
-}
+    cerr<<"AliRunDigitizer::InitEvent: fEvent = "<<fEvent<<endl;
 
-
-////////////////////////////////////////////////////////////////////////
-TTree* AliRunDigitizer::GetNextTreeH(TTree *current) const
-{
-// returns next one after the current one
-// returns the first if the current is NULL
-// returns NULL if the current is the last one
-
-  if (fNinputs <= 0) return 0;
-  if (current == 0) return fArrayTreeH[0];
-  for (Int_t i=0; i<fNinputs-1; i++) {
-    if (current == fArrayTreeH[i]) return fArrayTreeH[i+1];
+// if fOutputFileName was not given, write output to signal file
+  if (fOutputFileName == "") {
+    fOutput = (static_cast<AliStream*>(fInputStreams->At(0)))->CurrentFile();
   }
-  return 0;
-}
-////////////////////////////////////////////////////////////////////////
-TTree* AliRunDigitizer::GetNextTreeS(TTree *current) const
-{
-// returns next one after the current one
-// returns the first if the current is NULL
-// returns NULL if the current is the last one
-
-  if (fNinputs <= 0) return 0;
-  if (current == 0) return fArrayTreeS[0];
-  for (Int_t i=0; i<fNinputs-1; i++) {
-    if (current == fArrayTreeS[i]) return fArrayTreeS[i+1];
+  fOutput->cd();
+  char treeName[30];
+  sprintf(treeName,"TreeD%d",fEvent);
+  fTreeD = static_cast<TTree*>(fOutput->Get(treeName));
+  if (!fTreeD) {
+    fTreeD = new TTree(treeName,"Digits");
+    fTreeD->Write(0,TObject::kOverwrite);
   }
-  return 0;
-}
-////////////////////////////////////////////////////////////////////////
-TTree* AliRunDigitizer::GetNextTreeTPCS(TTree *current) const
-{
-// returns next one after the current one
-// returns the first if the current is NULL
-// returns NULL if the current is the last one
 
-  if (fNinputs <= 0) return 0;
-  if (current == 0) return fArrayTreeTPCS[0];
-  for (Int_t i=0; i<fNinputs-1; i++) {
-    if (current == fArrayTreeTPCS[i]) return fArrayTreeTPCS[i+1];
+// tree for ITS fast points
+  sprintf(treeName,"TreeR%d",fEvent);
+  fTreeR = static_cast<TTree*>(fOutput->Get(treeName));
+  if (!fTreeR) {
+    fTreeR = new TTree(treeName,"Reconstruction");
+    fTreeR->Write(0,TObject::kOverwrite);
   }
-  return 0;
-}
 
-////////////////////////////////////////////////////////////////////////
-Int_t AliRunDigitizer::GetNextMask(Int_t current) const
-{
-// returns next one after the current one
-// returns the first if the current is negative
-// returns negative if the current is the last one
+// special tree for TPC
+  sprintf(treeName,"%s%d",fTreeDTPCBaseName,fEvent);
+  fTreeDTPC = static_cast<TTree*>(fOutput->Get(treeName));
+  if (!fTreeDTPC) {
+    fTreeDTPC = new TTree(treeName,"TPC_Digits");
+    fTreeDTPC->Write(0,TObject::kOverwrite);
+  }
 
-  if (fNinputs <= 0) return -1;
-  if (current < 0) return fkMASK[0]; 
-  for (Int_t i=0; i<fNinputs-1; i++) {
-    if (current == fkMASK[i]) return fkMASK[i+1];
+// special tree for TRD
+  sprintf(treeName,"TreeD%d_TRD",fEvent);
+  fTreeDTRD = static_cast<TTree*>(fOutput->Get(treeName));
+  if (!fTreeDTRD) {
+    fTreeDTRD = new TTree(treeName,"TRD_Digits");
+    fTreeDTRD->Write(0,TObject::kOverwrite);
   }
-  return -1;
+
 }
-////////////////////////////////////////////////////////////////////////
-void AliRunDigitizer::FinishPerEvent()
+
+//_______________________________________________________________________
+void AliRunDigitizer::FinishEvent()
 {
 // called at the end of loop over digitizers
 
+  Int_t i;
   fOutput->cd();
   if (fCopyTreesFromInput > -1) {
     char treeName[20];
-    Int_t i = fCopyTreesFromInput; 
+    i = fCopyTreesFromInput; 
     sprintf(treeName,"TreeK%d",fCombination[i]);
-    ((TFile*)fInputFiles->At(i))->Get(treeName)->Clone()->Write();
+    fInputFiles[i]->Get(treeName)->Clone()->Write();
     sprintf(treeName,"TreeH%d",fCombination[i]);
-    ((TFile*)fInputFiles->At(i))->Get(treeName)->Clone()->Write();
+    fInputFiles[i]->Get(treeName)->Clone()->Write();
   }
   fEvent++;
   fNrOfEventsWritten++;
@@ -458,26 +456,38 @@ void AliRunDigitizer::FinishPerEvent()
     delete fTreeD;
     fTreeD = 0;
   }
+  if (fTreeR) {
+    delete fTreeR;
+    fTreeR = 0;
+  }
+  if (fTreeDTPC) {
+    delete fTreeDTPC;
+    fTreeDTPC = 0;
+  }
+  if (fTreeDTRD) {
+    delete fTreeDTRD;
+    fTreeDTRD = 0;
+  }
 }
-////////////////////////////////////////////////////////////////////////
+
+//_______________________________________________________________________
 void AliRunDigitizer::FinishGlobal()
 {
 // called at the end of Exec
 // save unique objects to the output file
 
   fOutput->cd();
-  this->Write();
+  this->Write(0,TObject::kOverwrite);
   if (fCopyTreesFromInput > -1) {
-    ((TFile*)fInputFiles->At(fCopyTreesFromInput))->Get("TE")
-      ->Clone()->Write();
+    fInputFiles[fCopyTreesFromInput]->Get("TE")->Clone()->Write();
     gAlice->Write();
   }
-  fOutput->Close();
+  fOutput->Write();
 }
 
 
-////////////////////////////////////////////////////////////////////////
-Int_t  AliRunDigitizer::GetNParticles(Int_t event)
+//_______________________________________________________________________
+Int_t  AliRunDigitizer::GetNParticles(Int_t event) const
 {
 // return number of particles in all input files for a given
 // event (as numbered in the output file)
@@ -493,13 +503,18 @@ Int_t  AliRunDigitizer::GetNParticles(Int_t event)
   return sum;
 }
 
-////////////////////////////////////////////////////////////////////////
-Int_t  AliRunDigitizer::GetNParticles(Int_t event, Int_t input)
+//_______________________________________________________________________
+Int_t  AliRunDigitizer::GetNParticles(Int_t /* event */, Int_t /* input */) const
 {
 // return number of particles in input file input for a given
 // event (as numbered in this input file)
 // return -1 if some error
 
+// Must be revised in the version with AliStream
+
+  return -1;
+
+/*
   TFile *file = ConnectInputFile(input);
   if (!file) {
     Error("GetNParticles","Cannot open input file");
@@ -524,23 +539,25 @@ Int_t  AliRunDigitizer::GetNParticles(Int_t event, Int_t input)
     cerr<<"Nsecondary: "<<header->GetNsecondary()<<endl;
   }
   return header->GetNprimary() + header->GetNsecondary();
+*/
 }
 
-////////////////////////////////////////////////////////////////////////
-Int_t* AliRunDigitizer::GetInputEventNumbers(Int_t event)
+//_______________________________________________________________________
+Int_t* AliRunDigitizer::GetInputEventNumbers(Int_t event) const
 {
 // return pointer to an int array with input event numbers which were
 // merged in the output event event
 
 // simplified for now, implement later
-  Int_t a[MAXFILESTOMERGE];
+  Int_t * a = new Int_t[kMaxStreamsToMerge];
   for (Int_t i = 0; i < fNinputs; i++) {
     a[i] = event;
   }
   return a;
 }
-////////////////////////////////////////////////////////////////////////
-Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t input)
+
+//_______________________________________________________________________
+Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t /* input */) const
 {
 // return an event number of an eventInput from input file input
 // which was merged to create output event event
@@ -548,36 +565,9 @@ Int_t AliRunDigitizer::GetInputEventNumber(Int_t event, Int_t input)
 // simplified for now, implement later
   return event;
 }
-////////////////////////////////////////////////////////////////////////
-TFile* AliRunDigitizer::ConnectInputFile(Int_t input)
-{
-// open input file with index input
-// 1st file has index 0
-// return 0x0 if fails
 
-// check if file with index input is already open
-  TFile *file = 0;
-  if (fInputFiles->GetEntriesFast() > input)
-    file = static_cast<TFile *>(fInputFiles->At(input));
-
-  if (!file) {
-    // find the file name and open it
-    TObjString *fn = static_cast<TObjString *>(fInputFileNames->At(input));
-    file = new((*fInputFiles)[input]) TFile((fn->GetString()).Data(),"READ");
-    if (!file) {
-      Error("ConnectInputFile","Cannot open input file");
-      return 0;
-    }
-    if (!file->IsOpen()) {
-      Error("ConnectInputFile","Cannot open input file");
-      return 0;
-    }
-  }
-  return file;
-}
-
-////////////////////////////////////////////////////////////////////////
-TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event)
+//_______________________________________________________________________
+TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event) const
 {
 // return pointer to particle with index i (index with mask)
 
@@ -586,14 +576,19 @@ TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t event)
   return GetParticle(i,input,GetInputEventNumber(event,input));
 }
 
-////////////////////////////////////////////////////////////////////////
-TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t input, Int_t event)
+//_______________________________________________________________________
+TParticle* AliRunDigitizer::GetParticle(Int_t /* i */, Int_t /* input */, 
+                                        Int_t /* event */) const
 {
 // return pointer to particle with index i in the input file input
 // (index without mask)
 // event is the event number in the file input
 // return 0 i fit does not exist
 
+// Must be revised in the version with AliStream
+
+  return 0;
+/*
   TFile *file = ConnectInputFile(input);
   if (!file) {
     Error("GetParticle","Cannot open input file");
@@ -634,12 +629,36 @@ TParticle* AliRunDigitizer::GetParticle(Int_t i, Int_t input, Int_t event)
     entry = i+header->GetNsecondary();
   else 
     entry = i-header->GetNprimary();
-//  tK->GetEntry(0);          // do I need this???
   Int_t bytesRead = tK->GetEntry(entry);
 //  new ((*fParticles)[nentries]) TParticle(*fParticleBuffer);
   if (bytesRead)
     return particleBuffer;
   return  0;
+*/
 }
-////////////////////////////////////////////////////////////////////////
 
+//_______________________________________________________________________
+void AliRunDigitizer::ExecuteTask(Option_t* option)
+{
+// overwrite ExecuteTask to do Digitize only
+
+  if (!IsActive()) return;
+  Digitize(option);
+  fHasExecuted = kTRUE;
+  return;
+}
+
+//_______________________________________________________________________
+TString AliRunDigitizer::GetInputFileName(const Int_t input, const Int_t order) const 
+{
+// returns file name of the order-th file in the input stream input
+// returns empty string if such file does not exist
+// first input stream is 0
+// first file in the input stream is 0
+  TString fileName("");
+  if (input >= fNinputs) return fileName;
+  AliStream * stream = static_cast<AliStream*>(fInputStreams->At(input));
+  if (order > stream->GetNInputFiles()) return fileName;
+  fileName = stream->GetFileName(order);
+  return fileName;
+}