AliEMCALRecoUtils: new class for cluster correction during analysis
authorgconesab <gconesab@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 10 Oct 2010 18:37:54 +0000 (18:37 +0000)
committergconesab <gconesab@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 10 Oct 2010 18:37:54 +0000 (18:37 +0000)
AliEMCALGeoUtils: Add a method for cluster position recalculation with different alignment shifts and particle depths

EMCAL/AliEMCALGeoUtils.cxx
EMCAL/AliEMCALGeoUtils.h
EMCAL/AliEMCALRecoUtils.cxx [new file with mode: 0644]
EMCAL/AliEMCALRecoUtils.h [new file with mode: 0644]
EMCAL/EMCALUtilsLinkDef.h
EMCAL/libEMCALUtils.pkg

index 7eebde9..ff5a4cb 100644 (file)
@@ -42,6 +42,7 @@
 #include <TParticle.h>
 #include <TGeoManager.h>
 #include <TGeoMatrix.h>
+#include <TGeoBBox.h>
 #include <TList.h>
 #include <TBrowser.h>
 
@@ -1319,3 +1320,168 @@ void AliEMCALGeoUtils::GetModulePhiEtaIndexInSModuleFromTRUIndex(Int_t itru, Int
   //printf(" GetModulePhiEtaIndexInSModuleFromTRUIndex : itru %2i iphitru %2i ietatru %2i iphiSM %2i ietaSM %2i \n", 
   // itru, iphitru, ietatru, iphiSM, ietaSM);
 }
+
+//__________________________________________________________________________________________________________________
+void AliEMCALGeoUtils::RecalculateTowerPosition(Float_t drow, Float_t dcol, const Int_t sm, Float_t energy, 
+                                                const Int_t particle, const Float_t misaligshifts[15], Float_t global[3]) const
+{ //Transform clusters cell position into global with alternative method, taking into account the depth calculation.
+  //Input are: the tower indeces, 
+  //           supermodule, 
+  //           particle type (photon 0, electron 1, hadron 2 )
+  //           misalignment shifts to global position in case of need.
+  // Federico.Ronchetti@cern.ch
+
+  if(gGeoManager){
+    //Recover some stuff
+    
+    TGeoNode        *geoXEn1;         
+    TGeoNodeMatrix  *geoSM[4];        
+    TGeoVolume      *geoSMVol[4];     
+    TGeoShape       *geoSMShape[4];    
+    TGeoBBox        *geoBox[4];        
+    TGeoMatrix      *geoSMMatrix[4];       
+    
+    gGeoManager->cd("ALIC_1/XEN1_1");
+    geoXEn1 = gGeoManager->GetCurrentNode();
+    for(int iSM = 0; iSM < 4; iSM++) {  
+      geoSM[iSM]       = dynamic_cast<TGeoNodeMatrix *>(geoXEn1->GetDaughter(iSM));
+      geoSMVol[iSM]    = geoSM[iSM]->GetVolume(); 
+      geoSMShape[iSM]  = geoSMVol[iSM]->GetShape();
+      geoBox[iSM]      = dynamic_cast<TGeoBBox *>(geoSMShape[iSM]);
+      geoSMMatrix[iSM] = geoSM[iSM]->GetMatrix();
+    }
+    
+    if(sm % 2 == 0) {
+      dcol = 47. - dcol;
+      drow = 23. - drow;
+    }
+    
+    Int_t i = 0; // one always needs "i"
+    Int_t istrip = 0;
+    Float_t z0 = 0;
+    Float_t zb = 0;
+    Float_t z_is = 0;
+    Float_t d = 0;
+    
+    Float_t x,y,z; // return variables in terry's RF
+    
+    //***********************************************************
+    //Do not like this: too many hardcoded values, is it no stored somewhere else?
+    //                : need more comments in the code 
+    //***********************************************************
+    
+    Float_t dz = 6.0;   // base cell width in eta
+    Float_t dx = 6.004; // base cell width in phi
+    
+    // parameters for shower depth calculation
+    Float_t x0  = 1.23;
+    Float_t ecr = 8;
+    Float_t cj  = 0.;
+    
+    //Float_t L = 26.04; // active tower length for hadron (lead+scint+paper)
+    // we use the geant numbers 13.87*2=27.74
+    Float_t teta1 = 0.;
+    
+    i = sm;
+    
+    if (dcol >= 47.5 || dcol<-0.5) {
+      exit(0);
+    }
+    
+    if (drow >= 23.5 || drow<-0.5) {
+      exit(0);
+    }
+    if (sm > 13 || sm <0) {
+      exit(0);
+    }
+    
+    
+    //boxes anc. here
+    Float_t l = geoBox[i]->GetDX()*2 ;
+    
+    energy = energy * 1000; // converting to MEV
+    
+    switch ( particle )
+    {
+      case 0:
+        cj = + 0.5; // photon
+        d  = x0 * TMath::Log( (energy / ecr) + cj);
+        break;
+        
+      case 1:
+        cj = - 0.5; // electron 
+        d = x0 * TMath::Log( (energy / ecr) + cj);
+        break;
+        
+      case 2:
+        // hadron 
+        d = 0.5 * l;
+        break;
+        
+      default:
+        cj = + 0.5; // photon
+        d = x0 * TMath::Log( (energy / ecr) + cj);
+    }
+    
+    istrip = int ((dcol+0.5)/2);
+    
+    // tapering angle
+    teta1 = TMath::DegToRad() * istrip * 1.5;
+    
+    // calculation of module corner along z 
+    // as a function of strip
+    
+    for (int is=0; is<= istrip; is++) {
+      
+      teta1 = TMath::DegToRad() * (is+1) * 1.5;
+      z_is = z_is + 2*dz*(TMath::Sin(teta1)*TMath::Tan(teta1) + TMath::Cos(teta1));
+      
+    }
+    
+    z0 = dz*(dcol-2*istrip+0.5);
+    zb = (2*dz-z0-d*TMath::Tan(teta1));
+    
+    z = z_is - zb*TMath::Cos(teta1);
+    y = d/TMath::Cos(teta1) + zb*TMath::Sin(teta1);
+    
+    x = (drow + 0.5)*dx;
+    
+    // moving the origin from terry's RF
+    // to the GEANT one
+    
+    double xx =  y - geoBox[i]->GetDX();
+    double yy = -x + geoBox[i]->GetDY() - 0.512; //to center the towers in the box
+    double zz =  z - geoBox[i]->GetDZ() + 1; //gap at z = 0
+    
+    const double localIn[3] = {xx, yy, zz};
+    double dglobal[3];
+    geoSMMatrix[i]->LocalToMaster(localIn, dglobal);
+    
+    
+    //hardcoded global shifts
+    if(sm == 2 || sm == 3) {//sector 1
+      global[0] = dglobal[0] + misaligshifts[3]*TMath::Sin(TMath::DegToRad()*20); // misaligshifts[3] = - 7.5
+      global[1] = dglobal[1] + misaligshifts[4]*TMath::Cos(TMath::DegToRad()*20); // misaligshifts[4] = + 7.5
+      global[2] = dglobal[2] + misaligshifts[5];                                  // misaligshifts[6] = 2.
+    }
+    else if(sm == 0 || sm == 1){//sector 0
+      global[0] = dglobal[0] + misaligshifts[0]; // misaligshifts[0] = 0.8
+      global[1] = dglobal[1] + misaligshifts[1]; // misaligshifts[1] = 8.3
+      global[2] = dglobal[2] + misaligshifts[2]; // misaligshifts[2] = 1.
+    }
+    else {
+      AliInfo("Careful, correction not implemented yet!");
+      global[0] = dglobal[0] ;
+      global[1] = dglobal[1] ;
+      global[2] = dglobal[2] ;
+    }
+    
+    
+  }
+  else{
+    AliFatal("Geometry boxes information, check that geometry.root is loaded\n");
+  }
+  
+}
+
+
index f10eb78..b9c0a8c 100644 (file)
@@ -162,7 +162,10 @@ public:
          else AliFatal(Form("Wrong supermodule index -> %d",smod));
   }
        
-protected:
+  //Alternate geometry that allows to calculate tower position for different particles and different alignments
+  void RecalculateTowerPosition(Float_t drow, Float_t dcol, const Int_t sm, Float_t energy, 
+                                     const Int_t particle, const Float_t misaligshifts[15], Float_t global[3]) const;
+  
   //Returns shift-rotational matrixes for different volumes
   const TGeoHMatrix * GetMatrixForSuperModule(Int_t smod)const ;
        
diff --git a/EMCAL/AliEMCALRecoUtils.cxx b/EMCAL/AliEMCALRecoUtils.cxx
new file mode 100644 (file)
index 0000000..efea718
--- /dev/null
@@ -0,0 +1,248 @@
+/**************************************************************************
+ * 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: AliEMCALRecoUtils.cxx 33808 2009-07-15 09:48:08Z gconesab $ */
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Class AliEMCALRecoUtils
+// Some utilities to recalculate the cluster position or energy linearity
+//
+//
+// Author:  Gustavo Conesa (LPSC- Grenoble) 
+///////////////////////////////////////////////////////////////////////////////
+
+// --- standard c ---
+
+// standard C++ includes
+//#include <Riostream.h>
+
+// ROOT includes
+
+// STEER includes
+#include "AliEMCALRecoUtils.h"
+#include "AliEMCALGeoUtils.h"
+#include "AliVCluster.h"
+#include "AliVCaloCells.h"
+#include "AliLog.h"
+
+ClassImp(AliEMCALRecoUtils)
+  
+//______________________________________________
+AliEMCALRecoUtils::AliEMCALRecoUtils():
+  fNonLinearityFunction (kPi0GammaGamma)
+{
+//
+  // Constructor.
+  // Initialize all constant values which have to be used
+  // during Reco algorithm execution
+  //
+  
+  for(Int_t i = 0; i < 15 ; i++) fMisalShift[i] = 0.;  
+  for(Int_t i = 0; i < 6  ; i++) fNonLinearityParams[i] = 0.; 
+  //By default kPi0GammaGamma case
+  fNonLinearityParams[0] = 0.1457/0.1349766/1.038;
+  fNonLinearityParams[1] = -0.02024/0.1349766/1.038;
+  fNonLinearityParams[2] = 1.046;
+  
+}
+
+//______________________________________________________________________
+AliEMCALRecoUtils::AliEMCALRecoUtils(const AliEMCALRecoUtils & reco) 
+: TNamed(reco), fNonLinearityFunction(reco.fNonLinearityFunction)
+{
+  //Copy ctor
+  
+  for(Int_t i = 0; i < 15 ; i++) fMisalShift[i]         = reco.fMisalShift[i];  
+  for(Int_t i = 0; i < 6  ; i++) fNonLinearityParams[i] = reco.fNonLinearityParams[i]; 
+}
+
+
+//______________________________________________________________________
+AliEMCALRecoUtils & AliEMCALRecoUtils::operator = (const AliEMCALRecoUtils & reco) 
+{
+  //Assignment operator
+  
+  if(this == &reco)return *this;
+  ((TNamed *)this)->operator=(reco);
+
+  fNonLinearityFunction = reco.fNonLinearityFunction;
+  for(Int_t i = 0; i < 15 ; i++) fMisalShift[i]         = reco.fMisalShift[i];  
+  for(Int_t i = 0; i < 6  ; i++) fNonLinearityParams[i] = reco.fNonLinearityParams[i]; 
+  
+  return *this;
+}
+
+
+//__________________________________________________
+Float_t AliEMCALRecoUtils::CorrectClusterEnergyLinearity(AliVCluster* cluster){
+// Correct cluster energy from non linearity functions
+  Float_t energy = cluster->E();
+  
+  switch (fNonLinearityFunction) {
+      
+    case kPi0MC:
+      //Non-Linearity correction (from MC with function ([0]*exp(-[1]/E))+(([2]/([3]*2.*TMath::Pi())*exp(-(E-[4])^2/(2.*[3]^2)))))
+      //Double_t par0 = 1.001;
+      //Double_t par1 = -0.01264;
+      //Double_t par2 = -0.03632;
+      //Double_t par3 = 0.1798;
+      //Double_t par4 = -0.522;
+       energy /= (fNonLinearityParams[0]*exp(-fNonLinearityParams[1]/energy))+
+                  ((fNonLinearityParams[2]/(fNonLinearityParams[3]*2.*TMath::Pi())*
+                    exp(-(energy-fNonLinearityParams[4])*(energy-fNonLinearityParams[4])/(2.*fNonLinearityParams[3]*fNonLinearityParams[3]))));
+      break;
+      
+    case kPi0GammaGamma:
+
+      //Non-Linearity correction (from Olga Data with function p0+p1*exp(-p2*E))
+      //Double_t par0 = 0.1457;
+      //Double_t par1 = -0.02024;
+      //Double_t par2 = 1.046;
+      energy /= (fNonLinearityParams[0]+fNonLinearityParams[1]*exp(-fNonLinearityParams[2]*energy)); //Olga function
+      break;
+      
+    case kPi0GammaConversion:
+      
+      //Non-Linearity correction (Nicolas from Dimitri Data with function C*[1-a*exp(-b*E)])
+      //Double_t C = 0.139393/0.1349766;
+      //Double_t a = 0.0566186;
+      //Double_t b = 0.982133;
+      energy /= fNonLinearityParams[0]*(1-fNonLinearityParams[1]*exp(-fNonLinearityParams[2]*energy));
+      
+      break;
+      
+    case kNoCorrection:
+      AliDebug(2,"No correction on the energy\n");
+      break;
+      
+  }
+  
+  return energy;
+
+}
+
+//__________________________________________________
+void AliEMCALRecoUtils::GetMaxEnergyCell(AliEMCALGeoUtils *geom, AliVCaloCells* cells, AliVCluster* clu, Int_t & absId,  Int_t& iSupMod, Int_t& ieta, Int_t& iphi)
+{
+  //For a given CaloCluster gets the absId of the cell 
+  //with maximum energy deposit.
+  
+  Double_t eMax        = -1.;
+  Double_t eCell       = -1.;
+  Int_t    cellAbsId   = -1 ;
+  Int_t iTower  = -1;
+  Int_t iIphi   = -1;
+  Int_t iIeta   = -1;
+       
+  for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
+     cellAbsId = clu->GetCellAbsId(iDig);
+     eCell     = cells->GetCellAmplitude(cellAbsId);
+     if(eCell > eMax)  { 
+      eMax  = eCell; 
+      absId = cellAbsId;
+      //printf("\t new max: cell %d, e %f, ecell %f\n",maxId, eMax,eCell);
+    }
+  }// cell loop
+  
+  //Get from the absid the supermodule, tower and eta/phi numbers
+  geom->GetCellIndex(absId,iSupMod,iTower,iIphi,iIeta); 
+  //Gives SuperModule and Tower numbers
+  geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
+                                         iIphi, iIeta,iphi,ieta);    
+  
+}
+
+//__________________________________________________
+void AliEMCALRecoUtils::RecalculateClusterPosition(AliEMCALGeoUtils *geom, AliVCaloCells* cells, AliVCluster* clu, Int_t iParticle)
+{
+  //For a given CaloCluster recalculates the position for a given set of misalignment shifts and puts it again in the CaloCluster.
+  
+  Double_t eMax       = -1.;
+  Double_t eCell      = -1.;
+  Int_t    cellAbsId  = -1;
+       
+  Int_t maxId   = -1;
+  Int_t iTower  = -1;
+  Int_t iIphi   = -1;
+  Int_t iIeta   = -1;
+       Int_t iSupMod = -1;
+  Int_t iphi = -1, ieta =-1;
+  
+  Float_t clEnergy = clu->E(); //Energy already recalibrated previously.
+  Float_t weight = 0., weightedCol = 0., weightedRow = 0., totalWeight=0.;
+  Bool_t  areInSameSM = kTRUE; //exclude clusters with cells in different SMs for now
+  Int_t   startingSM = -1;
+  
+  for (Int_t iDig=0; iDig< clu->GetNCells(); iDig++) {
+    cellAbsId = clu->GetCellAbsId(iDig);
+    geom->GetCellIndex(cellAbsId,iSupMod,iTower,iIphi,iIeta); 
+    geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,iIphi, iIeta,iphi,ieta);                  
+    if     (iDig==0)  startingSM = iSupMod;
+    else if(iSupMod != startingSM) areInSameSM = kFALSE;
+    
+    eCell  = cells->GetCellAmplitude(cellAbsId);
+    
+    weight = TMath::Log(eCell/clEnergy) + 4;
+    if(weight < 0) weight = 0;
+    totalWeight += weight;
+    weightedCol += ieta*weight;
+    weightedRow += iphi*weight;
+    
+    //printf("Max cell? cell %d, amplitude org %f, fraction %f, recalibration %f, amplitude new %f \n",cellAbsId, cells->GetCellAmplitude(cellAbsId), fraction, recalFactor, eCell) ;
+    
+    if(eCell > eMax)  { 
+      eMax  = eCell; 
+      maxId = cellAbsId;
+      //printf("\t new max: cell %d, e %f, ecell %f\n",maxId, eMax,eCell);
+    }
+  }// cell loop
+  
+  //Get from the absid the supermodule, tower and eta/phi numbers  
+  geom->GetCellIndex(maxId,iSupMod,iTower,iIphi,iIeta); 
+  //Gives SuperModule and Tower numbers
+  geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
+                                         iIphi, iIeta,iphi,ieta);  
+  
+  Float_t xyzNew[]={0.,0.,0.};
+  if(areInSameSM == kTRUE) {
+    //printf("In Same SM\n");
+    weightedCol = weightedCol/totalWeight;
+    weightedRow = weightedRow/totalWeight;
+    geom->RecalculateTowerPosition(weightedRow, weightedCol, iSupMod, clEnergy, iParticle, fMisalShift, xyzNew); 
+  }
+  else {
+    //printf("In Different SM\n");
+    geom->RecalculateTowerPosition(iphi,        ieta,        iSupMod, clEnergy, iParticle, fMisalShift, xyzNew); 
+  }
+  clu->SetPosition(xyzNew);
+
+  
+  //printf("\t Max : cell %d, iSupMod %d, ieta %d, iphi %d \n",maxId,iSupMod, ieta,iphi);
+  
+}
+
+//__________________________________________________
+void AliEMCALRecoUtils::Print(const Option_t *) const 
+{
+  // Print Parameters
+  
+  printf("AliEMCALRecoUtils Settings: \n");
+  printf("Misalignment shifts\n");
+  for(Int_t i=0; i<5; i++) printf("\t sector %d, (dx,dy,dz)=(%f,%f,%f)\n",i, fMisalShift[i*3],fMisalShift[i*3+1],fMisalShift[i*3+2]);
+  printf("Non linearity function %d, parameters:\n", fNonLinearityFunction);
+  for(Int_t i=0; i<6; i++) printf("param[%d]=%f\n",i, fNonLinearityParams[i]);
+    
+}
diff --git a/EMCAL/AliEMCALRecoUtils.h b/EMCAL/AliEMCALRecoUtils.h
new file mode 100644 (file)
index 0000000..9f2e1bf
--- /dev/null
@@ -0,0 +1,83 @@
+#ifndef ALIEMCALRECOUTILS_H
+#define ALIEMCALRECOUTILS_H
+
+/* $Id: AliEMCALRecoUtils.h 33808 2009-07-15 09:48:08Z gconesab $ */
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Class AliEMCALRecoUtils
+// Some utilities to recalculate the cluster position or energy linearity
+//
+//
+// Author:  Gustavo Conesa (LPSC- Grenoble) 
+///////////////////////////////////////////////////////////////////////////////
+
+//Root includes
+#include "TNamed.h"
+
+//AliRoot includes
+class AliVCluster;
+class AliVCaloCells;
+#include "AliLog.h"
+class AliEMCALGeoUtils;
+
+class AliEMCALRecoUtils : public TNamed {
+  
+public:
+  
+  AliEMCALRecoUtils();
+  AliEMCALRecoUtils(const AliEMCALRecoUtils&); 
+  AliEMCALRecoUtils& operator=(const AliEMCALRecoUtils&); 
+  virtual ~AliEMCALRecoUtils() {;}
+  
+  enum NonlinearityFunctions{kPi0MC=0,kPi0GammaGamma=1,kPi0GammaConversion=2,kNoCorrection=3};
+  
+  //Position recalculation
+  void     RecalculateClusterPosition(AliEMCALGeoUtils *geom, AliVCaloCells* cells, AliVCluster* clu, const Int_t iParticle); 
+  void     GetMaxEnergyCell(AliEMCALGeoUtils *geom, AliVCaloCells* cells, AliVCluster* clu, 
+                            Int_t & absId,  Int_t& iSupMod, Int_t& ieta, Int_t& iphi);
+  
+  Float_t  GetMisalShift(const Int_t i) const {
+    if(i < 15 ){return fMisalShift[i]; }
+    else { AliInfo(Form("Index %d larger than 15, do nothing\n",i)); return 0.;}
+  }
+  Float_t  *GetMisalShiftArray() {return fMisalShift; }
+
+  void     SetMisalShift(const Int_t i, const Float_t shift) {
+    if(i < 15 ){fMisalShift[i] = shift; }
+    else { AliInfo(Form("Index %d larger than 15, do nothing\n",i));}
+  }
+  void     SetMisalShiftArray(Float_t * misal) 
+  { for(Int_t i = 0; i < 15; i++)fMisalShift[i] = misal[i]; }
+
+  //Non Linearity
+  
+  Float_t CorrectClusterEnergyLinearity(AliVCluster* clu);
+  
+  Float_t  GetNonLinearityParam(const Int_t i) const {
+    if(i < 6 ){return fNonLinearityParams[i]; }
+    else { AliInfo(Form("Index %d larger than 6, do nothing\n",i)); return 0.;}
+  }
+  void     SetNonLinearityParam(const Int_t i, const Float_t param) {
+    if(i < 6 ){fNonLinearityParams[i] = param; }
+    else { AliInfo(Form("Index %d larger than 6, do nothing\n",i));}
+  }
+  
+  Int_t GetNonLinearityFunction() const {return fNonLinearityFunction;}
+  void  SetNonLinearityFunction(Int_t fun) {fNonLinearityFunction = fun ;}
+  
+  void Print(const Option_t*) const;
+  
+private:
+  
+  Float_t fMisalShift[15];        // Shift parameters
+  Int_t   fNonLinearityFunction;  // Non linearity function choice
+  Float_t fNonLinearityParams[6]; // Parameters for the non linearity function
+
+  ClassDef(AliEMCALRecoUtils, 1)
+  
+};
+
+#endif // ALIEMCALRECOUTILS_H
+
+
index e8d8c90..f01595c 100644 (file)
@@ -6,8 +6,8 @@
 
 #pragma link C++ class AliEMCALGeoParams+;
 #pragma link C++ class AliEMCALGeoUtils+;
-#pragma link C++ class AliEMCALEMCGeometry+;
 #pragma link C++ class AliEMCALGeometry+;
+#pragma link C++ class AliEMCALEMCGeometry+;
 #pragma link C++ class AliEMCALShishKebabTrd1Module+;
 #pragma link C++ class AliEMCALPIDUtils+;
 #pragma link C++ class AliCaloNeuralFit+;
@@ -20,5 +20,6 @@
 #pragma link C++ class AliCaloRawAnalyzerLMS+;
 #pragma link C++ class AliCaloPeakFinderVectors+;
 #pragma link C++ class AliEMCALHistoUtilities+;
+#pragma link C++ class AliEMCALRecoUtils+;
 
 #endif
index d9d7e54..70a857e 100644 (file)
@@ -3,9 +3,9 @@
 SRCS = \
 AliEMCALGeoParams.cxx \
 AliEMCALGeoUtils.cxx \
+AliEMCALGeometry.cxx \
 AliEMCALEMCGeometry.cxx  \
 AliEMCALShishKebabTrd1Module.cxx \
-AliEMCALGeometry.cxx  \
 AliEMCALPIDUtils.cxx \
 AliCaloNeuralFit.cxx \
 AliCaloRawAnalyzer.cxx \
@@ -16,17 +16,18 @@ AliCaloRawAnalyzerCrude.cxx \
 AliCaloRawAnalyzerLMS.cxx \
 AliCaloRawAnalyzerNN.cxx \
 AliCaloPeakFinderVectors.cxx \
-AliEMCALHistoUtilities.cxx 
+AliEMCALHistoUtilities.cxx \
+AliEMCALRecoUtils.cxx
 
 HDRS:= $(SRCS:.cxx=.h)  AliCaloConstants.h
 
 DHDR= EMCALUtilsLinkDef.h
 
-EXPORT:=AliEMCALGeoParams.h AliEMCALGeoUtils.h AliEMCALEMCGeometry.h AliEMCALShishKebabTrd1Module.h AliEMCALPIDUtils.h AliCaloNeuralFit.h AliCaloRawAnalyzer.h AliCaloBunchInfo.h AliCaloFitResults.h AliCaloRawAnalyzerCrude.h AliCaloRawAnalyzerLMS.h AliCaloRawAnalyzerPeakFinder.h AliCaloRawAnalyzerNN.h AliEMCALGeometry.h
+EXPORT:=AliEMCALGeoParams.h AliEMCALGeoUtils.h AliEMCALEMCGeometry.h AliEMCALShishKebabTrd1Module.h AliEMCALPIDUtils.h AliCaloNeuralFit.h AliCaloRawAnalyzer.h AliCaloBunchInfo.h AliCaloFitResults.h AliCaloRawAnalyzerCrude.h AliCaloRawAnalyzerLMS.h AliCaloRawAnalyzerPeakFinder.h AliCaloRawAnalyzerNN.h AliEMCALGeometry.h AliEMCALRecoUtils.h
 
 CXXFLAGS+=-D__EMCALUTIL__
 
 ifeq (win32gcc,$(ALICE_TARGET))
 PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) \
-                         -L$(ROOTLIBDIR) -lGeom 
+                         -L$(ROOTLIBDIR) -lGeom -lSTEERBase -lESD -lAOD
 endif