]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
New Recpoints
authorschutz <schutz@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 22 Jan 2002 08:08:12 +0000 (08:08 +0000)
committerschutz <schutz@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 22 Jan 2002 08:08:12 +0000 (08:08 +0000)
EMCAL/AliEMCALRecPoint.cxx [new file with mode: 0644]
EMCAL/AliEMCALRecPoint.h [new file with mode: 0644]
EMCAL/AliEMCALTowerRecPoint.cxx [new file with mode: 0644]
EMCAL/AliEMCALTowerRecPoint.h [new file with mode: 0644]

diff --git a/EMCAL/AliEMCALRecPoint.cxx b/EMCAL/AliEMCALRecPoint.cxx
new file mode 100644 (file)
index 0000000..35d73c5
--- /dev/null
@@ -0,0 +1,279 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+/* $Id$ */
+//_________________________________________________________________________
+//  Base Class for EMCAL Reconstructed Points  
+//  Why should I put meaningless comments
+//  just to satisfy
+//  the code checker                
+//*-- Author: Gines Martinez (SUBATECH)
+
+// --- ROOT system ---
+#include "TPad.h"
+#include "TClonesArray.h"
+
+// --- Standard library ---
+#include <iostream.h>
+#include <stdio.h>
+
+// --- AliRoot header files ---
+
+#include "AliEMCALGeometry.h"
+#include "AliEMCALDigit.h"
+#include "AliEMCALRecPoint.h"
+#include "AliEMCALGetter.h"
+
+ClassImp(AliEMCALRecPoint)
+
+
+//____________________________________________________________________________
+AliEMCALRecPoint::AliEMCALRecPoint()
+  : AliRecPoint()
+{
+  // ctor
+
+  fMaxTrack = 200 ;
+  fTheta = fPhi = 0. ; 
+  fEMCALArm = 1;
+
+}
+
+//____________________________________________________________________________
+AliEMCALRecPoint::AliEMCALRecPoint(const char * opt) : AliRecPoint(opt)
+{
+  // ctor
+  
+  fMaxTrack = 200 ;
+  fTheta = fPhi = 0. ; 
+  fEMCALArm = 1;
+  
+}
+
+//____________________________________________________________________________
+Int_t AliEMCALRecPoint::DistancetoPrimitive(Int_t px, Int_t py)
+{
+  // Compute distance from point px,py to  a AliEMCALRecPoint considered as a Tmarker
+  // Compute the closest distance of approach from point px,py to this marker.
+  // The distance is computed in pixels units.
+
+  TVector3 pos(0.,0.,0.) ;
+  GetLocalPosition( pos) ;
+  Float_t x =  pos.X() ;
+  Float_t y =  pos.Z() ;
+  const Int_t kMaxDiff = 10;
+  Int_t pxm  = gPad->XtoAbsPixel(x);
+  Int_t pym  = gPad->YtoAbsPixel(y);
+  Int_t dist = (px-pxm)*(px-pxm) + (py-pym)*(py-pym);
+  
+  if (dist > kMaxDiff) return 9999;
+  return dist;
+}
+
+//___________________________________________________________________________
+ void AliEMCALRecPoint::Draw(Option_t *option)
+ {
+   // Draw this AliEMCALRecPoint with its current attributes
+   
+   AppendPad(option);
+ }
+
+//______________________________________________________________________________
+void AliEMCALRecPoint::ExecuteEvent(Int_t event, Int_t px, Int_t py)
+{
+  // Execute action corresponding to one event
+  // This member function is called when a AliEMCALRecPoint is clicked with the locator
+  //
+  // If Left button is clicked on AliEMCALRecPoint, the digits are switched on    
+  // and switched off when the mouse button is released.
+
+  //  static Int_t pxold, pyold;
+
+  static TGraph *  digitgraph = 0 ;
+  static TPaveText* clustertext = 0 ;
+  
+  if (!gPad->IsEditable()) return;
+  
+  switch (event) {
+    
+    
+  case kButton1Down:{
+    AliEMCALDigit * digit ;
+    AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
+    AliEMCALGeometry * emcalgeom =  const_cast<AliEMCALGeometry*>(gime->EMCALGeometry());
+
+    Int_t iDigit;
+    Int_t relid[4] ;
+  
+    const Int_t kMulDigit=AliEMCALRecPoint::GetDigitsMultiplicity() ;
+    Float_t * xi = new Float_t [kMulDigit] ; 
+    Float_t * zi = new Float_t [kMulDigit] ;
+    
+    for(iDigit = 0; iDigit < kMulDigit; iDigit++) {
+      Fatal("AliEMCALRecPoint::ExecuteEvent", " -> Something wrong with the code"); 
+      digit = 0 ; //dynamic_cast<AliEMCALDigit *>((fDigitsList)[iDigit]);
+      emcalgeom->AbsToRelNumbering(digit->GetId(), relid) ;
+      emcalgeom->PosInAlice(relid, xi[iDigit], zi[iDigit]) ;
+    }
+    
+    if (!digitgraph) {
+      digitgraph = new TGraph(fMulDigit,xi,zi);
+      digitgraph-> SetMarkerStyle(5) ; 
+      digitgraph-> SetMarkerSize(1.) ;
+      digitgraph-> SetMarkerColor(1) ;
+      digitgraph-> Draw("P") ;
+    }
+    if (!clustertext) {
+      
+      TVector3 pos(0.,0.,0.) ;
+      GetLocalPosition(pos) ;
+      clustertext = new TPaveText(pos.X()-10,pos.Z()+10,pos.X()+50,pos.Z()+35,"") ;
+      Text_t  line1[40] ;
+      Text_t  line2[40] ;
+      sprintf(line1,"Energy=%1.2f GeV",GetEnergy()) ;
+      sprintf(line2,"%d Digits",GetDigitsMultiplicity()) ;
+      clustertext ->AddText(line1) ;
+      clustertext ->AddText(line2) ;
+      clustertext ->Draw("");
+    }
+    gPad->Update() ; 
+    Print() ;
+    delete[] xi ; 
+    delete[] zi ; 
+   }
+  
+break;
+  
+  case kButton1Up:
+    if (digitgraph) {
+      delete digitgraph  ;
+      digitgraph = 0 ;
+    }
+    if (clustertext) {
+      delete clustertext ;
+      clustertext = 0 ;
+    }
+    
+    break;
+    
+  }
+}
+//____________________________________________________________________________
+void AliEMCALRecPoint::EvalAll(Float_t logWeight,TClonesArray * digits) {
+  //evaluates (if necessary) all RecPoint data members 
+
+  EvalPrimaries(digits) ;
+}
+
+//____________________________________________________________________________
+void AliEMCALRecPoint::EvalEMCALArm(AliEMCALDigit * digit) 
+{
+  // Returns the EMCAL module in which the RecPoint is found
+
+
+  if( fEMCALArm == 0){
+  Int_t relid[4] ; 
+  
+  AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
+  AliEMCALGeometry * emcalgeom =  const_cast<AliEMCALGeometry*>(gime->EMCALGeometry());
+
+  emcalgeom->AbsToRelNumbering(digit->GetId(), relid) ;
+  fEMCALArm = relid[0];
+  }
+}
+
+//______________________________________________________________________________
+void  AliEMCALRecPoint::EvalPrimaries(TClonesArray * digits)
+{
+  // Constructs the list of primary particles (tracks) which have contributed to this RecPoint
+  
+  AliEMCALDigit * digit ;
+  Int_t * tempo    = new Int_t[fMaxTrack] ;
+
+  Int_t index ;  
+  for ( index = 0 ; index < GetDigitsMultiplicity() ; index++ ) { // all digits
+    digit = dynamic_cast<AliEMCALDigit *>(digits->At( fDigitsList[index] )) ; 
+    Int_t nprimaries = digit->GetNprimary() ;
+    Int_t * newprimaryarray = new Int_t[nprimaries] ;
+    Int_t ii ; 
+    for ( ii = 0 ; ii < nprimaries ; ii++)
+      newprimaryarray[ii] = digit->GetPrimary(ii+1) ; 
+
+    Int_t jndex ;
+    for ( jndex = 0 ; jndex < nprimaries ; jndex++ ) { // all primaries in digit
+      if ( fMulTrack > fMaxTrack ) {
+       fMulTrack = - 1 ;
+       cout << "AliEMCALRecPoint::GetNprimaries ERROR > increase fMaxTrack " << endl ;
+       break ;
+      }
+      Int_t newprimary = newprimaryarray[jndex] ;
+      Int_t kndex ;
+      Bool_t already = kFALSE ;
+      for ( kndex = 0 ; kndex < fMulTrack ; kndex++ ) { //check if not already stored
+       if ( newprimary == tempo[kndex] ){
+         already = kTRUE ;
+         break ;
+       }
+      } // end of check
+      if ( !already) { // store it
+       tempo[fMulTrack] = newprimary ; 
+       fMulTrack++ ;
+      } // store it
+    } // all primaries in digit
+    delete newprimaryarray ; 
+  } // all digits
+
+  
+  fTracksList = new Int_t[fMulTrack] ;
+  for(index = 0; index < fMulTrack; index++)
+   fTracksList[index] = tempo[index] ;
+  delete tempo ;
+
+}
+//____________________________________________________________________________
+void AliEMCALRecPoint::GetGlobalPosition(TVector3 & gpos) const
+{
+  // returns the position of the cluster in the global reference system of ALICE
+  // and the uncertainty on this position
+  
+  AliEMCALGeometry * emcalgeom = AliEMCALGetter::GetInstance()->EMCALGeometry();  
+  gpos.SetX(fPhi) ;
+  gpos.SetY(emcalgeom->GetIPDistance() + emcalgeom->GetAirGap()) ;
+  gpos.SetZ(fTheta) ; 
+}
+
+
+//______________________________________________________________________________
+void AliEMCALRecPoint::Paint(Option_t *)
+{
+  // Paint this ALiRecPoint as a TMarker  with its current attributes
+  
+  TVector3 pos(0.,0.,0.)  ;
+  GetLocalPosition(pos)   ;
+  Coord_t x = pos.X()     ;
+  Coord_t y = pos.Z()     ;
+  Color_t markercolor = 1 ;
+  Size_t  markersize = 1. ;
+  Style_t markerstyle = 5 ;
+  
+  if (!gPad->IsBatch()) {
+    gVirtualX->SetMarkerColor(markercolor) ;
+    gVirtualX->SetMarkerSize (markersize)  ;
+    gVirtualX->SetMarkerStyle(markerstyle) ;
+  }
+  gPad->SetAttMarkerPS(markercolor,markerstyle,markersize) ;
+  gPad->PaintPolyMarker(1,&x,&y,"") ;
+}
diff --git a/EMCAL/AliEMCALRecPoint.h b/EMCAL/AliEMCALRecPoint.h
new file mode 100644 (file)
index 0000000..772c011
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef ALIEMCALRECPOINT_H
+#define ALIEMCALRECPOINT_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+//_________________________________________________________________________
+//  Base Class for EMCAL Reconstructed Points  
+//  A recpoint being equivalent to a cluster in encal terminology                 
+//*-- Author: Gines Martinez (SUBATECH)
+
+#include <assert.h>
+
+// --- ROOT system ---
+
+#include "TMarker.h"
+#include "TGraph.h"
+#include "TPaveText.h"
+
+// --- Standard library ---
+
+// --- AliRoot header files ---
+
+#include "AliRecPoint.h"
+#include "AliEMCALDigit.h"
+
+class AliEMCALRecPoint : public AliRecPoint {
+
+ public:
+  
+  typedef TObjArray RecPointsList ; 
+
+  AliEMCALRecPoint() ;                   // ctor         
+  AliEMCALRecPoint(const char * opt) ;   // ctor 
+  AliEMCALRecPoint(const AliEMCALRecPoint & rp) {
+    // cpy ctor requested by Coding Convention 
+    // but not yet needed
+    assert(0==1) ; 
+  } 
+  
+  virtual ~AliEMCALRecPoint(){
+    // dtor
+  }
+  virtual  void   AddDigit(AliDigitNew &){
+    // do not use this definition but the one below
+    assert(0==1) ; 
+  }
+  virtual  void   AddDigit(AliEMCALDigit & digit, Float_t Energy) = 0 ; 
+  virtual Int_t   Compare(const TObject * obj) const = 0 ;   
+  virtual Int_t   DistancetoPrimitive(Int_t px, Int_t py);
+  virtual void    Draw(Option_t * option="") ;
+  virtual void    ExecuteEvent(Int_t event, Int_t px, Int_t py) ;
+  virtual void    EvalAll(Float_t logWeight,TClonesArray * digits) ;  
+  virtual void    EvalEMCALArm(AliEMCALDigit * digit) ;  
+  virtual void    EvalPrimaries(TClonesArray * digits) ;  
+  virtual Int_t   GetEMCALArm(void) const {return fEMCALArm ; }
+  virtual void    GetGlobalPosition(TVector3 & gpos, TMatrix & gmat) const {;} // return global position in ALICE
+  virtual void    GetGlobalPosition(TVector3 & gpos) const ; // return global position (r, theta, phi) in ALICE
+  //  virtual Int_t   GetEMCALMod(void) const {return fEMCALMod ; }
+  virtual Int_t * GetPrimaries(Int_t & number) const {number = fMulTrack ; 
+                                                      return fTracksList ; }
+  virtual Bool_t  IsEmc(void)const { return kTRUE ;  } 
+  virtual Bool_t  IsSortable() const { 
+    // tells that this is a sortable object
+    return kTRUE ; 
+  }  
+  virtual void    Paint(Option_t * option="");
+  virtual void    Print(Option_t * opt = "void") const {
+    // Print prototype
+  } 
+
+  AliEMCALRecPoint & operator = (const AliEMCALRecPoint & )  {
+    // assignement operator requested by coding convention but not needed
+    assert(0==1) ;
+    return *this ; 
+  }
+
+protected:
+  
+  Int_t fEMCALArm ; // EMCAM Arm number
+  Float_t fTheta ; // theta angle in Alice
+  Float_t fPhi ;   // phi angle in Alice
+
+
+  ClassDef(AliEMCALRecPoint,1) // RecPoint for EMCAL (Base Class)
+};
+
+#endif // AliEMCALRECPOINT_H
diff --git a/EMCAL/AliEMCALTowerRecPoint.cxx b/EMCAL/AliEMCALTowerRecPoint.cxx
new file mode 100644 (file)
index 0000000..6994449
--- /dev/null
@@ -0,0 +1,682 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+/* $Id$ */
+
+//_________________________________________________________________________
+//  RecPoint implementation for EMCAL-EMC 
+//  An TowerRecPoint is a cluster of digits   
+//*--
+//*-- Author: Dmitri Peressounko (RRC KI & SUBATECH)
+
+
+// --- ROOT system ---
+#include "TPad.h"
+#include "TH2.h"
+#include "TMath.h" 
+#include "TCanvas.h" 
+
+// --- Standard library ---
+
+#include <iostream.h> 
+
+// --- AliRoot header files ---
+
+ #include "AliGenerator.h"
+#include "AliEMCALGeometry.h"
+#include "AliEMCALTowerRecPoint.h"
+#include "AliRun.h"
+#include "AliEMCALGetter.h"
+
+ClassImp(AliEMCALTowerRecPoint)
+
+//____________________________________________________________________________
+AliEMCALTowerRecPoint::AliEMCALTowerRecPoint() : AliEMCALRecPoint()
+{
+  // ctor
+
+  fMulDigit   = 0 ;  
+  fAmp   = 0. ;   
+  fCoreEnergy = 0 ; 
+  fEnergyList = 0 ;
+  fTime = -1. ;
+  fLocPos.SetX(1000000.)  ;      //Local position should be evaluated
+   
+}
+
+//____________________________________________________________________________
+AliEMCALTowerRecPoint::AliEMCALTowerRecPoint(const char * opt) : AliEMCALRecPoint(opt)
+{
+  // ctor
+  
+  fMulDigit   = 0 ;  
+  fAmp   = 0. ;   
+  fCoreEnergy = 0 ; 
+  fEnergyList = 0 ;
+  fTime = -1. ;
+  fLocPos.SetX(1000000.)  ;      //Local position should be evaluated
+  
+}
+
+//____________________________________________________________________________
+AliEMCALTowerRecPoint::~AliEMCALTowerRecPoint()
+{
+  // dtor
+
+  if ( fEnergyList )
+    delete[] fEnergyList ; 
+}
+
+//____________________________________________________________________________
+void AliEMCALTowerRecPoint::AddDigit(AliEMCALDigit & digit, Float_t Energy)
+{
+  // Adds a digit to the RecPoint
+  // and accumulates the total amplitude and the multiplicity 
+  
+  if(fEnergyList == 0)
+    fEnergyList =  new Float_t[fMaxDigit]; 
+
+  if ( fMulDigit >= fMaxDigit ) { // increase the size of the lists 
+    fMaxDigit*=2 ; 
+    Int_t * tempo = new ( Int_t[fMaxDigit] ) ; 
+    Float_t * tempoE =  new ( Float_t[fMaxDigit] ) ;
+
+    Int_t index ;     
+    for ( index = 0 ; index < fMulDigit ; index++ ){
+      tempo[index]  = fDigitsList[index] ;
+      tempoE[index] = fEnergyList[index] ; 
+    }
+    
+    delete [] fDigitsList ; 
+    fDigitsList =  new ( Int_t[fMaxDigit] ) ;
+    delete [] fEnergyList ;
+    fEnergyList =  new ( Float_t[fMaxDigit] ) ;
+
+    for ( index = 0 ; index < fMulDigit ; index++ ){
+      fDigitsList[index] = tempo[index] ;
+      fEnergyList[index] = tempoE[index] ; 
+    }
+    delete [] tempo ;
+    delete [] tempoE ; 
+  } // if
+  
+  fDigitsList[fMulDigit]   = digit.GetIndexInList()  ; 
+  fEnergyList[fMulDigit]   = Energy ;
+  fMulDigit++ ; 
+  fAmp += Energy ; 
+
+  // EvalEMCALMod(&digit) ;
+}
+
+//____________________________________________________________________________
+Bool_t AliEMCALTowerRecPoint::AreNeighbours(AliEMCALDigit * digit1, AliEMCALDigit * digit2 ) const
+{
+  // Tells if (true) or not (false) two digits are neighbors
+  
+  Bool_t aren = kFALSE ;
+  
+  AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
+  AliEMCALGeometry * phosgeom =  (AliEMCALGeometry*)gime->EMCALGeometry();
+
+  Int_t relid1[4] ; 
+  phosgeom->AbsToRelNumbering(digit1->GetId(), relid1) ; 
+
+  Int_t relid2[4] ; 
+  phosgeom->AbsToRelNumbering(digit2->GetId(), relid2) ; 
+  
+  Int_t rowdiff = TMath::Abs( relid1[2] - relid2[2] ) ;  
+  Int_t coldiff = TMath::Abs( relid1[3] - relid2[3] ) ;  
+
+  if (( coldiff <= 1 )  && ( rowdiff <= 1 ) && (coldiff + rowdiff > 0)) 
+    aren = kTRUE ;
+  
+  return aren ;
+}
+
+//____________________________________________________________________________
+Int_t AliEMCALTowerRecPoint::Compare(const TObject * obj) const
+{
+  // Compares two RecPoints according to their position in the EMCAL modules
+
+  Float_t delta = 1 ; //Width of "Sorting row". If you changibg this 
+                      //value (what is senseless) change as vell delta in
+                      //AliEMCALTrackSegmentMakerv* and other RecPoints...
+  Int_t rv ; 
+
+  AliEMCALTowerRecPoint * clu = (AliEMCALTowerRecPoint *)obj ; 
+
+  Int_t phosmod1 = GetEMCALArm() ;
+  Int_t phosmod2 = clu->GetEMCALArm() ;
+
+  TVector3 locpos1; 
+  GetLocalPosition(locpos1) ;
+  TVector3 locpos2;  
+  clu->GetLocalPosition(locpos2) ;  
+
+  if(phosmod1 == phosmod2 ) {
+    Int_t rowdif = (Int_t)TMath::Ceil(locpos1.X()/delta)-(Int_t)TMath::Ceil(locpos2.X()/delta) ;
+    if (rowdif> 0) 
+      rv = 1 ;
+     else if(rowdif < 0) 
+       rv = -1 ;
+    else if(locpos1.Z()>locpos2.Z()) 
+      rv = -1 ;
+    else 
+      rv = 1 ; 
+     }
+
+  else {
+    if(phosmod1 < phosmod2 ) 
+      rv = -1 ;
+    else 
+      rv = 1 ;
+  }
+
+  return rv ; 
+}
+//______________________________________________________________________________
+void AliEMCALTowerRecPoint::ExecuteEvent(Int_t event, Int_t px, Int_t py) const
+{
+  
+  // Execute action corresponding to one event
+  //  This member function is called when a AliEMCALRecPoint is clicked with the locator
+  //
+  //  If Left button is clicked on AliEMCALRecPoint, the digits are switched on    
+  //  and switched off when the mouse button is released.
+  
+    
+  // AliEMCALGetter * gime =  AliEMCALGetter::GetInstance() ; 
+//   if(!gime) return ;
+//   AliEMCALGeometry * emcalgeom =  (AliEMCALGeometry*)gime->EMCALGeometry();
+  
+//   static TGraph *  digitgraph = 0 ;
+  
+//   if (!gPad->IsEditable()) return;
+  
+//   TH2F * histo = 0 ;
+//   TCanvas * histocanvas ; 
+
+//   const TClonesArray * digits = gime->Digits() ;
+  
+//   switch (event) {
+    
+//   case kButton1Down: {
+//     AliEMCALDigit * digit ;
+//     Int_t iDigit;
+//     Int_t relid[4] ;
+    
+//     const Int_t kMulDigit = AliEMCALTowerRecPoint::GetDigitsMultiplicity() ; 
+//     Float_t * xi = new Float_t[kMulDigit] ; 
+//     Float_t * zi = new Float_t[kMulDigit] ; 
+    
+//     // create the histogram for the single cluster 
+//     // 1. gets histogram boundaries
+//     Float_t ximax = -999. ; 
+//     Float_t zimax = -999. ; 
+//     Float_t ximin = 999. ; 
+//     Float_t zimin = 999. ;
+    
+//     for(iDigit=0; iDigit<kMulDigit; iDigit++) {
+//       digit = (AliEMCALDigit *) digits->At(fDigitsList[iDigit])  ;
+//       emcalgeom->AbsToRelNumbering(digit->GetId(), relid) ;
+//       emcalgeom->RelPosInModule(relid, xi[iDigit], zi[iDigit]);
+//       if ( xi[iDigit] > ximax )
+//     ximax = xi[iDigit] ; 
+//       if ( xi[iDigit] < ximin )
+//     ximin = xi[iDigit] ; 
+//       if ( zi[iDigit] > zimax )
+//     zimax = zi[iDigit] ; 
+//       if ( zi[iDigit] < zimin )
+//     zimin = zi[iDigit] ;     
+//     }
+//     ximax += emcalgeom->GetCrystalSize(0) / 2. ;
+//     zimax += emcalgeom->GetCrystalSize(2) / 2. ;
+//     ximin -= emcalgeom->GetCrystalSize(0) / 2. ;
+//     zimin -= emcalgeom->GetCrystalSize(2) / 2. ;
+//     Int_t xdim = (int)( (ximax - ximin ) / emcalgeom->GetCrystalSize(0) + 0.5  ) ; 
+//     Int_t zdim = (int)( (zimax - zimin ) / emcalgeom->GetCrystalSize(2) + 0.5 ) ;
+    
+//     // 2. gets the histogram title
+    
+//     Text_t title[100] ; 
+//     sprintf(title,"Energy=%1.2f GeV ; Digits ; %d ", GetEnergy(), GetDigitsMultiplicity()) ;
+    
+//     if (!histo) {
+//       delete histo ; 
+//       histo = 0 ; 
+//     }
+//     histo = new TH2F("cluster3D", title,  xdim, ximin, ximax, zdim, zimin, zimax)  ;
+    
+//     Float_t x, z ; 
+//     for(iDigit=0; iDigit<kMulDigit; iDigit++) {
+//       digit = (AliEMCALDigit *) digits->At(fDigitsList[iDigit])  ;
+//       emcalgeom->AbsToRelNumbering(digit->GetId(), relid) ;
+//       emcalgeom->RelPosInModule(relid, x, z);
+//       histo->Fill(x, z, fEnergyList[iDigit] ) ;
+//     }
+    
+//     if (!digitgraph) {
+//       digitgraph = new TGraph(kMulDigit,xi,zi);
+//       digitgraph-> SetMarkerStyle(5) ; 
+//       digitgraph-> SetMarkerSize(1.) ;
+//       digitgraph-> SetMarkerColor(1) ;
+//       digitgraph-> Paint("P") ;
+//     }
+    
+//     //    Print() ;
+//     histocanvas = new TCanvas("cluster", "a single cluster", 600, 500) ; 
+//     histocanvas->Draw() ; 
+//     histo->Draw("lego1") ; 
+    
+//     delete[] xi ; 
+//     delete[] zi ; 
+    
+//     break;
+//   }
+  
+//   case kButton1Up: 
+//     if (digitgraph) {
+//       delete digitgraph  ;
+//       digitgraph = 0 ;
+//     }
+//     break;
+  
+//    }
+}
+
+//____________________________________________________________________________
+void  AliEMCALTowerRecPoint::EvalDispersion(Float_t logWeight,TClonesArray * digits)
+{
+  // Calculates the dispersion of the shower at the origine of the RecPoint
+
+  Float_t d    = 0. ;
+  Float_t wtot = 0. ;
+
+  AliEMCALDigit * digit ;
+  AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
+  AliEMCALGeometry * emcalgeom =  (AliEMCALGeometry*)gime->EMCALGeometry();
+  
+
+ // Calculates the center of gravity in the local EMCAL-module coordinates 
+  
+  Int_t iDigit;
+  Int_t relid[4] ;
+
+  if (!fTheta || !fPhi ) {
+    for(iDigit=0; iDigit<fMulDigit; iDigit++) {
+      digit = dynamic_cast<AliEMCALDigit *>(digits->At(fDigitsList[iDigit])) ;
+      
+      Float_t thetai ;
+      Float_t phii ;
+      emcalgeom->AbsToRelNumbering(digit->GetId(), relid) ;
+      emcalgeom->PosInAlice(relid, thetai, phii);
+      Float_t w = TMath::Max( 0., logWeight + TMath::Log( fEnergyList[iDigit] / fAmp ) ) ;
+      fTheta = fTheta + thetai * w ;
+      fPhi   += (phii * w );
+      wtot  += w ;
+    }
+    
+    fTheta /= wtot ;
+    fPhi   /= wtot ;
+  }
+
+  const Float_t kDeg2Rad = TMath::Pi() / static_cast<Double_t>(180) ; 
+  
+  Float_t cyl_radius = emcalgeom->GetIPDistance()+emcalgeom->GetAirGap() ;
+  Float_t x =  cyl_radius * TMath::Cos(fPhi * kDeg2Rad ) ;
+  Float_t y =  cyl_radius * TMath::Cos(fPhi * kDeg2Rad ) ; 
+  Float_t z =  cyl_radius * TMath::Tan(fTheta * kDeg2Rad ) ; 
+  
+// Calculates the dispersion in coordinates 
+  wtot = 0.;
+  for(iDigit=0; iDigit < fMulDigit; iDigit++) {
+    digit = (AliEMCALDigit *) digits->At(fDigitsList[iDigit])  ;
+    Float_t thetai = 0. ;
+    Float_t phii = 0.;
+    emcalgeom->AbsToRelNumbering(digit->GetId(), relid) ;
+    emcalgeom->PosInAlice(relid, thetai, phii);
+    Float_t xi =  cyl_radius * TMath::Cos(phii * kDeg2Rad ) ;
+    Float_t yi =  cyl_radius * TMath::Sin(phii * kDeg2Rad ) ; 
+    Float_t zi =  cyl_radius * TMath::Tan(thetai * kDeg2Rad ) ; 
+
+    Float_t w = TMath::Max(0.,logWeight+TMath::Log(fEnergyList[iDigit]/fAmp ) ) ;
+    d += w*((xi-x)*(xi-x) + (yi-y)*(yi-y)+ (zi-z)*(zi-z) ) ; 
+    wtot+=w ;
+  }
+  
+  d /= wtot ;
+
+  fDispersion = TMath::Sqrt(d) ;
+}
+//______________________________________________________________________________
+void AliEMCALTowerRecPoint::EvalCoreEnergy(Float_t logWeight, TClonesArray * digits)
+{
+  // This function calculates energy in the core, 
+  // i.e. within a radius rad = 3cm around the center. Beyond this radius
+  // in accordance with shower profile the energy deposition 
+  // should be less than 2%
+
+  Float_t coreRadius = 10. ;
+
+  AliEMCALDigit * digit ;
+  Int_t relid[4] ;
+  Float_t wtot = 0. ;
+
+  AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
+  AliEMCALGeometry * emcalgeom =  (AliEMCALGeometry*)gime->EMCALGeometry();
+    
+  Int_t iDigit;
+
+  if (!fTheta || !fPhi ) {
+    for(iDigit=0; iDigit<fMulDigit; iDigit++) {
+      digit = dynamic_cast<AliEMCALDigit *>(digits->At(fDigitsList[iDigit])) ;
+      
+      Float_t thetai ;
+      Float_t phii ;
+      emcalgeom->AbsToRelNumbering(digit->GetId(), relid) ;
+      emcalgeom->PosInAlice(relid, thetai, phii);
+      Float_t w = TMath::Max( 0., logWeight + TMath::Log( fEnergyList[iDigit] / fAmp ) ) ;
+      fTheta = fTheta + thetai * w ;
+      fPhi   += (phii * w );
+      wtot  += w ;
+    }
+    
+    fTheta /= wtot ;
+    fPhi   /= wtot ;
+  }
+
+  const Float_t kDeg2Rad = TMath::Pi() / static_cast<Double_t>(180) ; 
+
+  Float_t cyl_radius = emcalgeom->GetIPDistance()+emcalgeom->GetAirGap() ;
+  Float_t x =  cyl_radius * TMath::Cos(fPhi * kDeg2Rad ) ;
+  Float_t y =  cyl_radius * TMath::Cos(fPhi * kDeg2Rad ) ; 
+  Float_t z =  cyl_radius * TMath::Tan(fTheta * kDeg2Rad ) ; 
+
+  for(iDigit=0; iDigit < fMulDigit; iDigit++) {
+    digit = (AliEMCALDigit *) ( digits->At(fDigitsList[iDigit]) ) ;
+    Int_t relid[4] ;
+    Float_t thetai = 0. ;
+    Float_t phii = 0. ;
+    emcalgeom->AbsToRelNumbering(digit->GetId(), relid) ;
+    emcalgeom->PosInAlice(relid, thetai, phii);
+    
+    Float_t xi =  cyl_radius * TMath::Cos(phii * kDeg2Rad ) ;
+    Float_t yi =  cyl_radius * TMath::Sin(phii * kDeg2Rad ) ; 
+    Float_t zi =  cyl_radius * TMath::Tan(thetai * kDeg2Rad ) ; 
+     
+    Float_t distance = TMath::Sqrt((xi-x)*(xi-x)+(yi-y)*(yi-y)+(zi-z)*(zi-z)) ;
+    if(distance < coreRadius)
+      fCoreEnergy += fEnergyList[iDigit] ;
+  }
+
+}
+
+//____________________________________________________________________________
+void  AliEMCALTowerRecPoint::EvalElipsAxis(Float_t logWeight,TClonesArray * digits)
+{
+  // Calculates the axis of the shower ellipsoid
+
+  Double_t wtot = 0. ;
+  Double_t x    = 0.;
+  Double_t z    = 0.;
+  Double_t dxx  = 0.;
+  Double_t dzz  = 0.;
+  Double_t dxz  = 0.;
+
+  AliEMCALDigit * digit ;
+
+  AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
+  AliEMCALGeometry * emcalgeom =  (AliEMCALGeometry*)gime->EMCALGeometry();
+
+  Int_t iDigit;
+  const Float_t kDeg2Rad = TMath::Pi() / static_cast<Double_t>(180) ; 
+  
+  Float_t cyl_radius = emcalgeom->GetIPDistance()+emcalgeom->GetAirGap() ;
+
+  for(iDigit=0; iDigit<fMulDigit; iDigit++) {
+    digit = (AliEMCALDigit *) digits->At(fDigitsList[iDigit])  ;
+    Int_t relid[4] ;
+    Float_t thetai = 0. ;
+    Float_t phii = 0. ; 
+    emcalgeom->AbsToRelNumbering(digit->GetId(), relid) ;
+    emcalgeom->PosInAlice(relid, thetai, phii);
+    Double_t w = TMath::Max(0.,logWeight+TMath::Log(fEnergyList[iDigit]/fAmp ) ) ;
+    Float_t xi =  cyl_radius * TMath::Cos(fPhi * kDeg2Rad ) ;
+    Float_t zi =  cyl_radius * TMath::Tan(fTheta * kDeg2Rad ) ; 
+    dxx  += w * xi * xi ;
+    x    += w * xi ;
+    dzz  += w * zi * zi ;
+    z    += w * zi ; 
+    dxz  += w * xi * zi ; 
+    wtot += w ;
+  }
+  dxx /= wtot ;
+  x   /= wtot ;
+  dxx -= x * x ;
+  dzz /= wtot ;
+  z   /= wtot ;
+  dzz -= z * z ;
+  dxz /= wtot ;
+  dxz -= x * z ;
+
+//   //Apply correction due to non-perpendicular incidence
+//   Double_t CosX ;
+//   Double_t CosZ ;
+//   AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
+//   AliEMCALGeometry * emcalgeom =  (AliEMCALGeometry*)gime->EMCALGeometry();
+  //   Double_t DistanceToIP= (Double_t ) emcalgeom->GetIPDistance() ;
+  
+//   CosX = DistanceToIP/TMath::Sqrt(DistanceToIP*DistanceToIP+x*x) ;
+//   CosZ = DistanceToIP/TMath::Sqrt(DistanceToIP*DistanceToIP+z*z) ;
+
+//   dxx = dxx/(CosX*CosX) ;
+//   dzz = dzz/(CosZ*CosZ) ;
+//   dxz = dxz/(CosX*CosZ) ;
+
+
+  fLambda[0] =  0.5 * (dxx + dzz) + TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz )  ;
+  if(fLambda[0] > 0)
+    fLambda[0] = TMath::Sqrt(fLambda[0]) ;
+
+  fLambda[1] =  0.5 * (dxx + dzz) - TMath::Sqrt( 0.25 * (dxx - dzz) * (dxx - dzz) + dxz * dxz )  ;
+  if(fLambda[1] > 0) //To avoid exception if numerical errors lead to negative lambda.
+    fLambda[1] = TMath::Sqrt(fLambda[1]) ;
+  else
+    fLambda[1]= 0. ;
+}
+
+//____________________________________________________________________________
+void AliEMCALTowerRecPoint::EvalAll(Float_t logWeight, TClonesArray * digits )
+{
+  // Evaluates all shower parameters
+
+  AliEMCALRecPoint::EvalAll(logWeight,digits) ;
+  EvalGlobalPosition(logWeight, digits) ;
+  EvalElipsAxis(logWeight, digits) ;
+  EvalDispersion(logWeight, digits) ;
+  EvalCoreEnergy(logWeight, digits);
+  EvalTime(digits) ;
+}
+
+//____________________________________________________________________________
+void AliEMCALTowerRecPoint::EvalGlobalPosition(Float_t logWeight, TClonesArray * digits)
+{
+  // Calculates the center of gravity in the local EMCAL-module coordinates 
+  Float_t wtot = 0. ;
+  Int_t relid[4] ;
+  
+  AliEMCALDigit * digit ;
+
+  AliEMCALGetter * gime = AliEMCALGetter::GetInstance() ; 
+  AliEMCALGeometry * emcalgeom  =  static_cast<AliEMCALGeometry*>(gime->EMCALGeometry());
+  Int_t iDigit;
+
+  for(iDigit=0; iDigit<fMulDigit; iDigit++) {
+    digit = dynamic_cast<AliEMCALDigit *>(digits->At(fDigitsList[iDigit])) ;
+
+    Float_t thetai ;
+    Float_t phii ;
+    emcalgeom->AbsToRelNumbering(digit->GetId(), relid) ;
+    emcalgeom->PosInAlice(relid, thetai, phii);
+    Float_t w = TMath::Max( 0., logWeight + TMath::Log( fEnergyList[iDigit] / fAmp ) ) ;
+    fTheta = fTheta + thetai * w ;
+    fPhi   += (phii * w );
+    wtot  += w ;
+  }
+
+  fTheta /= wtot ;
+  fPhi   /= wtot ;
+
+  fLocPos.SetX(0.)  ;
+  fLocPos.SetY(0.) ;
+  fLocPos.SetZ(0.)  ;
+
+  fLocPosM = 0 ;
+}
+
+//____________________________________________________________________________
+Float_t AliEMCALTowerRecPoint::GetMaximalEnergy(void) const
+{
+  // Finds the maximum energy in the cluster
+  
+  Float_t menergy = 0. ;
+
+  Int_t iDigit;
+
+  for(iDigit=0; iDigit<fMulDigit; iDigit++) {
+    if(fEnergyList[iDigit] > menergy) 
+      menergy = fEnergyList[iDigit] ;
+  }
+  return menergy ;
+}
+
+//____________________________________________________________________________
+Int_t AliEMCALTowerRecPoint::GetMultiplicityAtLevel(const Float_t H) const
+{
+  // Calculates the multiplicity of digits with energy larger than H*energy 
+  
+  Int_t multipl   = 0 ;
+  Int_t iDigit ;
+  for(iDigit=0; iDigit<fMulDigit; iDigit++) {
+
+    if(fEnergyList[iDigit] > H * fAmp) 
+      multipl++ ;
+  }
+  return multipl ;
+}
+
+//____________________________________________________________________________
+Int_t  AliEMCALTowerRecPoint::GetNumberOfLocalMax(Int_t *  maxAt, Float_t * maxAtEnergy,
+                                              Float_t locMaxCut,TClonesArray * digits) const
+{ 
+  // Calculates the number of local maxima in the cluster using fLocalMaxCut as the minimum
+  // energy difference between two local maxima
+
+  AliEMCALDigit * digit ;
+  AliEMCALDigit * digitN ;
+  
+
+  Int_t iDigitN ;
+  Int_t iDigit ;
+
+  for(iDigit = 0; iDigit < fMulDigit; iDigit++)
+    maxAt[iDigit] = (Int_t) digits->At(fDigitsList[iDigit])  ;
+
+  
+  for(iDigit = 0 ; iDigit < fMulDigit; iDigit++) {   
+    if(maxAt[iDigit] != -1) {
+      digit = (AliEMCALDigit *) maxAt[iDigit] ;
+          
+      for(iDigitN = 0; iDigitN < fMulDigit; iDigitN++) {       
+       digitN = (AliEMCALDigit *) digits->At(fDigitsList[iDigitN]) ; 
+       
+       if ( AreNeighbours(digit, digitN) ) {
+         if (fEnergyList[iDigit] > fEnergyList[iDigitN] ) {    
+           maxAt[iDigitN] = -1 ;
+           // but may be digit too is not local max ?
+           if(fEnergyList[iDigit] < fEnergyList[iDigitN] + locMaxCut) 
+             maxAt[iDigit] = -1 ;
+         }
+         else {
+           maxAt[iDigit] = -1 ;
+           // but may be digitN too is not local max ?
+           if(fEnergyList[iDigit] > fEnergyList[iDigitN] - locMaxCut) 
+             maxAt[iDigitN] = -1 ; 
+         } 
+       } // if Areneighbours
+      } // while digitN
+    } // slot not empty
+  } // while digit
+  
+  iDigitN = 0 ;
+  for(iDigit = 0; iDigit < fMulDigit; iDigit++) { 
+    if(maxAt[iDigit] != -1){
+      maxAt[iDigitN] = maxAt[iDigit] ;
+      maxAtEnergy[iDigitN] = fEnergyList[iDigit] ;
+      iDigitN++ ; 
+    }
+  }
+  return iDigitN ;
+}
+//____________________________________________________________________________
+void AliEMCALTowerRecPoint::EvalTime(TClonesArray * digits){
+  
+  Float_t maxE = 0;
+  Int_t maxAt = 0;
+  for(Int_t idig=0; idig < fMulDigit; idig++){
+    if(fEnergyList[idig] > maxE){
+      maxE = fEnergyList[idig] ;
+      maxAt = idig;
+    }
+  }
+  fTime = ((AliEMCALDigit*) digits->At(fDigitsList[maxAt]))->GetTime() ;
+  
+}
+//____________________________________________________________________________
+void AliEMCALTowerRecPoint::Print(Option_t * option) 
+{
+  // Print the list of digits belonging to the cluster
+  
+  cout << "AliEMCALTowerRecPoint: " << endl ;
+
+  Int_t iDigit;
+  cout << " digits # = " ;
+  for(iDigit=0; iDigit<fMulDigit; iDigit++)
+    cout << fDigitsList[iDigit] << "  " ;  
+  cout << endl ;
+  
+  cout << " Energies = " ;
+  for(iDigit=0; iDigit<fMulDigit; iDigit++) 
+    cout  << fEnergyList[iDigit] << "  ";
+  cout << endl ;
+  
+  cout << " Primaries  " ;
+  for(iDigit = 0;iDigit < fMulTrack; iDigit++)
+    cout << fTracksList[iDigit] << " " << endl ;
+       
+  cout << "       Multiplicity    = " << fMulDigit  << endl ;
+  cout << "       Cluster Energy  = " << fAmp << endl ;
+  cout << "       Number of primaries " << fMulTrack << endl ;
+  cout << "       Stored at position " << GetIndexInList() << endl ; 
+}
diff --git a/EMCAL/AliEMCALTowerRecPoint.h b/EMCAL/AliEMCALTowerRecPoint.h
new file mode 100644 (file)
index 0000000..52ea583
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef ALIEMCALTOWERRECPOINT_H
+#define ALIEMCALTOWERRECPOINT_H
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+/* $Id$ */
+
+//_________________________________________________________________________
+//  RecPoint implementation for EMCAL-EMC 
+//  An TowerRecPoint is a cluster of digits   
+//           
+//*-- Author: Dmitri Peressounko (RRC KI & SUBATECH)
+//*-- Author: Yves Schutz (SUBATECH)
+
+// --- ROOT system ---
+
+//#include "TObject.h"
+#include "TArrayI.h"
+// --- Standard library ---
+
+// --- AliRoot header files ---
+
+#include "AliEMCALDigit.h"
+#include "AliEMCALRecPoint.h"
+
+class AliEMCALTowerRecPoint : public AliEMCALRecPoint  {
+
+public:
+
+  AliEMCALTowerRecPoint() ;
+  AliEMCALTowerRecPoint(const char * opt) ;
+  AliEMCALTowerRecPoint(const AliEMCALTowerRecPoint & rp) {
+    // cpy ctor requested by Coding Convention 
+    // but not yet needed
+    assert(0==1) ; 
+  } 
+  virtual ~AliEMCALTowerRecPoint() ;  
+
+  virtual void  AddDigit(AliEMCALDigit & digit, Float_t Energy) ;          // add a digit to the digits list  
+  Int_t       Compare(const TObject * obj) const;                         // method for sorting  
+
+  virtual void  EvalAll(Float_t logWeight,TClonesArray * digits) ;
+  virtual void  EvalGlobalPosition(Float_t logWeight, TClonesArray * digits) ;
+
+  virtual void  ExecuteEvent(Int_t event, Int_t px, Int_t py) const; 
+
+  Float_t         GetCoreEnergy()const {return fCoreEnergy ;}
+  virtual Float_t GetDispersion()const {return fDispersion ;}
+  virtual void    GetElipsAxis(Float_t * lambda)const { lambda[0] = fLambda[0] ;
+                                                        lambda[1] = fLambda[1] ; }
+  Float_t *   GetEnergiesList() const {return fEnergyList ;}       // gets the list of energies making this recpoint
+  Float_t     GetMaximalEnergy(void) const ;                       // get the highest energy in the cluster
+  Int_t       GetMaximumMultiplicity() const {return fMaxDigit ;}  // gets the maximum number of digits allowed
+  Int_t       GetMultiplicity(void) const { return fMulDigit ; }   // gets the number of digits making this recpoint
+  Int_t       GetMultiplicityAtLevel(const Float_t level) const ;  // computes multiplicity of digits with 
+                                                                   // energy above relative level
+  virtual Int_t GetNumberOfLocalMax(Int_t *  maxAt, Float_t * maxAtEnergy,
+                                    Float_t locMaxCut,TClonesArray * digits ) const ; 
+                                                                   // searches for the local maxima 
+  Float_t     GetTime(void) const{return  fTime ; } 
+  Bool_t      IsTower(void) const { return kTRUE ; }                 // true if the recpoint is in EMC
+  Bool_t      IsSortable() const {return kTRUE ; }                 // says that emcrecpoints are sortable objects 
+  void        Print(Option_t * opt = "void") ; 
+
+  AliEMCALTowerRecPoint & operator = (const AliEMCALTowerRecPoint & rvalue)  {
+    // assignement operator requested by coding convention but not needed
+    assert(0==1) ;
+    return *this ; 
+  }
+
+ protected:
+          void  EvalCoreEnergy(Float_t logWeight,TClonesArray * digits) ;             
+  virtual void  EvalLocalPosition(Float_t logWeight,TClonesArray * digits) {;}// computes the position in the EMCAL module 
+  virtual void  EvalDispersion(Float_t logWeight,TClonesArray * digits) ;   // computes the dispersion of the shower
+  virtual void  EvalElipsAxis(Float_t logWeight, TClonesArray * digits );   // computes the axis of shower ellipsoide
+          void  EvalTime( TClonesArray * digits );
+  virtual Bool_t AreNeighbours(AliEMCALDigit * digit1, AliEMCALDigit * digit2 ) const ;
+
+  Float_t fCoreEnergy ;       // energy in a shower core 
+  Float_t fLambda[2] ;        // shower ellipse axes
+  Float_t fDispersion ;       // shower dispersion
+  Float_t *fEnergyList ;      //[fMulDigit] energy of digits
+  Float_t fTime ;             // Time of the digit with maximal energy deposition
+  
+  ClassDef(AliEMCALTowerRecPoint,1)  // Tower RecPoint (cluster)
+
+};
+
+#endif // AliEMCALTOWERRECPOINT_H