PHOS Reconstruction





Definitions and objectives

What is PHOS ?

PHOS is the association of two sub-detectors: Both sub-detectors are physically organized in modules. A separate document is dedicated to the description of the PHOS geometry.

Reconstruction design

The reconstruction software consists in making particles from the digits generated by the simulation.

Use Case of reconstruction

Figure 1.: Use Case for reconstruction. Only PHOS is implemented. Other detectors are ignored. Click on image for full scale

The PHOS reconstruction is delegated by the detector to a reconstructioner algorithmic object. It proceeds along three steps:
Clusterization
The reconstruction of the showers (total energy loss and incident direction) induced in the EM calorimeter (AliPHOSEmcRecPoint) and of the pads hit in the pre-shower detector (AliPHOSPpsdRecPoint). The clustering is delegated to the algorithmic object AliPHOSClusterizerv1 which derives from the interface AliPHOSClusterizer. The clusterization is controlled by several parameters.
Sub-Track construction
Sub tracks are obtained by combining reconstructed points in EMCA and PPSD to form a track segment (AliPHOSTrackSegment). This construction is delegated to the algorithmic object AliPHOSTrackSegmentMakerv1 which derives from the interface AliPHOSTrackSegmentMaker.
Particle identification
From each track segment a reconstructed particle (AliPHOSRecParticle) is made the identification being based on the information delivered by the PPSD (which PPSD stage is hit) and by EMCA (shower profile and topology).The identification is delegated to the algorithmic object AliPHOSPIDv1 which derives from the interface AliPHOSPID. Several parameters control the identification procedure.
The first step is detector specific, i.e. does not require any information about other detectors. The two last steps may (and probably will) depend on other detector reconstructions (connecting sub tracks or combining particle identification delivered by various sub-detectors).

How to use it ?

This is a little piece of code which shows how to use the reconstruction. It can be used in a Root macro or the class AliPHOSAnalyze can be used instead together with the GUI interface EditorBar.C:
      fRootFile   = new TFile("MyFileName", "update") ;   // open the root file created by the simulation
      gAlice = (AliRun*) fRootFile->Get("gAlice");        // get from file the AliRun object
      fPHOS  = (AliPHOSv0 *)gAlice->GetDetector("PHOS") ; // get from file the detector object
      fGeom  = AliPHOSGeometry::GetInstance(              // get the geometry used for the simulation
                     fPHOS->GetGeometry()->GetName(), 
                     fPHOS->GetGeometry()->GetTitle() ) ;

      //========== Initializes the Index to Object converter
      fObjGetter = AliPHOSIndexToObject::GetInstance(fPHOS) ; 
  
      //========== Create the Clusterizer and set a few parameters
      fClu =  new AliPHOSClusterizerv1() ; 
      fClu->SetEmcEnergyThreshold(0.030) ; 
      fClu->SetEmcClusteringThreshold(1.0) ; 
      fClu->SetPpsdEnergyThreshold    (0.0000002) ; 
      fClu->SetPpsdClusteringThreshold(0.0000001) ; 
      fClu->SetLocalMaxCut(0.03) ;
      fClu->SetCalibrationParameters(0., 0.00000001) ;  
      cout <<  "AnalyzeOneEvent > using clusterizer " << fClu->GetName() << endl ; 
      fClu->PrintParameters() ; 
    
      //========== Creates the track segment maker
      fTrs = new AliPHOSTrackSegmentMakerv1() ;
      cout <<  "AnalyzeOneEvent > using tack segment maker " << fTrs->GetName() << endl ; 
      fTrs->UnsetUnfoldFlag() ;
    
      //========== Creates the particle identifier
      fPID = new AliPHOSPIDv1() ;
      cout <<  "AnalyzeOneEvent > using particle identifier " << fPID->GetName() << endl ; 
      fPID->SetShowerProfileCuts(0., 0., 0., 0.) ;
      fPIS->SetDispersionCutOff(0.34) ;

      //========== Creates the Reconstructioner  
      fRec = new AliPHOSReconstructioner(fClu, fTrs, fPID) ;     
    
      //=========== Connect the various Tree's for evt
      gAlice->GetEvent(evt);
    
      //=========== Fill the fDigits array from the Digit TTree
      gAlice->TreeD()->GetEvent(0) ;     
      
      //=========== Do the reconstruction
      fPHOS->Reconstruction(fRec);  
    
      // =========== Write to the root file
      fRootFile->Close() ; 
    

Clusterization

A digit is a set of two numbers: the id of the elementary cell numbered from 1 to the maximum number of cells (EMCA+PPSD), and a digitized deposited energy. With the help of the geometry object the absolute id is converted into a relative numbering with a single EMCA or PPSD module, in terms of rows and columns ( ALIPHOSGeometry::AbsToRelNumbering() ). A clustering algorithm ( AliPHOSClusterizerv1::MakeClusters() ) groups neighbouring cells in EMCA and PPSD ( AliPHOSClusterizerv1::AreNeighbours() ) where two cells are defined as neighbours if they have a common edge or a common corner. The algorithm is controlled with alltogether 4 parameters: An ensemble of neighbouring digits is called a reconstructed point. The PHOS clusterizer produces EmcRecPoints and PpsdRecPoints deriving form the base class AliPHOSRecPoint. Each reconstructed point points, through a mechanism described later, to the digits at its origin. Since a digit remembers which primary particle(s) were at its origin, the list of primary particles at the origin of a reconstructed point is provided by the method AliPHOSRecPoint::GetPrimaries()).

The reconstructed points are contained in two TObjArray (mandatory because the size of a reconstructed point depends on the number of digits used to build it) which are stored in TreeR, branch PHOSEmcRP for EMCA and branch PHOSPpsdRP for PPSD.


Track Segments Maker

Each EMCA reconstructed point is either combined with one or two PPSD reconstructed points to form a track segment or constitutes a track segment by itself. As a first step the EMCA reconstructed points are unfolded in case there is more than one local maximum ( overlapping showers) to make two new reconstructed points which digit's energy is shared after a fitting procedure. The unfolding procedure can be switch on and off with the method: AliPHOSTrackSegmentMakerv1::(Un)SetUnfoldFlag(). EMCA reconstructed points and PPSD reconstructed points are then linked together to form pairs or triplets according to their relative distance. Each track segment points is linked, through a mechanism described later, to the reconstructed points at its origin.

The track segments are contained in a TClonesArray which are stored in TreeR, branch PHOSTS.


Particle Identification

Clusterization and track segments making are two activities that are detector-driven. This is not the case for the particle identification. Indeed a particle might be identified by combining the track segments calculated by several detectors. Up to know the implementation for such a mechanism is not yet done. Instead PHOS has its own stand alone particle identification algorithm which associates a reconstructed particle to each track segment. The particle identification is controlled by several parameters which can be set by the user. Each reconstructed particle is linked, through a mechanism described later, to the track segment at its origin. The various types of reconstructed particles are the following:
NEUTRAL: a reconstructed point in EMCA, none in the two layers of the PPSD;
GAMMA : a reconstructed point in the lower PPSD layer, none in the upper one, and a reconstructed point in EMCA that satisfies the shower topology cuts;
GAMMAHADRON : as a GAMMA, but the EMCA reconstructed point does not satisfy the shower topology cuts;
CHARGED: a reconstructed point in EMCA, and one in the upper layer of the PPSD;
NEUTRALEM: a NEUTRAL particle for which the EMCA reconstructed point satisfies the shower profile cut;
NEUTRALHADRON: a NEUTRAL particle for which the EMCA reconstructed point does not satisfy the shower profile cut;
ELECTRON: a CHARGED particle for which the EMCA reconstructed point satisfies the shower profile cut;
CHARGEDHADRON: a CHARGED particle for which the EMCA reconstructed point does not satisfy the shower profile cut;

Disk Storage Structure

All the three types of reconstructed objects( reconstructed point, track segment and reconstructed particle) are stored in the reconstruction Tree (TreeR). The container of the reconstructed points is a TObjArray and the container of the track segment and the reconstructed particles is a TClonesArray. The names of the branches are respectively: PHOSEmcRP, PHOSPpsdRP, PHOSTS and PHOSRP. The TreeR is best seen in the following example:
      root [2] TFile myfile("junk.root")
      root [3] TTree * reconstructedtree = (TTree *)myfile.Get("TreeR0")
      root [5] reconstructedtree.Print()
      ******************************************************************************
      *Tree    :TreeR0    : Reconstruction                                         *
      *Entries :        1 : Total  Size =     10882 bytes  File  Size =       4024 *
      *        :          : Tree compression factor =   5.65                       *
      ******************************************************************************
      *Branch  :PHOSEmcRP : PHOSEmcRP                                              *
      *Entries :        1 : Total  Size =         0 bytes  File Size  =          0 *
      *Baskets :        0 : Basket Size =     16000 bytes  Compression=   1.00     *
      *............................................................................*
      *Branch  :PHOSPpsdRP : PHOSPpsdRP                                            *
      *Entries :        1 : Total  Size =      8334 bytes  File Size  =       1476 *
      *Baskets :        1 : Basket Size =     16000 bytes  Compression=   5.65     *
      *............................................................................*
      *Branch  :PHOSTS    : PHOSTS                                                 *
      *Entries :        1 : Total  Size =         0 bytes  File Size  =          0 *
      *Baskets :        0 : Basket Size =     16000 bytes  Compression=   1.00     *
      *............................................................................*
      *Branch  :PHOSRP    : PHOSRP                                                 *
      *Entries :        1 : Total  Size =         0 bytes  File Size  =          0 *
      *Entries :        1 : Total  Size =         0 bytes  File Size  =          0 *
      *Baskets :        0 : Basket Size =     16000 bytes  Compression=   1.00     *
      *............................................................................*
      root [6]                       
    
branches in reconstructed Tree

Figure 2: Branches in TreeR generated by the PHOS reconstruction. PHOSEmc(Ppsd)RP contains EMCA(PPSD) reconstructed points in TObjArray; PHOSTS contains track segments in a TClonesArray; PHOSRP contains reconstructed particles in a TClonesArray.


How are the links implemented ?

An algorithmic class, AliPHOSIndexToObject returns a pointer to the object of interest given the index of its storage in the array (TObjArray or TClonesArray). It is a singleton (only one instance of the object does exist at run time). It must be initialized once:
      AliPHOS * phos = (AliPHOSv0 *)gAlice->GetDetector("PHOS") ;
      AliPHOSIndexToObject::GetInstance(phos) ; 
    
It can then be used as follow, for example for retrieving a particle from the kine tree (TreeK):
     AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ;
     Int_t index = 123 ; 
     TParticle * primaryparticle = please->GimePrimaryParticle(index) ;
    
We shall now detail how the various reconstruction objects are linked together.

Digits to primary particles

Digits have three additional data members (fPrimary1(2,3)) that gives the index of the primary particles (maximum 3) that have contributed to the formation of the digit. Remember that in PHOS a digit is obtained from all the hits accumulated in a single cell. This is not really elegant, but because the container of digits is a TClonesArray it is not possible to replace the three data members by an array of integers of variable length as all objects in a TClonesArray must be identical. To retrieve the particles that have contibuted to a digit, do:
    // initialization
          // open root file
     TFile rootfile("junk.root") ;               
          // get AliRun object
     gAlice = (AliRun *)rootfile.Get("gAlice") ;
          // get detector object
     AliPHOSv0 * phos = (AliPHOSv0 *)gAlice->GetDetector("PHOS") ;
          // get the geometry associated with the detector
     AliPHOSGeometry::GetInstance( phos->GetGeometry()->GetName(), phos->GetGeometry()->GetTitle() ) ; 
          // initializes the index to object converter
     AliPHOSIndexToObject::GetInstance(phos) ;
          // get the list of digits
     TClonesArray * digitslist = phos->Digits() ; 
          // loop over the list of digits
     TIter nextdigit(digitslist) ; 
     AliPHOSDigit * digit ; 
     TParticle * primaryparticle[3] ; 
          // get the pointer of the index to object converter
     AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ;
     while ( digit = (AliPHOSDigit * )nextdigit() ) {
       for ( Int_t i = 0 ; i < digit->GetNprimary() ; i++ ) 
       primary[i] = please->GimePrimaryParticle(digit->GetPrimary(i) ) ;
     }     
    

Reconstructed point to Digit

A digit has an additional data member which is the index of the object stored in the TObjArray. It is set by FinishEvent(). A reconstructed point containing a list of digits, it can retrieve the digit object with the help of AliPHOSIndexToObject:
      // initialization
          // open root file
     TFile rootfile("junk.root") ;               
          // get AliRun object
     gAlice = (AliRun *)rootfile.Get("gAlice") ;
          // get detector object
     AliPHOSv0 * phos = (AliPHOSv0 *)gAlice->GetDetector("PHOS") ;
          // get the geometry associated with the detector
     AliPHOSGeometry::GetInstance( phos->GetGeometry()->GetName(), phos->GetGeometry()->GetTitle() ) ; 
          // initializes the index to object converter
     AliPHOSIndexToObject::GetInstance(phos) ;
          // get the reconstructed points list
     Int_t evt = 123 ; 
     TObjArray * recpointslist = phos->EmcRecPoints(evt) ; 
          // loop over reconstructed points 
     TIter nextrecpoint(recpointslist) ; 
          // get the pointer of the index to object converter
     AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ;
     AliPHOSEmcRecPoint * recpoint ;  
     while ( recpoint = (AliPHOSEmcRecPoint * )nextrecpoint() ) {
             // get the associated digits list
       Int_t * digitsindexeslist = recpoint->GetDigitsList() ;
             // loop over the list of digits
       for ( Int_t i = 0 ; i < recpoint->GetDigitsMultiplicity() ; i++ ) {
         AliPHOSDigit * digit = please->GimeDigit(digitsindexeslist[i] ) ;
               // get the primary particle associated with that digit
 	 Int_t numberofprimaries = 0 ; 
	 Int_t * prim = digit->GetPrimaries(numberofprimaries) ;
         for (Int_t i = 0 ; i < numberofprimaries ; i++ )
           // and print them 
	   please->GimePrimaryParticle( prim[i] )->Print()  ;
         } 
       } 
         // or get the primaries directly from the reconstructed point
       Int_t numberofprimaries = 0 ; 
       Int_t * prim = recpoint->GetPrimaries(numberofprimaries) ;  
     }       
    

Track segment to reconstructed point

A reconstructed point has an additional data member which is the index of the object stored in the TClnesArray. It is set by the reconstructioner. A track segment contains the index of one EMCA reconstructed points and two PPSD reconstructed points, it can retrieve this reconstructed point objects with the help of AliPHOSIndexToObject:
     // initialization
          // open root file
     TFile rootfile("junk.root") ;               
          // get AliRun object
     gAlice = (AliRun *)rootfile.Get("gAlice") ;
          // get detector object
     AliPHOSv0 * phos = (AliPHOSv0 *)gAlice->GetDetector("PHOS") ;
          // get the geometry associated with the detector
     AliPHOSGeometry::GetInstance( phos->GetGeometry()->GetName(), phos->GetGeometry()->GetTitle() ) ; 
          // initializes the index to object converter
     AliPHOSIndexToObject::GetInstance(phos) ;
          // get the track segments list
     Int_t evt = 123 ; 
     TClonesArray * tracksegmentslist = phos->TrackSegments(evt) ; 
          // loop over track segments
     TIter nexttracksegment(tracksegmentslist) ; 
     AliPHOSTrackSegment * tracksegment ;  
         // get the pointer of the index to object converter
     AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ;
     while ( tracksegment = (AliPHOSTrackSegment * )nexttracksegment() ) {
           // get the associated reconstructed points
         AliPHOSEmcRecPoint  * emcrecpoint     = please->GimeRecPoint(tracksegment->GetEmcRecPoint(),    "emc" ) ;
         AliPHOSPpsdRecPoint * ppsduprecpoint  = please->GimeRecPoint(tracksegment->GetPpsdUpRecPoint(), "ppsd" ) ;
         AliPHOSPpsdRecPoint * ppsdlowrecpoint = please->GimeRecPoint(tracksegment->GetPpsdLowRecPoint(),"ppsd" ) ;
          // get the primaries particles  
         Int_t numberofprimariestoemc = 0 ; 
         Int_t * primemc = tracksegment->GetPrimariesEmc(numberofprimariestoemc) ;
         Int_t numberofprimariestoppsdup = 0 ; 
         Int_t * primppsdup = tracksegment->GetPrimariesPpsdUp(numberofprimariestoppsdup) ;
         Int_t numberofprimariestoppsdlow = 0 ; 
         Int_t * primppsdlow = tracksegment->GetPrimariesPpsdLow(numberofprimariestoppsdlow) ;
          // print one as example  
         please->GimePrimaryParticle( primppsdlow[0] )->Print()  ;     
       }
     rootfile.Close() ;
     gAlice = 0 ; 
     phos = 0 ; 
     recparticleslist = 0 ;
     

Reconstructed particle to Track segment

A track segment has an additional data member which is the index of the object stored in the TClnesArray. It is set by the reconstructioner. A reconstructed particle contains the index of a track segment, it can retrieve this reconstructed point objects with the help of AliPHOSIndexToObject:
     // initialization
          // open root file
     TFile rootfile("junk.root") ;               
          // get AliRun object
     gAlice = (AliRun *)rootfile.Get("gAlice") ;
          // get detector object
     AliPHOSv0 * phos = (AliPHOSv0 *)gAlice->GetDetector("PHOS") ;
          // get the geometry associated with the detector
     AliPHOSGeometry::GetInstance( phos->GetGeometry()->GetName(), phos->GetGeometry()->GetTitle() ) ; 
          // initializes the index to object converter
     AliPHOSIndexToObject::GetInstance(phos) ;
          // get the reconstructed particles list
     Int_t evt = 123 ; 
     TClonesArray * recparticleslist = phos->RecParticles(evt) ; 
     // loop over reconstructed particles
     TIter nextrecparticle(recparticleslist) ; 
     AliPHOSRecParticle * recparticle ;  
       // get the pointer of the index to object converter
     AliPHOSIndexToObject * please = AliPHOSIndexToObject::GetInstance() ;
     while ( recparticle = (AliPHOSRecParticle * )nextrecparticle() ) {
           // get the track segment ...
         AliPHOSTrackSegment  * tracksegment  = recparticle->GetPHOSTrackSegment()  ;
           // and print it
	 tracksegment->Print() ;
           // get the list of primaries ...
	 Int_t numberofprimaries = 0 ; 
	 Int_t * prim = recparticle->GetPrimaries(numberofprimaries) ;
         for (Int_t i = 0 ; i < numberofprimaries ; i++ )
           // and print them 
	   please->GimePrimaryParticle( prim[i] )->Print()  ; 
    }     
     rootfile.Close() ;
     gAlice = 0 ; 
     phos = 0 ; 
     recparticleslist = 0 ;
    
A short cut allows to access the primaries at the origin of the reconstructed particle:
     Int_t numberofprimaries = 0 ; 
     Int_t * prim = recparticle->GetPrimariesPpsdLow(numberofprimaries) ;
    

© Groupe Photons Subatech [Go to the GPS Home Page]
Last modified: Sun Mar 26 17:20:12 CEST 2000