AliRoot Core  edcc906 (edcc906)
AliEMCALClusterizerNxN.cxx
Go to the documentation of this file.
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  * *
4  * Author: The ALICE Off-line Project. *
5  * Contributors are mentioned in the code where appropriate. *
6  * *
7  * Permission to use, copy, modify and distribute this software and its *
8  * documentation strictly for non-commercial purposes is hereby granted *
9  * without fee, provided that the above copyright notice appears in all *
10  * copies and that both the copyright notice and this permission notice *
11  * appear in the supporting documentation. The authors make no claims *
12  * about the suitability of this software for any purpose. It is *
13  * provided "as is" without express or implied warranty. *
14  **************************************************************************/
15 
16 // --- ROOT system ---
17 #include <TMath.h>
18 #include <TMinuit.h>
19 #include <TTree.h>
20 #include <TBenchmark.h>
21 #include <TBrowser.h>
22 #include <TROOT.h>
23 #include <TClonesArray.h>
24 
25 // --- Standard library ---
26 #include <cassert>
27 
28 // --- AliRoot header files ---
29 #include "AliLog.h"
30 #include "AliEMCALClusterizerNxN.h"
31 #include "AliEMCALRecPoint.h"
32 #include "AliEMCALDigit.h"
33 #include "AliEMCALGeometry.h"
34 #include "AliCaloCalibPedestal.h"
35 #include "AliEMCALCalibData.h"
36 #include "AliEMCALCalibTime.h"
37 #include "AliESDCaloCluster.h"
38 #include "AliEMCALUnfolding.h"
39 
41 ClassImp(AliEMCALClusterizerNxN) ;
43 
46 //____________________________________________________________________________
48  : AliEMCALClusterizer(), fNRowDiff(1), fNColDiff(1), fEnergyGrad(0)
49 { }
50 
55 //____________________________________________________________________________
57  : AliEMCALClusterizer(geometry), fNRowDiff(1), fNColDiff(1), fEnergyGrad(0)
58 { }
59 
67 //____________________________________________________________________________
69  AliEMCALCalibData * calib,
70  AliEMCALCalibTime * calibt,
71  AliCaloCalibPedestal * caloped)
72 : AliEMCALClusterizer(geometry, calib, calibt, caloped),
74 { }
75 
78 //____________________________________________________________________________
80 { }
81 
85 //____________________________________________________________________________
87 {
88  if (strstr(option,"tim"))
89  gBenchmark->Start("EMCALClusterizer");
90 
91  if (strstr(option,"print"))
92  Print("");
93 
94  // Get calibration parameters from file or digitizer default values.
96 
97  //Get dead channel map from file or digitizer default values.
99 
100  MakeClusters(); //only the real clusters
101 
102  if (fToUnfold)
103  {
106  }
107 
108  // Evaluate position, dispersion and other RecPoint properties for EC section
109  for (Int_t index = 0; index < fRecPoints->GetEntries(); index++)
110  {
111  AliEMCALRecPoint * rp = dynamic_cast<AliEMCALRecPoint *>(fRecPoints->At(index));
112  if (rp) {
114  AliDebug(5, Form("MAX INDEX %d ", rp->GetMaximalEnergyIndex()));
115  //For each rec.point set the distance to the nearest bad crystal
116  if (fCaloPed)
118  }
119  }
120 
121  fRecPoints->Sort();
122 
123  for (Int_t index = 0; index < fRecPoints->GetEntries(); index++)
124  {
125  AliEMCALRecPoint *rp = dynamic_cast<AliEMCALRecPoint *>(fRecPoints->At(index));
126  if (rp)
127  {
128  rp->SetIndexInList(index);
129  }
130  else AliFatal("RecPoint NULL!!");
131  }
132 
133  if (fTreeR)
134  fTreeR->Fill();
135 
136  if (strstr(option,"deb") || strstr(option,"all"))
137  PrintRecPoints(option);
138 
139  AliDebug(1,Form("EMCAL Clusterizer found %d Rec Points",fRecPoints->GetEntriesFast()));
140 
141  if (strstr(option,"tim"))
142  {
143  gBenchmark->Stop("EMCALClusterizer");
144  printf("Exec took %f seconds for Clusterizing",
145  gBenchmark->GetCpuTime("EMCALClusterizer"));
146  }
147 }
148 
157 //____________________________________________________________________________
158 Int_t AliEMCALClusterizerNxN::AreNeighbours(AliEMCALDigit * d1, AliEMCALDigit * d2, Bool_t & shared) const
159 {
160  if (fEnergyGrad)
161  { //false by default
162  if (d2->GetCalibAmp()>d1->GetCalibAmp())
163  return 3; // energy of neighboring cell should be smaller in order to become a neighbor
164  }
165 
166  Int_t nSupMod1=0, nModule1=0, nIphi1=0, nIeta1=0, iphi1=0, ieta1=0;
167  Int_t nSupMod2=0, nModule2=0, nIphi2=0, nIeta2=0, iphi2=0, ieta2=0;
168  Int_t rowdiff=0, coldiff=0;
169 
170  shared = kFALSE;
171 
172  fGeom->GetCellIndex(d1->GetId(), nSupMod1,nModule1,nIphi1,nIeta1);
173  fGeom->GetCellIndex(d2->GetId(), nSupMod2,nModule2,nIphi2,nIeta2);
174  fGeom->GetCellPhiEtaIndexInSModule(nSupMod1,nModule1,nIphi1,nIeta1, iphi1,ieta1);
175  fGeom->GetCellPhiEtaIndexInSModule(nSupMod2,nModule2,nIphi2,nIeta2, iphi2,ieta2);
176 
177  //If different SM, check if they are in the same phi, then consider cells close to eta=0 as neighbours; May 2010
178  if (nSupMod1 != nSupMod2 )
179  {
180  //Check if the 2 SM are in the same PHI position (0,1), (2,3), ...
181  Float_t smPhi1 = fGeom->GetEMCGeometry()->GetPhiCenterOfSM(nSupMod1);
182  Float_t smPhi2 = fGeom->GetEMCGeometry()->GetPhiCenterOfSM(nSupMod2);
183 
184  if (!TMath::AreEqualAbs(smPhi1, smPhi2, 1e-3)) return 2; //Not phi rack equal, not neighbours
185 
186  // In case of a shared cluster, index of SM in C side, columns start at 48 and ends at 48*2
187  // C Side impair SM, nSupMod%2=1; A side pair SM nSupMod%2=0
188  if (nSupMod1%2) ieta1+=AliEMCALGeoParams::fgkEMCALCols;
190 
191  shared = kTRUE; // maybe a shared cluster, we know this later, set it for the moment.
192 
193  }//Different SM, same phi
194 
195  rowdiff = TMath::Abs(iphi1 - iphi2);
196  coldiff = TMath::Abs(ieta1 - ieta2);
197 
198  // neighbours +-1 in col and row
199  if ( TMath::Abs(coldiff) <= fNColDiff && TMath::Abs(rowdiff) <= fNRowDiff)
200  {
201 
202  AliDebug(9, Form("AliEMCALClusterizerNxN::AreNeighbours(): id1=%d, (row %d, col %d) ; id2=%d, (row %d, col %d), shared %d \n",
203  d1->GetId(), iphi1,ieta1, d2->GetId(), iphi2,ieta2, shared));
204 
205  return 1;
206  }//Neighbours
207  else
208  {
209  AliDebug(9, Form("NOT AliEMCALClusterizerNxN::AreNeighbours(): id1=%d, (row %d, col %d) ; id2=%d, (row %d, col %d), shared %d \n",
210  d1->GetId(), iphi1,ieta1, d2->GetId(), iphi2,ieta2, shared));
211  shared = kFALSE;
212  return 2;
213  }//Not neighbours
214 }
215 
218 //____________________________________________________________________________
220 {
221  if (fGeom==0)
222  AliFatal("Did not get geometry from EMCALLoader");
223 
225  fRecPoints->Delete();
226 
227  // Set up TObjArray with pointers to digits to work on, calibrate digits
228  TObjArray digitsC;
229  TIter nextdigit(fDigitsArr);
230  AliEMCALDigit *digit = 0;
231  while ( (digit = static_cast<AliEMCALDigit*>(nextdigit())) )
232  {
233  Float_t dEnergyCalibrated = digit->GetAmplitude();
234  Float_t time = digit->GetTime();
235  Calibrate(dEnergyCalibrated,time ,digit->GetId());
236  digit->SetCalibAmp(dEnergyCalibrated);
237  digit->SetTime(time);
238  digitsC.AddLast(digit);
239  }
240 
241  TIter nextdigitC(&digitsC);
242 
243  AliDebug(1,Form("MakeClusters: Number of digits %d -> (e %f)\n",
244  fDigitsArr->GetEntries(),fMinECut));
245 
246  Bool_t bDone = kFALSE;
247  while ( bDone != kTRUE )
248  {
249  // first sort the digits:
250  Int_t iMaxEnergyDigit = -1;
251  Float_t dMaxEnergyDigit = -1;
252  AliEMCALDigit *pMaxEnergyDigit = 0;
253 
254  nextdigitC.Reset();
255  while ( (digit = static_cast<AliEMCALDigit *>(nextdigitC())) )
256  { // scan over the list of digitsC
257  Float_t dEnergyCalibrated = digit->GetCalibAmp();
258  Float_t time = digit->GetTime();
259  if (fGeom->CheckAbsCellId(digit->GetId()) &&
260  dEnergyCalibrated > fMinECut &&
261  time < fTimeMax &&
262  time > fTimeMin ) // no threshold by default!
263  { // needs to be set in OCDB!
264  if (dEnergyCalibrated > dMaxEnergyDigit)
265  {
266  dMaxEnergyDigit = dEnergyCalibrated;
267  iMaxEnergyDigit = digit->GetId();
268  pMaxEnergyDigit = digit;
269  }
270  }
271  }
272 
273  if (iMaxEnergyDigit < 0 || digitsC.GetEntries() <= 0)
274  {
275  bDone = kTRUE;
276  continue;
277  }
278 
279  AliDebug (2, Form("Max digit found: %1.5f AbsId: %d", dMaxEnergyDigit, iMaxEnergyDigit));
280 
281  // keep the candidate digits in a list
282  TList clusterDigitList;
283  clusterDigitList.SetOwner(kFALSE);
284  clusterDigitList.AddLast(pMaxEnergyDigit);
285 
286  Double_t clusterCandidateEnergy = dMaxEnergyDigit;
287 
288  // now loop over the rest of the digits and cluster into NxN cluster
289  // we do not actually cluster yet: we keep them in the list clusterDigitList
290  nextdigitC.Reset();
291  while ( (digit = static_cast<AliEMCALDigit *>(nextdigitC())) )
292  { // scan over the list of digitsC
293  if (digit == pMaxEnergyDigit) continue;
294  Float_t dEnergyCalibrated = digit->GetCalibAmp();
295 
296  AliDebug(5, Form("-> Digit ENERGY: %1.5f", dEnergyCalibrated));
297 
298  if (fGeom->CheckAbsCellId(digit->GetId()) && dEnergyCalibrated > 0.0 )
299  {
300  Float_t time = pMaxEnergyDigit->GetTime(); //Time or TimeR?
301  if (TMath::Abs(time - digit->GetTime()) > fTimeCut ) continue; //Time or TimeR?
302  Bool_t shared = kFALSE; //cluster shared by 2 SuperModules?
303  if (AreNeighbours(pMaxEnergyDigit, digit, shared) == 1) // call (digit,digitN) in THAT order !!!!!
304  {
305  clusterDigitList.AddLast(digit);
306  clusterCandidateEnergy += dEnergyCalibrated;
307  }
308  }
309  }// loop over the next digits
310 
311  // start a cluster here only if a cluster energy is larger than clustering threshold
312  AliDebug(5, Form("Clusterization threshold is %f MeV", fECAClusteringThreshold));
313 
314  if (clusterCandidateEnergy > fECAClusteringThreshold)
315  {
316  if (fNumberOfECAClusters >= fRecPoints->GetSize())
317  fRecPoints->Expand(2*fNumberOfECAClusters+1);
318 
319  (*fRecPoints)[fNumberOfECAClusters] = new AliEMCALRecPoint("") ;
320  AliEMCALRecPoint *recPoint = dynamic_cast<AliEMCALRecPoint *>( fRecPoints->At(fNumberOfECAClusters) ) ;
321 
322  // AliEMCALRecPoint *recPoint = new AliEMCALRecPoint("");
323  // fRecPoints->AddAt(recPoint, fNumberOfECAClusters);
324  // recPoint = static_cast<AliEMCALRecPoint *>(fRecPoints->At(fNumberOfECAClusters));
325  if (recPoint)
326  {
329 
330  AliDebug(9, Form("Number of cells per cluster (max is 9!): %d", clusterDigitList.GetEntries()));
331 
332  for (Int_t idig = 0; idig < clusterDigitList.GetEntries(); idig++)
333  {
334  digit = (AliEMCALDigit*)clusterDigitList.At(idig);
335  AliDebug(5, Form(" Adding digit %d", digit->GetId()));
336  // note: this way the sharing info is lost!
337  recPoint->AddDigit(*digit, digit->GetCalibAmp(), kFALSE); //Time or TimeR?
338  digitsC.Remove(digit);
339  }
340  }// recpoint
341  }
342  else
343  {
344  // we do not want to start clustering in the same spot!
345  // but in this case we may NOT reuse this seed for another cluster!
346  // need a better bookeeping?
347  digitsC.Remove(pMaxEnergyDigit);
348  }
349 
350  AliDebug (2, Form("Number of digits left: %d", digitsC.GetEntries()));
351  } // while ! done
352 
353  AliDebug(1,Form("total no of clusters %d from %d digits",fNumberOfECAClusters,fDigitsArr->GetEntriesFast()));
354 }
Bool_t CheckAbsCellId(Int_t absId) const
void EvalDistanceToBadChannels(AliCaloCalibPedestal *caloped)
virtual Int_t AreNeighbours(AliEMCALDigit *d1, AliEMCALDigit *d2, Bool_t &shared) const
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
Int_t fNumberOfECAClusters
number of clusters found in EC section
virtual void Calibrate(Float_t &amp, Float_t &time, const Int_t cellId)
#define TObjArray
Float_t GetTime(void) const
Definition: AliEMCALDigit.h:64
virtual void Digits2Clusters(Option_t *option)
TObjArray * fRecPoints
array with EMCAL clusters
void SetCalibAmp(Float_t amp)
Float_t fECAW0
logarithmic weight for the cluster center of gravity calculation
TBenchmark * gBenchmark
virtual void SetInput(Int_t numberOfECAClusters, TObjArray *recPoints, TClonesArray *digitsArr)
Cell energy calibration factors container class.
EMCal digits object.
Definition: AliEMCALDigit.h:30
Double_t GetPhiCenterOfSM(Int_t nsupmod) const
Int_t fNRowDiff
How many neighbors to consider along row (phi)
Int_t GetMaximalEnergyIndex(void) const
Finds the maximum energy in the cluster.
void GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta, Int_t &iphi, Int_t &ieta) const
void SetTime(Float_t time)
Definition: AliEMCALDigit.h:74
AliEMCALClusterizerNxN()
Default constructor.
Float_t fTimeCut
maximum time difference between the digits inside EMC cluster
Bool_t fJustClusters
false for standard reco
virtual void GetCalibrationParameters(void)
Bool_t fToUnfold
says if unfolding should be performed
Bool_t GetCellIndex(Int_t absId, Int_t &nSupMod, Int_t &nModule, Int_t &nIphi, Int_t &nIeta) const
virtual void MakeUnfolding()
virtual void AddDigit(AliEMCALDigit &digit, const Float_t energy, const Bool_t shared)
Float_t fTimeMin
minimum time of physical signal in a cell/digit
EMCal rec_points object.
AliEMCALGeometry * fGeom
! pointer to geometry for utilities
virtual void MakeClusters()
Make clusters.
Cell time shifts container class.
Double_t GetCalibAmp() const
pedestal/bad map monitoring and calibration tools
Float_t fTimeMax
maximum time of physical signal in a cell/digit
#define AliFatal(message)
Definition: AliLog.h:640
static const int fgkEMCALCols
Number of columns per module for EMCAL.
Create clusters of maximum size NxM.
TClonesArray * fDigitsArr
array with EMCAL digits
#define AliDebug(logLevel, message)
Definition: AliLog.h:300
AliCaloCalibPedestal * fCaloPed
! tower status map if aval
AliEMCALEMCGeometry * GetEMCGeometry() const
Int_t GetId() const
Definition: AliDigitNew.h:23
virtual void GetCaloCalibPedestal(void)
AliEMCALUnfolding * fClusterUnfolding
! pointer to unfolding object
virtual void EvalAll(Float_t logWeight, TClonesArray *digits, const Bool_t justClusters)
Evaluates cluster parameters: position, shower shape, primaries ...
Float_t fECAClusteringThreshold
minimum energy to seed a EC digit in a cluster
TTree * fTreeR
tree with output clusters
Bool_t fEnergyGrad
If true only cluster if neighboring cell has less energy.
Int_t fNColDiff
How many neighbors to consider along col (eta)
virtual void SetClusterType(Int_t ver)
void SetIndexInList(Int_t val)
Float_t GetAmplitude() const
Definition: AliEMCALDigit.h:55
virtual void Print(Option_t *option) const
Print clusterizer parameters.
EMCal geometry, singleton.
Float_t fMinECut
minimum energy for a digit to be a member of a cluster
Base class for the clusterization algorithm (pure abstract)
virtual ~AliEMCALClusterizerNxN()
Destructtor.
virtual void PrintRecPoints(Option_t *option)