these TTask are posted to the apropriate folders //YSAlice/tasks/(S)Digitizer and...
[u/mrichter/AliRoot.git] / PHOS / AliPHOSSDigitizer.cxx
index 9780671a2df3534a48c786c125ead502f053e2b8..b0ca76bc7f195ee587510326dd01c269f7f0ca93 100644 (file)
 /* $Id$ */
 
 //_________________________________________________________________________
-// This is a TTask that constructs SDigits out of Hits
-// A Summable Digits is the sum of all hits in a cell
-// A threshold is applied 
+// This is a TTask that makes SDigits out of Hits
+// A Summable Digits is the sum of all hits originating 
+// from one primary in one active cell
+// A threshold for assignment of the primary to SDigit is applied 
+// SDigits are written to TreeS, branch "PHOS"
+// AliPHOSSDigitizer with all current parameters is written 
+// to TreeS branch "AliPHOSSDigitizer".
+// Both branches have the same title. If necessary one can produce 
+// another set of SDigits with different parameters. Two versions
+// can be distunguished using titles of the branches.
+// User case:
+//  root [0] AliPHOSSDigitizer * s = new AliPHOSSDigitizer("galice.root")
+//  Warning in <TDatabasePDG::TDatabasePDG>: object already instantiated
+//  root [1] s->ExecuteTask()
+//             // Makes SDigitis for all events stored in galice.root
+//  root [2] s->SetPedestalParameter(0.001)
+//             // One can change parameters of digitization
+// root [3] s->SetSDigitsBranch("Pedestal 0.001")
+//             // and write them into the new branch
+// root [4] s->ExecuteTask("deb all tim")
+//             // available parameters:
+//             deb - print # of produced SDigitis
+//             deb all  - print # and list of produced SDigits
+//             tim - print benchmarking information
 //
 //*-- Author :  Dmitri Peressounko (SUBATECH & KI) 
 //////////////////////////////////////////////////////////////////////////////
 
+
 // --- ROOT system ---
+#include "TFile.h"
 #include "TTask.h"
 #include "TTree.h"
 #include "TSystem.h"
+#include "TROOT.h"
+#include "TFolder.h"
+#include "TBenchmark.h"
 // --- Standard library ---
+#include <iomanip.h>
 
 // --- AliRoot header files ---
-
+#include "AliRun.h"
 #include "AliPHOSDigit.h"
 #include "AliPHOSHit.h"
-#include "AliPHOSv1.h"
 #include "AliPHOSSDigitizer.h"
 
-#include "TROOT.h"
-#include "TFolder.h"
 
 ClassImp(AliPHOSSDigitizer)
 
@@ -46,61 +70,88 @@ ClassImp(AliPHOSSDigitizer)
   AliPHOSSDigitizer::AliPHOSSDigitizer():TTask("AliPHOSSDigitizer","") 
 {
   // ctor
-  fA = 0;
-  fB = 10000000. ;
+  fA             = 0;
+  fB             = 10000000.;
   fPrimThreshold = 0.01 ;
-  fNevents = 0 ;     // Number of events to digitize, 0 means all evens in current file
-  // add Task to //root/Tasks folder
-  TTask * roottasks = (TTask*)gROOT->GetRootFolder()->FindObject("Tasks") ; 
-  roottasks->Add(this) ; 
+  fNevents       = 0 ;      
+  fSDigits       = 0 ;
+  fHits          = 0 ;
+  fIsInitialized = kFALSE ;
 
 }
+
 //____________________________________________________________________________ 
-AliPHOSSDigitizer::AliPHOSSDigitizer(char* HeaderFile, char *SDigitsFile):TTask("AliPHOSSDigitizer","")
+AliPHOSSDigitizer::AliPHOSSDigitizer(const char* headerFile, const char *sDigitsTitle):TTask("AliPHOSSDigitizer","")
 {
   // ctor
-  fA = 0;
-  fB = 10000000.;
+  fA             = 0;
+  fB             = 10000000.;
   fPrimThreshold = 0.01 ;
-  fNevents = 0 ;         // Number of events to digitize, 0 means all events in current file
-  fSDigitsFile = SDigitsFile ;
-  fHeadersFile = HeaderFile ;
-  //add Task to //root/Tasks folder
-  TTask * roottasks = (TTask*)gROOT->GetRootFolder()->FindObject("Tasks") ; 
-  roottasks->Add(this) ; 
-    
+  fNevents       = 0 ;      
+  fSDigitsTitle  = sDigitsTitle ;
+  fHeadersFile   = headerFile ;
+  fIsInitialized = kFALSE ;
+
+  Init();
 }
 
 //____________________________________________________________________________ 
-  AliPHOSSDigitizer::~AliPHOSSDigitizer()
+AliPHOSSDigitizer::~AliPHOSSDigitizer()
 {
   // dtor
+  if(fSDigits)
+    delete fSDigits ;
+  if(fHits)
+    delete fHits ;
 }
+//____________________________________________________________________________ 
+void AliPHOSSDigitizer::Init()
+{
+  // Initialization: open root-file, allocate arrays for hits and sdigits,
+  // attach task SDigitizer to the list of PHOS tasks
+  // 
+  // Initialization can not be done in the default constructor
 
+  if(!fIsInitialized){
 
-//____________________________________________________________________________
-void AliPHOSSDigitizer::Exec(Option_t *option) { 
-  //Collects all hits in the same active volume into digit
-
-  TFile * file = 0;
-
-  // if(gAlice->TreeE()==0)        //If gAlice not yet read/constructed
-  if(fHeadersFile.IsNull())
-    file = new TFile("galice.root", "update") ;
-  else
-    file = new TFile(fHeadersFile.Data(),"update") ;
+    if(fHeadersFile.IsNull())
+      fHeadersFile="galice.root" ;
 
-  gAlice = (AliRun *) file->Get("gAlice") ;
-  
-  
+    TFile * file = (TFile*) gROOT->GetFile(fHeadersFile.Data() ) ;
+    
+    //if file was not opened yet, read gAlice
+    if(file == 0){
+      if(fHeadersFile.Contains("rfio"))
+       file =  TFile::Open(fHeadersFile,"update") ;
+      else
+       file = new TFile(fHeadersFile.Data(),"update") ;
+      gAlice = (AliRun *) file->Get("gAlice") ;
+    }
+    
+    fHits    = new TClonesArray("AliPHOSHit",1000);
+    fSDigits = new TClonesArray("AliPHOSDigit",1000);
+    
+    //add Task to //YSAlice/tasks/(S)Diditizer/PHOS
+    TFolder * alice  = (TFolder*)gROOT->GetListOfBrowsables()->FindObject("YSAlice") ; 
+    TTask * aliceSD  = (TTask*)alice->FindObject("tasks/(S)Digitizer") ; 
+    TTask * phosSD   = (TTask*)aliceSD->GetListOfTasks()->FindObject("PHOS") ;
+    phosSD->Add(this) ; 
+    
+    fIsInitialized = kTRUE ;
+  }
+}
+//____________________________________________________________________________
+void AliPHOSSDigitizer::Exec(Option_t *option) 
+{ 
+  // Collects all hits in the same active volume into digit
   
-  TClonesArray * sdigits = new TClonesArray("AliPHOSDigit",1000) ;
+  if(!fIsInitialized)
+    Init() ;
 
-  AliPHOS * PHOS = (AliPHOS *) gAlice->GetDetector("PHOS") ;
+  if(strstr(option,"tim"))
+    gBenchmark->Start("PHOSSDigitizer");
   
-    
-  if(fNevents == 0) 
-    fNevents = (Int_t) gAlice->TreeE()->GetEntries() ; 
+  fNevents = (Int_t) gAlice->TreeE()->GetEntries() ; 
   
   Int_t ievent ;
   for(ievent = 0; ievent < fNevents; ievent++){
@@ -112,111 +163,205 @@ void AliPHOSSDigitizer::Exec(Option_t *option) {
       return ;
     }
     
-    if(gAlice->TreeS() == 0)
-      gAlice->MakeTree("S") ;
-    
-    TClonesArray * hits = PHOS->Hits() ;
+    //set address of the hits 
+    TBranch * branch = gAlice->TreeH()->GetBranch("PHOS");
+    if (branch) 
+      branch->SetAddress(&fHits);
+    else{
+      cout << "ERROR in AliPHOSSDigitizer: "<< endl ;
+      cout << "      no branch PHOS in TreeH"<< endl ;
+      cout << "      do nothing " << endl ;
+      return ;
+    }
     
-    sdigits->Clear();
+    fSDigits->Clear();
     Int_t nSdigits = 0 ;
     
-    //Make branches
-    char branchname[20];
-    sprintf(branchname,"%s",PHOS->GetName());  
-    
-    Int_t bufferSize = 16000 ;
-    char * file =0;
-    if(!fSDigitsFile.IsNull())
-      file = (char*) fSDigitsFile.Data() ; //ievent ;
-    else
-      if(gSystem->Getenv("CONFIG_SPLIT_FILE")){ //generating file name
-       file = new char[30] ;
-       //      sprintf(file,"PHOS.SDigits%d.root",ievent) ;
-       sprintf(file,"PHOS.SDigits.root") ;
-      }
-      else
-       file = 0 ;
-    
-    gAlice->MakeBranchInTree(gAlice->TreeS(),branchname,&sdigits,bufferSize,file);  
-
-
-    Int_t splitlevel = 0 ;
-    sprintf(branchname,"AliPHOSSDigitizer");   
-    AliPHOSSDigitizer * sd = this ;
-    gAlice->MakeBranchInTree(gAlice->TreeS(),branchname,"AliPHOSSDigitizer",&sd, bufferSize, splitlevel,file); 
     
-
-    //Now made SDigits from hits, for PHOS it is the same
-
+    //Now made SDigits from hits, for PHOS it is the same, so just copy    
     Int_t itrack ;
-    for (itrack=0; itrack<gAlice->GetNtrack(); itrack++){
+    for (itrack=0; itrack < gAlice->GetNtrack(); itrack++){
       
-      //=========== Get the Hits Tree for the Primary track itrack
-      gAlice->ResetHits();    
-      gAlice->TreeH()->GetEvent(itrack);
+      //=========== Get the PHOS branch from Hits Tree for the Primary track itrack
+      branch->GetEntry(itrack,0);
       
       Int_t i;
-      for ( i = 0 ; i < hits->GetEntries() ; i++ ) {
-       AliPHOSHit * hit = (AliPHOSHit*)hits->At(i) ;
-       AliPHOSDigit * newdigit ;
+      for ( i = 0 ; i < fHits->GetEntries() ; i++ ) {
+       AliPHOSHit * hit = (AliPHOSHit*)fHits->At(i) ;
 
        // Assign primary number only if contribution is significant
        if( hit->GetEnergy() > fPrimThreshold)
-         newdigit = new AliPHOSDigit( hit->GetPrimary(), hit->GetId(), Digitize( hit->GetEnergy() ) ) ;
+         new((*fSDigits)[nSdigits]) AliPHOSDigit( hit->GetPrimary(), hit->GetId(), Digitize( hit->GetEnergy() ) ) ;
        else
-         newdigit = new AliPHOSDigit( -1               , hit->GetId(), Digitize( hit->GetEnergy() ) ) ;
+         new((*fSDigits)[nSdigits]) AliPHOSDigit( -1               , hit->GetId(), Digitize( hit->GetEnergy() ) ) ;
        
-       new((*sdigits)[nSdigits]) AliPHOSDigit(* newdigit) ;
        nSdigits++ ;  
        
-       delete newdigit ;    
       } 
       
     } // loop over tracks
     
-    sdigits->Sort() ;
+    fSDigits->Sort() ;
     
-    nSdigits = sdigits->GetEntries() ;
-    sdigits->Expand(nSdigits) ;
+    nSdigits = fSDigits->GetEntriesFast() ;
+    fSDigits->Expand(nSdigits) ;
     
     Int_t i ;
     for (i = 0 ; i < nSdigits ; i++) { 
-      AliPHOSDigit * digit = (AliPHOSDigit *) sdigits->At(i) ; 
+      AliPHOSDigit * digit = (AliPHOSDigit *) fSDigits->At(i) ; 
       digit->SetIndexInList(i) ;     
     }
+
+    if(gAlice->TreeS() == 0)
+      gAlice->MakeTree("S") ;
+    
+    //check, if this branch already exits?
+    TBranch * sdigitsBranch = 0;
+    TBranch * sdigitizerBranch = 0;
+    
+    TObjArray * branches = gAlice->TreeS()->GetListOfBranches() ;
+    Int_t ibranch;
+    Bool_t phosNotFound = kTRUE ;
+    Bool_t sdigitizerNotFound = kTRUE ;
+    
+    for(ibranch = 0;ibranch <branches->GetEntries();ibranch++){
+      
+      if(phosNotFound){
+       sdigitsBranch=(TBranch *) branches->At(ibranch) ;
+       if( (strcmp("PHOS",sdigitsBranch->GetName())==0 ) &&
+           (fSDigitsTitle.CompareTo(sdigitsBranch->GetTitle()) == 0) )
+         phosNotFound = kFALSE ;
+      }
+      if(sdigitizerNotFound){
+       sdigitizerBranch = (TBranch *) branches->At(ibranch) ;
+       if( (strcmp(sdigitizerBranch->GetName(),"AliPHOSSDigitizer") == 0)&&
+           (fSDigitsTitle.CompareTo(sdigitizerBranch->GetTitle()) == 0) )
+         sdigitizerNotFound = kFALSE ;
+      }
+    }
+
+    if(!(sdigitizerNotFound && phosNotFound)){
+      cout << "AliPHOSSdigitizer error:" << endl ;
+      cout << "Can not overwrite existing branches: do not write" << endl ;
+      return ;
+    }
     
-    gAlice->TreeS()->Fill() ;
+    //Make (if necessary) branches    
+    char * file =0;
+    if(gSystem->Getenv("CONFIG_SPLIT_FILE")){ //generating file name
+      file = new char[strlen(gAlice->GetBaseFile())+20] ;
+      sprintf(file,"%s/PHOS.SDigits.root",gAlice->GetBaseFile()) ;
+    }
+    
+    TDirectory *cwd = gDirectory;
+    
+    //First list of sdigits
+    Int_t bufferSize = 32000 ;    
+    sdigitsBranch = gAlice->TreeS()->Branch("PHOS",&fSDigits,bufferSize);
+    sdigitsBranch->SetTitle(fSDigitsTitle.Data());
+    if (file) {
+      sdigitsBranch->SetFile(file);
+      TIter next( sdigitsBranch->GetListOfBranches());
+      TBranch * subbr;
+      while ((subbr=(TBranch*)next())) {
+       subbr->SetFile(file);
+      }   
+      cwd->cd();
+    } 
+      
+    //second - SDigitizer
+    Int_t splitlevel = 0 ;
+    AliPHOSSDigitizer * sd = this ;
+    sdigitizerBranch = gAlice->TreeS()->Branch("AliPHOSSDigitizer","AliPHOSSDigitizer",
+                                              &sd,bufferSize,splitlevel); 
+    sdigitizerBranch->SetTitle(fSDigitsTitle.Data());
+    if (file) {
+      sdigitizerBranch->SetFile(file);
+      TIter next( sdigitizerBranch->GetListOfBranches());
+      TBranch * subbr ;
+      while ((subbr=(TBranch*)next())) {
+       subbr->SetFile(file);
+      }   
+      cwd->cd();
+      delete file;
+    }
+
+    sdigitsBranch->Fill() ;
+    sdigitizerBranch->Fill() ;
     gAlice->TreeS()->Write(0,TObject::kOverwrite) ;
+    
+    if(strstr(option,"deb"))
+      PrintSDigits(option) ;
+    
   }
-
-  delete sdigits ;
-  if(file)
-    file->Close() ;
-
+  
+  if(strstr(option,"tim")){
+    gBenchmark->Stop("PHOSSDigitizer");
+    cout << "AliPHOSSDigitizer:" << endl ;
+    cout << "   took " << gBenchmark->GetCpuTime("PHOSSDigitizer") << " seconds for SDigitizing " 
+        <<  gBenchmark->GetCpuTime("PHOSSDigitizer")/fNevents << " seconds per event " << endl ;
+    cout << endl ;
+  }
+  
+  
 }
 //__________________________________________________________________
-void AliPHOSSDigitizer::SetSDigitsFile(char * file ){
-  if(!fSDigitsFile.IsNull())
-    cout << "Changing SDigits file from " <<(char *)fSDigitsFile.Data() << " to " << file << endl ;
-  fSDigitsFile=file ;
+void AliPHOSSDigitizer::SetSDigitsBranch(const char * title )
+{
+  // Setting title to branch SDigits 
+  if(!fSDigitsTitle.IsNull())
+    cout << "AliPHOSSdigitizer: changing SDigits file from " <<fSDigitsTitle.Data() << " to " << title << endl ;
+  fSDigitsTitle=title ;
 }
 //__________________________________________________________________
-void AliPHOSSDigitizer::Print(Option_t* option)const{
+void AliPHOSSDigitizer::Print(Option_t* option)const
+{
+  // Prints parameters of SDigitizer
   cout << "------------------- "<< GetName() << " -------------" << endl ;
-  if(fSDigitsFile.IsNull())
-    cout << " Writing SDigitis to file galice.root "<< endl ;
-  else
-    cout << "    Writing SDigitis to file  " << (char*) fSDigitsFile.Data() << endl ;
-  cout << "   with digitization parameters A = " << fA << endl ;
-  cout << "                                B = " << fB << endl ;
-  cout << "Threshold for Primary assignment  = " << fPrimThreshold << endl ; 
+  cout << "   Writing SDigitis to branch with title  " << fSDigitsTitle.Data() << endl ;
+  cout << "   with digitization parameters  A = " << fA << endl ;
+  cout << "                                 B = " << fB << endl ;
+  cout << "   Threshold for Primary assignment= " << fPrimThreshold << endl ; 
   cout << "---------------------------------------------------"<<endl ;
-
+  
 }
 //__________________________________________________________________
-Bool_t AliPHOSSDigitizer::operator==( AliPHOSSDigitizer const &sd )const{
+Bool_t AliPHOSSDigitizer::operator==( AliPHOSSDigitizer const &sd )const
+{
+  // Equal operator.
+  // SDititizers are equal if their pedestal, slope and threshold are equal
+
   if( (fA==sd.fA)&&(fB==sd.fB)&&(fPrimThreshold==sd.fPrimThreshold))
     return kTRUE ;
   else
     return kFALSE ;
 }
+//__________________________________________________________________
+void AliPHOSSDigitizer::PrintSDigits(Option_t * option)
+{
+  // Prints list of digits produced in the current pass of AliPHOSDigitizer
+  
+  cout << "AliPHOSSDigitizer: " << endl ;
+  cout << "       Number of entries in SDigits list  " << fSDigits->GetEntriesFast() << endl ;
+  cout << endl ;
+  
+  if(strstr(option,"all")){// print all digits
+    
+    //loop over digits
+    AliPHOSDigit * digit;
+    cout << "SDigit Id " << " Amplitude " <<  " Index "  <<  " Nprim " << " Primaries list " <<  endl;    
+    Int_t index ;
+    for (index = 0 ; index < fSDigits->GetEntries() ; index++) {
+      digit = (AliPHOSDigit * )  fSDigits->At(index) ;
+      cout << setw(8)  <<  digit->GetId() << " "  <<   setw(3)  <<  digit->GetAmp() <<   "  "  
+          << setw(6)  <<  digit->GetIndexInList() << "  "   
+          << setw(5)  <<  digit->GetNprimary() <<"  ";
+      
+      Int_t iprimary;
+      for (iprimary=0; iprimary<digit->GetNprimary(); iprimary++)
+       cout << setw(5)  <<  digit->GetPrimary(iprimary+1) << "  ";
+      cout << endl;     
+    }
+    
+  }
+}