]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - FMD/AliFMDReconstructor.cxx
Fixes, and extra debug
[u/mrichter/AliRoot.git] / FMD / AliFMDReconstructor.cxx
index 085c91a37e881db584de8724232cf6c9b0e0555b..6801f5bfee4eab5fa52ae65c5738facfe70187b1 100644 (file)
  * provided "as is" without express or implied warranty.                  *
  **************************************************************************/
 
-//_________________________________________________________________________
-// This is a class that constructs ReconstParticles (reconstructed particles) 
-// out of Digits
+/* $Id$ */
+
+//____________________________________________________________________
+//
+// This is a class that constructs AliFMDMult (reconstructed
+// multiplicity) from of Digits
+//
+// This class reads either digits from a TClonesArray or raw data from
+// a DDL file (or similar), and stores the read ADC counts in an
+// internal cache (fAdcs). 
+//
+// From the cached values it then calculates the number of particles
+// that hit a region of the FMDs, as specified by the user. 
+//
+// The reconstruction can be done in two ways: Either via counting the
+// number of empty strips (Poisson method), or by converting the ADC
+// signal to an energy deposition, and then dividing by the typical
+// energy loss of a particle.
+// 
+//      +---------------------+       +---------------------+
+//      | AliFMDReconstructor |<>-----| AliFMDMultAlgorithm |
+//      +---------------------+       +---------------------+
+//                                               ^
+//                                               |
+//                                   +-----------+---------+
+//                                   |                     |
+//                         +-------------------+   +------------------+
+//                         | AliFMDMultPoisson |   | AliFMDMultNaiive |
+//                         +-------------------+   +------------------+
+//
+// AliFMDReconstructor acts as a manager class.  It contains a list of
+// AliFMDMultAlgorithm objects.  The call graph looks something like 
+//
+//
+//       +----------------------+            +----------------------+
+//       | :AliFMDReconstructor |            | :AliFMDMultAlgorithm |
+//       +----------------------+            +----------------------+
+//                  |                                  |
+//    Reconstruct  +-+                                 |
+//    ------------>| |                         PreRun +-+
+//                 | |------------------------------->| |   
+//                 | |                                +-+
+//                 | |-----+ (for each event)          |
+//                 | |     | *ProcessEvent             |
+//                 |+-+    |                           |
+//                 || |<---+                 PreEvent +-+
+//                 || |------------------------------>| |      
+//                 || |                               +-+
+//                 || |-----+                          |
+//                 || |     | ProcessDigits            |
+//                 ||+-+    |                          |
+//                 ||| |<---+                          |
+//                 ||| |         *ProcessDigit(digit) +-+
+//                 ||| |----------------------------->| |
+//                 ||| |                              +-+
+//                 ||+-+                               |
+//                 || |                     PostEvent +-+
+//                 || |------------------------------>| |
+//                 || |                               +-+
+//                 |+-+                                |
+//                 | |                        PostRun +-+
+//                 | |------------------------------->| |
+//                 | |                                +-+
+//                 +-+                                 |
+//                  |                                  |
+//
+//
 // 
 //-- Authors: Evgeny Karpechev(INR) and Alla Maevsksia
-//////////////////////////////////////////////////////////////////////////////
-
-// --- ROOT system ---
-#include "TTask.h"
-#include "TTree.h"
-#include "TSystem.h"
-#include "TFile.h"
-#include "TROOT.h"
-#include "TFolder.h"
-#include "TH2F.h"
-
-// --- Standard library ---
-#include <stdlib.h>
-#include <Riostream.h>
+//  Latest changes by Christian Holm Christensen <cholm@nbi.dk>
+//
+//
+//____________________________________________________________________
 
-// --- AliRoot header files ---
-
-#include "AliRunLoader.h"
-#include "AliLoader.h"
-
-#include "AliFMDdigit.h"
-#include "AliFMDhit.h"
-#include "AliFMDReconstParticles.h"
-#include "AliFMD.h"
-#include "AliFMDv1.h"
-#include "AliFMDReconstructor.h"
-#include "AliRun.h"
-#include "AliConfig.h"
-#include "AliHeader.h"
-#include "AliGenEventHeader.h"
+#include <AliLog.h>                        // ALILOG_H
+#include <AliRun.h>                        // ALIRUN_H
+#include <AliRunLoader.h>                  // ALIRUNLOADER_H
+#include <AliLoader.h>                     // ALILOADER_H
+#include <AliHeader.h>                     // ALIHEADER_H
+#include <AliRawReader.h>                  // ALIRAWREADER_H
+#include <AliGenEventHeader.h>             // ALIGENEVENTHEADER_H
+#include "AliFMD.h"                       // ALIFMD_H
+#include "AliFMDGeometry.h"                // ALIFMDGEOMETRY_H
+#include "AliFMDParameters.h"              // ALIFMDPARAMETERS_H
+#include "AliFMDDetector.h"                // ALIFMDDETECTOR_H
+#include "AliFMDRing.h"                    // ALIFMDRING_H
+#include "AliFMDDigit.h"                   // ALIFMDDIGIT_H
+#include "AliFMDReconstructor.h"           // ALIFMDRECONSTRUCTOR_H
+#include "AliFMDRawStream.h"               // ALIFMDRAWSTREAM_H
+#include "AliFMDRawReader.h"               // ALIFMDRAWREADER_H
+#include "AliFMDMultAlgorithm.h"          // ALIFMDMULTALGORITHM_H
+#include "AliFMDMultPoisson.h"            // ALIFMDMULTPOISSON_H
+#include "AliFMDMultNaiive.h"             // ALIFMDMULTNAIIVE_H
+#include "AliESD.h"                       // ALIESD_H
 
+//____________________________________________________________________
 ClassImp(AliFMDReconstructor)
-
-        
-//____________________________________________________________________________
-
-void AliFMDReconstructor::Reconstruct(AliRunLoader* runLoader) const
-{ 
- //Collects all digits in the same active volume into number of particles
-  /*
-    Reconstruct number of particles 
-    in given group of pads for given FMDvolume
-    determine by numberOfVolume , 
-    numberOfMinSector,numberOfMaxSector,
-    numberOfMinRing, numberOgMaxRing
-    Reconstructor method choose dependence on number of empty pads  
-  */
-
-
-#ifdef DEBUG
-  Info("Exec ","Start");
+#if 0
+  ; // This is here to keep Emacs for indenting the next line
 #endif
 
-  Int_t const knumVolumes=5;
-  Int_t padADC;
-  Float_t eta, etain,etaout,rad,theta;
-  Int_t ivol, iSector, iRing;
-  Float_t rin[5]={4.2,15.4,4.2,15.4,4.2};
-  Float_t rout[5]={17.4,28.4,17.4,28.4,17.4};
-  Float_t z[5]={-62.8, -75.2, 83.4, 75.2, 340.};
-  Int_t numberOfRings[5]={512,256,512,256,512};
-  Int_t numberOfSectors[5]=  {20,40,20,40,20};
-  Int_t numberOfEtaIntervals[5];
-  // number of ring for boundary 0.1 eta
+//____________________________________________________________________
+AliFMDReconstructor::AliFMDReconstructor() 
+  : AliReconstructor(),
+    fPedestal(0), 
+    fPedestalWidth(0),
+    fPedestalFactor(0)
+{
+  // Make a new FMD reconstructor object - default CTOR.
+  AliFMDParameters* pars = AliFMDParameters::Instance();
+  fPedestal       = pars->GetPedestal();
+  fPedestalWidth  = pars->GetPedestalWidth();
+  fPedestalFactor = pars->GetPedestalFactor();
+  
+  fAlgorithms.Add(new AliFMDMultNaiive);
+  fAlgorithms.Add(new AliFMDMultPoisson);
 
+  TIter next(&fAlgorithms);
+  AliFMDMultAlgorithm* algorithm = 0;
+  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next()))) 
+    algorithm->PreRun(0);
+}
   
-  if (runLoader == 0x0)
-   {
-    Error("Exec","Run Loader loader is NULL - Session not opened");
-    return;
-   }
 
-  AliLoader* plFMD = runLoader->GetLoader("FMDLoader");
-  if (plFMD == 0x0)
-   {
-     Fatal("AliFMDReconstructor","Can not find FMD (loader) in specified event");
-     return;//never reached
-   }
-   
-  if (!runLoader->GetAliRun()) runLoader->LoadgAlice();
-  if (!runLoader->TreeE()) runLoader->LoadHeader();
+//____________________________________________________________________
+AliFMDReconstructor::AliFMDReconstructor(const AliFMDReconstructor& other) 
+  : AliReconstructor(),
+    fPedestal(0), 
+    fPedestalWidth(0),
+    fPedestalFactor(0)
+{
+  // Copy constructor 
+  fPedestal       = other.fPedestal;
+  fPedestalWidth  = other.fPedestalWidth;
+  fPedestalFactor = other.fPedestalFactor;
 
-  TDirectory* cwd = gDirectory;
-  gDirectory = 0x0;
-  Text_t buf1[20];
-  TH2F* hTotal[10];
-  for (Int_t j=1; j<=5; j++){
-    sprintf(buf1,"hTotal%d",j);
-    
-    hTotal[j] = new TH2F(buf1," Number of primary particles ",
-                        numberOfSectors[j-1],1,numberOfSectors[j-1],
-                        numberOfRings[j-1],1,numberOfRings[j-1]);
-  }   
-  gDirectory = cwd;
-  plFMD->LoadRecPoints("RECREATE");
-  Int_t retval=0;     
-  Int_t nevents=Int_t (runLoader->TreeE()->GetEntries()); 
-#ifdef DEBUG
-  cout<<" nevents "<<nevents<<endl;
-#endif
-   for(Int_t ievent=0;ievent<nevents;ievent++)
-    { 
-#ifdef DEBUG
-      cout<<" *** event "<<ievent<<endl; 
-#endif
-      runLoader->GetEvent(ievent) ;
-      //event z-vertex for correction eta-rad dependence      
-      AliHeader *header = runLoader->GetHeader();
-      AliGenEventHeader* genHeader = header->GenEventHeader();
-      TArrayF *o = new TArrayF(3); 
-      genHeader->PrimaryVertex(*o);
-      Float_t zVertex=o->At(2);
+  
+  fAlgorithms.Delete();
+  TIter next(&(other.fAlgorithms));
+  AliFMDMultAlgorithm* algorithm = 0;
+  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next()))) 
+    fAlgorithms.Add(algorithm);
+  fAlgorithms.SetOwner(kFALSE);
+}
+  
 
-      for (Int_t i=0; i<5; i++)
-        hTotal[i+1]->Reset();
-      
-      retval = plFMD->LoadDigits("READ"); 
-      if (retval)
-       {
-         Error("Exec","Error occured while loading digits. Exiting.");
-         return;
-       }
-      
-      AliFMD * fFMD = (AliFMD *)gAlice->GetDetector("FMD");
-      TClonesArray *fReconParticles=fFMD->ReconParticles();
-      TClonesArray *fDigits=fFMD->Digits();
-      TTree* treeD = plFMD->TreeD();
-      if (treeD == 0x0)
-       {
-         Error("Exec","Can not get Tree with Digits. Nothing to reconstruct - Exiting");
-         return;
-       }
-      
-      TBranch *brDigits=0;
-           
-      brDigits=treeD->GetBranch("FMD");
+//____________________________________________________________________
+AliFMDReconstructor&
+AliFMDReconstructor::operator=(const AliFMDReconstructor& other) 
+{
+  // Assignment operator
+  fPedestal       = other.fPedestal;
+  fPedestalWidth  = other.fPedestalWidth;
+  fPedestalFactor = other.fPedestalFactor;
+
+  fAlgorithms.Delete();
+  TIter next(&(other.fAlgorithms));
+  AliFMDMultAlgorithm* algorithm = 0;
+  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next()))) 
+    fAlgorithms.Add(algorithm);
+  fAlgorithms.SetOwner(kFALSE);
 
-      if (brDigits) {
-       brDigits->SetAddress(&fDigits);
-      }else{
-       cerr<<"EXEC Branch FMD digits not found"<<endl;
-       return;
-      } 
-         
-      if(plFMD->TreeR()==0) plFMD->MakeTree("R");
+  return *this;
+}
 
-      //Make branches
-      fFMD->MakeBranch("R");
+//____________________________________________________________________
+AliFMDReconstructor::~AliFMDReconstructor() 
+{
+  // Destructor 
+  fAlgorithms.Delete();
+}
 
-      
-      Int_t zeroADC=6;
-      // read Digits 
-      AliFMDdigit  *fmdDigit;
-       if (fFMD)
-       {
-         plFMD->TreeD()->GetEvent(0); 
-                 
-         Int_t nDigits=fDigits->GetEntries();
-         Int_t recParticles[6];
-         Int_t nRecPart=0 ;
-         Int_t zeroPads=0;
-         Int_t numberOfPads=0;
-         Int_t pedestal;
-         Float_t channelWidth=(22400*50)/1024;
-         for (Int_t digit=0;digit<nDigits;digit++) 
-           {
-             fmdDigit=(AliFMDdigit*)fDigits->UncheckedAt(digit);    
-             ivol=fmdDigit->Volume();
-             iSector=fmdDigit->NumberOfSector();
-             iRing=fmdDigit->NumberOfRing();
-             pedestal=Int_t(gRandom->Gaus(500,250));
-             padADC= fmdDigit->ADCsignal()
-               -Int_t(Float_t(pedestal)/channelWidth);
-             if (padADC<0) padADC=0;
-              hTotal[ivol]->Fill(iSector,iRing,padADC);
-           } //digit loop
+//____________________________________________________________________
+void 
+AliFMDReconstructor::Init(AliRunLoader* runLoader) 
+{
+  // Initialize the reconstructor 
+  AliDebug(1, Form("Init called with runloader 0x%x", runLoader));
+  fCurrentVertex = 0;
+  if (!runLoader) { 
+    Warning("Init", "No run loader");
+    return;
+  }
+  AliHeader* header = runLoader->GetHeader();
+  if (!header) {
+    Warning("Init", "No header");
+    return;
+  }
+  AliGenEventHeader* eventHeader = header->GenEventHeader();
+  if (eventHeader) {
+    TArrayF vtx;
+    eventHeader->PrimaryVertex(vtx);
+    fCurrentVertex = vtx[2];
+    AliDebug(1, Form("Primary vertex Z coordinate for event # %d/%d is %f", 
+                    header->GetRun(), header->GetEvent(), fCurrentVertex));
+    Warning("Init", "no generator event header");
+  }
+  else {
+    Warning("Init", "No generator event header - "
+           "perhaps we get the vertex from ESD?");
+  }
+  // Get the ESD tree 
+  SetESD(new AliESD);
+}
 
-         //reconstruct multiplicity in 0.1 eta according Poisson distribution 
+//____________________________________________________________________
+void 
+AliFMDReconstructor::ConvertDigits(AliRawReader* reader, 
+                                  TTree* digitsTree) const
+{
+  // Convert Raw digits to AliFMDDigit's in a tree 
+  AliFMDRawReader rawRead(reader, digitsTree);
+  // rawRead.SetSampleRate(fFMD->GetSampleRate());
+  rawRead.Exec();
+}
 
-         Int_t rmin=0; Int_t rmax=0; 
-         Int_t smin=0; Int_t smax=0; 
-         for (ivol=0; ivol<knumVolumes; ivol++)
-           {
-             Float_t ring2number=Float_t (numberOfRings[ivol])/
-               (rout[ivol]-rin[ivol]);
-             Float_t realZ=zVertex+z[ivol];
-             theta=TMath::ATan(rout[ivol]/TMath::Abs(realZ));
-             etain = - TMath::Log( TMath::Tan(theta/2.));
-             theta=TMath::ATan(rin[ivol]/TMath::Abs(realZ));
-             etaout=- TMath::Log( TMath::Tan(theta/2.));
-             numberOfEtaIntervals[ivol]=Int_t((etaout-etain)*10)-1;
-             eta=etain;
-             for (Int_t e1=0;e1<=numberOfEtaIntervals[ivol];e1++) 
-               {
-                 theta = 2.*TMath::ATan (TMath::Exp (-eta));
-                 Float_t radmin = TMath::Abs(realZ) * (TMath::Tan (theta));
-                 rmax= Int_t ( (radmin-rin[ivol])*ring2number+0.5);
-                 eta=eta+0.1;
-                 theta = 2.*TMath::ATan (TMath::Exp (-eta));
-                 rad = TMath::Abs(realZ) * (TMath::Tan (theta));
-                 rmin=Int_t( (rad-rin[ivol])*ring2number+0.5);
-                 
-                 zeroPads=0;
-                 smin=0;
-                 smax=numberOfSectors[ivol]; 
-                 numberOfPads=(rmax-rmin)*(smax-smin);
-                 for (Int_t iring=rmin; iring<rmax; iring++) 
-                   {
-                     for 
-                       (Int_t isector=0;
-                        isector<numberOfSectors[ivol]; 
-                        isector++) 
-                       {
-                         if(hTotal[ivol+1]->GetBinContent(isector+1,iring+1)
-                            <zeroADC) zeroPads++;}
-                     
-                   } //ring
-                 Float_t numberOfPads=Float_t(smax-smin)*Float_t(rmax-rmin);
+//____________________________________________________________________
+void 
+AliFMDReconstructor::Reconstruct(TTree* digitsTree, 
+                                TTree* clusterTree) const 
+{
+  // Reconstruct event from digits in tree 
+  // Get the FMD branch holding the digits. 
+  // FIXME: The vertex may not be known yet, so we may have to move
+  // some of this to FillESD. 
+  AliDebug(1, "Reconstructing from digits in a tree");
 
-                 Double_t lambda=-TMath::Log(Double_t(zeroPads)/numberOfPads);
-                 Int_t fRecon=Int_t (lambda*numberOfPads+0.5);
-                 recParticles[0]=ivol+1;
-                 recParticles[1]=smin;
-                 recParticles[2]=smax;
-                 recParticles[3]=rmin;
-                 recParticles[4]=rmax;
-                 recParticles[5]= fRecon;
-                 new((*fReconParticles)[nRecPart++])   AliFMDReconstParticles(recParticles);             
-                 
+  if (fESD) {
+    const AliESDVertex* vertex = fESD->GetVertex();
+    // if (vertex) {
+    //   AliDebug(1, Form("Got vertex from ESD: %f", vertex->GetZv()));
+    //   fCurrentVertex = vertex->GetZv();
+    // }
+  }
+  
+  TBranch *digitBranch = digitsTree->GetBranch("FMD");
+  if (!digitBranch) {
+    Error("Exec", "No digit branch for the FMD found");
+    return;
+  }
+  TClonesArray* digits = new TClonesArray("AliFMDDigit");
+  digitBranch->SetAddress(&digits);
 
-                } // eta
-            } // volume
-          
-       }//if FMD
-       plFMD->TreeR()->Reset();
-       plFMD->TreeR()->Fill(); 
-       plFMD->WriteRecPoints("OVERWRITE");
-       plFMD->UnloadDigits();
-    } //event loop
-  plFMD->UnloadRecPoints();
-#ifdef DEBUG
-  Info(" Exec"," finished");
-#endif
-  //  delete hTotal[10]; 
+  TIter next(&fAlgorithms);
+  AliFMDMultAlgorithm* algorithm = 0;
+  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next()))) 
+    algorithm->PreEvent(clusterTree, fCurrentVertex);
+  digitBranch->GetEntry(0);
+  
+  ProcessDigits(digits);
 
+  next.Reset();
+  algorithm = 0;
+  while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next()))) 
+    algorithm->PostEvent();
+  clusterTree->Fill();
+  digits->Delete();
+  delete digits;
+}
+//____________________________________________________________________
+void
+AliFMDReconstructor::ProcessDigits(TClonesArray* digits) const
+{
+  // For each digit, find the pseudo rapdity, azimuthal angle, and
+  // number of corrected ADC counts, and pass it on to the algorithms
+  // used. 
+  Int_t nDigits = digits->GetEntries();
+  AliDebug(1, Form("Got %d digits", nDigits));
+  for (Int_t i = 0; i < nDigits; i++) {
+    AliFMDDigit* digit = static_cast<AliFMDDigit*>(digits->At(i));
+    AliFMDGeometry* fmd = AliFMDGeometry::Instance();
+    AliFMDDetector* subDetector = fmd->GetDetector(digit->Detector());
+    if (!subDetector) { 
+      Warning("ProcessDigits", "Unknown detector: FMD%d" , digit->Detector());
+      continue;
+    }
+    
+    AliFMDRing* ring  = subDetector->GetRing(digit->Ring());
+    Float_t     ringZ = subDetector->GetRingZ(digit->Ring());
+    if (!ring) {
+      Warning("ProcessDigits", "Unknown ring: FMD%d%c", digit->Detector(), 
+             digit->Ring());
+      break;
+    }
+    
+    Float_t  realZ    = fCurrentVertex + ringZ;
+    Float_t  stripR   = ((ring->GetHighR() - ring->GetLowR()) 
+                        / ring->GetNStrips() * (digit->Strip() + .5) 
+                        + ring->GetLowR());
+    Float_t  theta    = TMath::ATan2(stripR, realZ);
+    Float_t  phi      = (2 * TMath::Pi() / ring->GetNSectors() 
+                        * (digit->Sector() + .5));
+    Float_t  eta      = -TMath::Log(TMath::Tan(theta / 2));
+    UShort_t counts   = SubtractPedestal(digit);
+    
+    TIter next(&fAlgorithms);
+    AliFMDMultAlgorithm* algorithm = 0;
+    while ((algorithm = static_cast<AliFMDMultAlgorithm*>(next()))) 
+      algorithm->ProcessDigit(digit, eta, phi, counts);
+  }
 }
+      
+//____________________________________________________________________
+UShort_t
+AliFMDReconstructor::SubtractPedestal(AliFMDDigit* digit) const
+{
+  // Member function to subtract the pedestal from a digit
+  // This implementation does nothing, but a derived class could over
+  // load this to subtract a pedestal that was given in a database or
+  // something like that. 
 
+  Int_t counts = 0;
+  Float_t ped = fPedestal + fPedestalFactor * fPedestalWidth;
+  if (digit->Count3() > 0)      counts = digit->Count3();
+  else if (digit->Count2() > 0) counts = digit->Count2();
+  else                          counts = digit->Count1();
+  counts = TMath::Max(Int_t(counts - ped), 0);
+  return  UShort_t(counts);
+}
 
-//_____________________________________________________________________________
-void AliFMDReconstructor::FillESD(AliRunLoader* /*runLoader*/, 
-                                 AliESD* /*esd*/) const
+//____________________________________________________________________
+void 
+AliFMDReconstructor::FillESD(TTree*  /* digitsTree */, 
+                            TTree*  /* clusterTree */,
+                            AliESD* /* esd*/) const
 {
-// nothing to be done
-
+  // nothing to be done
+  // FIXME: The vertex may not be known when Reconstruct is executed,
+  // so we may have to move some of that member function here. 
+#if 0
+  TClonesArray* multStrips  = 0;
+  TClonesArray* multRegions = 0;
+  TTree*        treeR  = fmdLoader->TreeR();
+  TBranch*      branchRegions = treeR->GetBranch("FMDPoisson");
+  TBranch*      branchStrips  = treeR->GetBranch("FMDNaiive");
+  branchRegions->SetAddress(&multRegions);
+  branchStrips->SetAddress(&multStrips);
+  
+  Int_t total = 0;
+  Int_t nEntries  = clusterTree->GetEntries();
+  for (Int_t entry = 0; entry < nEntries; entry++) {
+    AliDebug(5, Form("Entry # %d in cluster tree", entry));
+    treeR->GetEntry(entry);
+    
+    
+    Int_t nMults = multRegions->GetLast();
+    for (Int_t i = 0; i <= nMults; i++) {
+      AliFMDMultRegion* multR =
+       static_cast<AliFMDMultRegion*>(multRegions->UncheckedAt(i));
+      Int_t nParticles=multR->Particles();
+      if (i>=0 && i<=13)   hEtaPoissonI1->AddBinContent(i+1,nParticles);
+      if (i>=14 && i<=27 ) hEtaPoissonI2->AddBinContent(i-13,nParticles);
+      if (i>=28 && i<=33 );
+      if (i>=34 && i<=47 ) hEtaPoissonI3->AddBinContent(48-i,nParticles);
+      if (i>=48 && i<=53)  hEtaPoissonO3->AddBinContent(54-i,nParticles);
+    }
+  }
+#endif   
 }
 
+//____________________________________________________________________
+//
+// EOF
+//