AliRoot Core  edcc906 (edcc906)
AliEMCALUnfolding.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 "TClonesArray.h"
18 #include <TMath.h>
19 #include <TMinuit.h>
20 
21 // --- Standard library ---
22 #include <cassert>
23 
24 // --- AliRoot header files ---
25 #include "AliEMCALUnfolding.h"
26 #include "AliEMCALGeometry.h"
27 #include "AliRunLoader.h"
28 #include "AliRun.h"
29 #include "AliEMCAL.h"
30 #include "AliEMCALRecParam.h"
31 #include "AliEMCALRecPoint.h"
32 #include "AliEMCALDigit.h"
33 #include "AliEMCALReconstructor.h"
34 
35 #include "AliLog.h"
36 #include "AliCDBManager.h"
37 class AliCDBStorage;
38 #include "AliCDBEntry.h"
39 
40 Double_t AliEMCALUnfolding::fgSSPars[8]={0.9262,3.365,1.548,0.1625,-0.4195,0.,0.,2.332};
41 Double_t AliEMCALUnfolding::fgPar5[3]={12.31,-0.007381,-0.06936};
42 Double_t AliEMCALUnfolding::fgPar6[3]={0.05452,0.0001228,0.001361};
43 
45 ClassImp(AliEMCALUnfolding) ;
47 
51 //____________________________________________________________________________
53  fNumberOfECAClusters(0),
54  fECALocMaxCut(0),
55  fThreshold(0.01),//10 MeV
56  fRejectBelowThreshold(0),//split
57  fGeom(NULL),
58  fRecPoints(NULL),
59  fDigitsArr(NULL)
60 {
61  Init() ;
62 }
63 
70 //____________________________________________________________________________
73  fECALocMaxCut(0),
74  fThreshold(0.01),//10 MeV
75  fRejectBelowThreshold(0),//split
76  fGeom(geometry),
77  fRecPoints(NULL),
78  fDigitsArr(NULL)
79 {
80  if (!fGeom)
81  {
82  AliFatal("AliEMCALUnfolding: Geometry not initialized.");
83  }
84 }
85 
96 //____________________________________________________________________________
98  Float_t ecaLocMaxCut,
99  Double_t *ssPars,Double_t *par5,Double_t *par6):
101  fECALocMaxCut(ecaLocMaxCut),
102  fThreshold(0.01),//10 MeV
103  fRejectBelowThreshold(0),//split
104  fGeom(geometry),
105  fRecPoints(NULL),
106  fDigitsArr(NULL)
107 {
108  if (!fGeom)
109  {
110  AliFatal("AliEMCALUnfolding: Geometry not initialized.");
111  }
112 
113  Int_t i=0;
114  for (i = 0; i < 8; i++) fgSSPars[i] = ssPars[i];
115  for (i = 0; i < 3; i++)
116  {
117  fgPar5[i] = par5[i];
118  fgPar6[i] = par6[i];
119  }
120 }
121 
125 //____________________________________________________________________________
127 {
129  if (rl && rl->GetAliRun()){
130  AliEMCAL* emcal = dynamic_cast<AliEMCAL*>(rl->GetAliRun()->GetDetector("EMCAL"));
131  if(emcal)fGeom = emcal->GetGeometry();
132  }
133 
134  if(!fGeom)
136 
137  AliDebug(1,Form("geom %p",fGeom));
138 
139  if(!gMinuit)
140  // gMinuit = new TMinuit(100) ;//the same is in FindFitV2
141  gMinuit = new TMinuit(30) ;//the same is in FindFitV2
142 }
143 
146 //____________________________________________________________________________
148 { }
149 
156 //____________________________________________________________________________
157 void AliEMCALUnfolding::SetInput(Int_t numberOfECAClusters,TObjArray *recPoints,TClonesArray *digitsArr)
158 {
159  SetNumberOfECAClusters(numberOfECAClusters);
160  SetRecPoints(recPoints);
161  SetDigitsArr(digitsArr);
162 }
163 
167 //____________________________________________________________________________
169 {
170  AliDebug(4,Form(" V1: total no of clusters %d from %d digits",fNumberOfECAClusters,fDigitsArr->GetEntriesFast()));
171 
172  if(fNumberOfECAClusters <= 0)
173  {
174  AliDebug(4,Form(" V1+UNFOLD: total no of clusters %d from %d digits",fNumberOfECAClusters,fDigitsArr->GetEntriesFast()));
175 
176  return ;
177  }
178 
179  if ( !fGeom )
180  AliFatal("Did not get geometry from EMCALLoader") ;
181  //Int_t nModulesToUnfold = fGeom->GetNCells();
182 
183  Int_t numberOfClustersToUnfold=fNumberOfECAClusters;
184  //we unfold only clusters present in the array untill now
185  //fNumberOfECAClusters may change due to unfilded clusters
186  //so 0 to numberOfClustersToUnfold-1: clusters before unfolding
187  //numberOfClustersToUnfold to the end: new clusters from unfolding
188  //of course numberOfClustersToUnfold also is decreased but we don't loop over clusters added in UF
189 
190  Int_t index ;
191  for(index = 0 ; index < numberOfClustersToUnfold ; index++)
192  {
193  AliEMCALRecPoint * recPoint = dynamic_cast<AliEMCALRecPoint *>( fRecPoints->At(index) ) ;
194  if(!recPoint)
195  {
196  AliError(Form("RecPoint NULL, index = %d, fNumberOfECAClusters = %d, numberOfClustersToUnfold = %d",index,fNumberOfECAClusters,numberOfClustersToUnfold)) ;
197  continue ;
198  }
199 
200  Int_t nMultipl = recPoint->GetMultiplicity() ;
201  AliEMCALDigit ** maxAt = new AliEMCALDigit*[nMultipl] ;
202  Float_t * maxAtEnergy = new Float_t[nMultipl] ;
203 
204  Int_t nMax = recPoint->GetNumberOfLocalMax(maxAt, maxAtEnergy,fECALocMaxCut,fDigitsArr) ;
205  if( nMax > 1 )
206  {
207  // if cluster is very flat (no pronounced maximum) then nMax = 0
208  AliDebug(4,Form(" *** V1+UNFOLD *** Cluster index before UF %d",fNumberOfECAClusters));
209 
210  if(UnfoldClusterV2(recPoint, nMax, maxAt, maxAtEnergy) )
211  {
212  //if unfolding correct remove old recPoint
213  fRecPoints->Remove(recPoint);
214  fRecPoints->Compress() ;//is it really needed
215  index-- ;
217  numberOfClustersToUnfold--;
218  }
219 
220  AliDebug(4,Form(" Cluster index after UF %d",fNumberOfECAClusters));
221  }
222  else
223  {
224  recPoint->SetNExMax(1) ; //Only one local maximum
225  }
226 
227  delete[] maxAt ;
228  delete[] maxAtEnergy ;
229 
230  } // rec point loop
231  // End of Unfolding of clusters
232 
233  AliDebug(4,Form(" V1+UNFOLD: total no of clusters %d from %d digits",fNumberOfECAClusters,fDigitsArr->GetEntriesFast()));
234  // for(Int_t i=0;i<fNumberOfECAClusters;i++){
235  // AliEMCALRecPoint * recPoint = dynamic_cast<AliEMCALRecPoint *>(fRecPoints->At(i));
236  // Int_t nMultipl = recPoint->GetMultiplicity() ;
237  // Double_t energy=recPoint->GetEnergy();
238  // Int_t absIdMaxDigit=recPoint->GetAbsIdMaxDigit();
239  // Int_t sm=recPoint->GetSuperModuleNumber();
240  // Double_t pointEne=recPoint->GetPointEnergy();
241  // Float_t maxEne=recPoint->GetMaximalEnergy();
242  // Int_t maxEneInd=recPoint->GetMaximalEnergyIndex();
243  // printf(" cluster %d,ncells %d,ene %f,absIdMaxCell %d,sm %d,pointEne %f,maxEne %f,maxEneInd %d\n",i,nMultipl,energy,absIdMaxDigit,sm,pointEne,maxEne,maxEneInd);
244  // }
245 }
246 
257 //____________________________________________________________________________
259  Int_t nMax,
260  AliEMCALDigit ** maxAt,
261  Float_t * maxAtEnergy,
262  TObjArray *list)
263 {
264  //**************************** part 1 *******************************************
265  // Performs the unfolding of a cluster with nMax overlapping showers
266 
267  //cout<<"unfolding check here part 1"<<endl;
268  AliDebug(5,Form(" Original cluster E %f, nMax = %d",iniTower->GetEnergy(),nMax ));
269 
270  Int_t nPar = 3 * nMax ;
271  Float_t * fitparameters = new Float_t[nPar] ;
272 
273  if ( !fGeom )
274  AliFatal("Did not get geometry from EMCALLoader") ;
275 
276  Bool_t rv = FindFitV2(iniTower, maxAt, maxAtEnergy, nPar, fitparameters) ;
277  if( !rv )
278  {
279  // Fit failed, return (and remove cluster? - why? I leave the cluster)
280  iniTower->SetNExMax(-1) ;
281  delete[] fitparameters ;
282  return 0;//changed here
283  }
284 
285  // speed up solution for clusters with 2 maxima where one maximum is below threshold fThreshold
286  if(nMax==2)
287  {
288  if(fitparameters[2]<fThreshold || fitparameters[5]<fThreshold){
289  AliDebug(1,"One of fitted energy below threshold");
290  iniTower->SetNExMax(1) ;
291  delete[] fitparameters ;
292  return 0;//changed here
293  }
294  }
295 
296  //**************************** part 2 *******************************************
297  // create unfolded rec points and fill them with new energy lists
298  // First calculate energy deposited in each sell in accordance with
299  // fit (without fluctuations): efit[]
300  // and later correct this number in acordance with actual energy
301  // deposition
302 
303  // cout<<"unfolding check here part 2"<<endl;
304  Int_t nDigits = iniTower->GetMultiplicity() ;
305  Float_t * efit = new Float_t[nDigits] ;//new fitted energy in cells
306  Float_t xpar=0.,zpar=0.,epar=0. ;//center of gravity in cell units
307 
308  AliEMCALDigit * digit = 0 ;
309  Int_t * digitsList = iniTower->GetDigitsList() ;
310 
311  Int_t iSupMod = 0 ;
312  Int_t iTower = 0 ;
313  Int_t iIphi = 0 ;
314  Int_t iIeta = 0 ;
315  Int_t iphi = 0 ;//x direction
316  Int_t ieta = 0 ;//z direstion
317 
318  Int_t iparam = 0 ;
319  Int_t iDigit = 0 ;
320 
321  for(iDigit = 0 ; iDigit < nDigits ; iDigit ++)
322  {
323  digit = dynamic_cast<AliEMCALDigit*>( fDigitsArr->At(digitsList[iDigit] ) ) ;
324  if(digit)
325  {
326  fGeom->GetCellIndex(digit->GetId(),iSupMod,iTower,iIphi,iIeta);
327  fGeom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
328  iIphi, iIeta,iphi,ieta);
330 
331  efit[iDigit] = 0.;
332  iparam = 0;
333  while(iparam < nPar )
334  {
335  xpar = fitparameters[iparam] ;
336  zpar = fitparameters[iparam+1] ;
337  epar = fitparameters[iparam+2] ;
338 
339  efit[iDigit] += epar * ShowerShapeV2((Float_t)iphi - xpar,(Float_t)ieta - zpar) ;
340  iparam += 3 ;
341  }
342  } else AliDebug(1,"Digit NULL part 2!");
343 
344  }//digit loop
345 
346  //**************************** part 3 *******************************************
347  // Now create new RecPoints and fill energy lists with efit corrected to fluctuations
348  // so that energy deposited in each cell is distributed between new clusters proportionally
349  // to its contribution to efit
350 
351  Float_t * energiesList = iniTower->GetEnergiesList() ;
352  Float_t ratio = 0. ;
353  Float_t eDigit = 0. ;
354  Int_t nSplittedClusters=(Int_t)nPar/3;
355 
356  Float_t * correctedEnergyList = new Float_t[nDigits*nSplittedClusters];
357  //above - temporary table with energies after unfolding.
358  //the order is following:
359  //first cluster <first cell - last cell>,
360  //second cluster <first cell - last cell>, etc.
361 
362  //**************************** sub-part 3.1 *************************************
363  //If not the energy from a given cell in the cluster is divided in correct proportions
364  //in accordance to the other clusters and added to them and set to 0.
365 
366  // cout<<"unfolding check here part 3.1"<<endl;
367 
368  iparam = 0 ;
369  while(iparam < nPar )
370  {
371  xpar = fitparameters[iparam] ;
372  zpar = fitparameters[iparam+1] ;
373  epar = fitparameters[iparam+2] ;
374 
375  for(iDigit = 0 ; iDigit < nDigits ; iDigit ++)
376  {
377  digit = dynamic_cast<AliEMCALDigit*>( fDigitsArr->At( digitsList[iDigit] ) ) ;
378  if(digit)
379  {
380  fGeom->GetCellIndex(digit->GetId(),iSupMod,iTower,iIphi,iIeta);
381  fGeom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
382  iIphi, iIeta,iphi,ieta);
383 
385 
386  if(efit[iDigit]==0)
387  {//just for sure
388  correctedEnergyList[iparam/3*nDigits+iDigit] = 0.;//correction here
389  continue;
390  }
391 
392  ratio = epar * ShowerShapeV2((Float_t)iphi - xpar,(Float_t)ieta - zpar) / efit[iDigit] ;
393  eDigit = energiesList[iDigit] * ratio ;
394 
395  //add energy to temporary matrix
396  correctedEnergyList[iparam/3*nDigits+iDigit] = eDigit;
397 
398  } else AliDebug(1,"NULL digit part 3");
399  }//digit loop
400  iparam += 3 ;
401  }//while
402 
403  //**************************** sub-part 3.2 *************************************
404  //here we check if energy of the cell in the cluster after unfolding is above threshold.
405  //here we correct energy for each cell and cluster
406  // cout<<"unfolding check here part 3.2"<<endl;
407 
408 
409  //here we have 3 possibilities
410  //when after UF cell energy in cluster is below threshold:
411  //1 - keep it associated to cluster - equivalent of threshold=0
412  //2 - default - split (or add) energy of that cell into that cell in the other cluster(s)
413  //3 - reject that cell from cluster - fraction energy in cell=0 - breaks energy conservation
414  //Bool_t rejectBelowThreshold=kTRUE;//default option = 2 - split = kFALSE
415 
416  if(fThreshold > 0)
417  {//option 2 or 3
419  {//option 3
420  for(iDigit = 0 ; iDigit < nDigits ; iDigit++)
421  {//digit loop
422  for(iparam = 0 ; iparam < nPar ; iparam+=3)
423  {//param0 loop = energy loop
424  if(correctedEnergyList[iparam/3*nDigits+iDigit] < fThreshold ) correctedEnergyList[iparam/3*nDigits+iDigit]=0.;
425  }
426  }
427  }
428  else
429  {//option 2
430  Float_t maximumEne=0.;
431  Int_t maximumIndex=0;
432  Bool_t isAnyBelowThreshold=kFALSE;
433  // Float_t Threshold=0.01;
434  Float_t * energyFraction = new Float_t[nSplittedClusters];
435  Int_t iparam2 = 0 ;
436  for(iDigit = 0 ; iDigit < nDigits ; iDigit++)
437  {
438  isAnyBelowThreshold=kFALSE;
439  maximumEne=0.;
440  for(iparam = 0 ; iparam < nPar ; iparam+=3)
441  {
442  if(correctedEnergyList[iparam/3*nDigits+iDigit] < fThreshold ) isAnyBelowThreshold = kTRUE;
443  if(correctedEnergyList[iparam/3*nDigits+iDigit] > maximumEne)
444  {
445  maximumEne = correctedEnergyList[iparam/3*nDigits+iDigit];
446  maximumIndex = iparam;
447  }
448  }//end of loop over clusters after unfolding
449 
450  if(!isAnyBelowThreshold) continue; //no cluster-cell below threshold
451 
452  if(maximumEne < fThreshold)
453  {//add all cluster cells and put energy into max index, other set to 0
454  maximumEne=0.;
455  for(iparam = 0 ; iparam < nPar ; iparam+=3)
456  {
457  maximumEne+=correctedEnergyList[iparam/3*nDigits+iDigit];
458  correctedEnergyList[iparam/3*nDigits+iDigit]=0;
459  }
460  correctedEnergyList[maximumIndex/3*nDigits+iDigit]=maximumEne;
461  continue;
462  }//end if
463 
464  //divide energy of cell below threshold in the correct proportion and add to other cells
465  maximumEne=0.;//not used any more so use it for the energy sum
466  for(iparam = 0 ; iparam < nPar ; iparam+=3)
467  {//calculate energy sum
468  if(correctedEnergyList[iparam/3*nDigits+iDigit] < fThreshold) energyFraction[iparam/3]=0;
469  else
470  {
471  energyFraction[iparam/3]=1.;
472  maximumEne+=correctedEnergyList[iparam/3*nDigits+iDigit];
473  }
474  }//end of loop over clusters after unfolding
475  if(maximumEne>0.)
476  {
477  for(iparam = 0 ; iparam < nPar ; iparam+=3){//calculate fraction
478  energyFraction[iparam/3] = energyFraction[iparam/3] * correctedEnergyList[iparam/3*nDigits+iDigit] / maximumEne;
479  }
480 
481  for(iparam = 0 ; iparam < nPar ; iparam+=3)
482  {//add energy from cells below threshold to others
483  if(energyFraction[iparam/3]>0.) continue;
484  else
485  {
486  for(iparam2 = 0 ; iparam2 < nPar ; iparam2+=3)
487  {
488  correctedEnergyList[iparam2/3*nDigits+iDigit] += (energyFraction[iparam2/3] *
489  correctedEnergyList[iparam/3*nDigits+iDigit]) ;
490  }//inner loop
491  correctedEnergyList[iparam/3*nDigits+iDigit] = 0.;
492  }
493  }
494  }
495  else
496  {
497  //digit energy to be set to 0
498  for(iparam = 0 ; iparam < nPar ; iparam+=3)
499  {
500  correctedEnergyList[iparam/3*nDigits+iDigit] = 0.;
501  }
502  }//correction for: is energy>0
503 
504  }//end of loop over digits
505  delete[] energyFraction;
506 
507  }//end of option 2 or 3
508  }
509 
510  //**************************** sub-part 3.3 *************************************
511  //here we add digits to recpoints with corrected energy
512  // cout<<"unfolding check here part 3.3"<<endl;
513 
514  Int_t newClusterIndex=0;
515  iparam = 0 ;
516  while(iparam < nPar )
517  {
518  AliEMCALRecPoint * recPoint = 0 ;
519 
520  if(nSplittedClusters >= list->GetSize())
521  list->Expand(nSplittedClusters);
522 
523  //add recpoint
524  (*list)[newClusterIndex] = new AliEMCALRecPoint("") ;
525  recPoint = dynamic_cast<AliEMCALRecPoint *>( list->At(newClusterIndex) ) ;
526 
527  if(recPoint){//recPoint present -> good
528  recPoint->SetNExMax(nSplittedClusters) ;//can be wrong number, to be corrected in outer method
529 
530  for(iDigit = 0 ; iDigit < nDigits ; iDigit ++)
531  {
532  digit = dynamic_cast<AliEMCALDigit*>( fDigitsArr->At( digitsList[iDigit] ) ) ;
533 
534  if(digit && correctedEnergyList[iparam/3*nDigits+iDigit]>0. )
535  {
536  //if(correctedEnergyList[iparam/3*nDigits+iDigit]<fThreshold) printf("Final E cell %f < %f\n",correctedEnergyList[iparam/3*nDigits+iDigit],fThreshold);
537  recPoint->AddDigit( *digit, correctedEnergyList[iparam/3*nDigits+iDigit], kFALSE ) ; //FIXME, need to study the shared case
538  }
539  else
540  {
541  AliDebug(1,Form("NULL digit part3.3 or NULL energy=%f",correctedEnergyList[iparam/3*nDigits+iDigit]));
542  }
543  }//digit loop
544 
545  if(recPoint->GetMultiplicity()==0)
546  {//recpoint exists but no digits associated -> remove from list
547  delete (*list)[newClusterIndex];
548  list->RemoveAt(newClusterIndex);
549  nSplittedClusters--;
550  newClusterIndex--;//decrease cluster number
551  }
552  else
553  {//recPoint exists and has digits associated -> very good increase number of clusters
554  AliDebug(5,Form("cluster %d, digit no %d, energy %f",iparam/3,(recPoint->GetDigitsList())[0],(recPoint->GetEnergiesList())[0]));
555  }
556 
557  } else
558  {//recPoint empty -> remove from list
559  AliError("NULL RecPoint");
560  //protection from recpoint with no digits
561  delete (*list)[newClusterIndex];
562  list->RemoveAt(newClusterIndex);
563  nSplittedClusters--;
564  newClusterIndex--;//decrease cluster number
565  }
566 
567  iparam += 3 ;
568  newClusterIndex++;
569  }//while
570 
571  delete[] fitparameters ;
572  delete[] efit ;
573  delete[] correctedEnergyList ;
574 
575  // print
576  AliDebug(5,Form(" nSplittedClusters %d, fNumberOfECAClusters %d, newClusterIndex %d,list->Entries() %d\n",nSplittedClusters,fNumberOfECAClusters,newClusterIndex,list->GetEntriesFast() ));
577 
578  // cout<<"end of unfolding check part 3.3"<<endl;
579  return nSplittedClusters;
580 }
581 
591 //____________________________________________________________________________
593  Int_t nMax,
594  AliEMCALDigit ** maxAt,
595  Float_t * maxAtEnergy)
596 {
597  TObjArray *list =new TObjArray(2);//temporary object
598  Int_t nUnfoldedClusters=UnfoldOneCluster(iniTower,nMax,maxAt,maxAtEnergy,list);
599 
600  // here we write new clusters from list to fRecPoints
601  AliDebug(5,Form("Number of clusters after unfolding %d",list->GetEntriesFast()));
602  Int_t iDigit=0;
603  AliEMCALDigit * digit = 0 ;
604  for(Int_t i=0;i<list->GetEntriesFast();i++)
605  {
606  AliEMCALRecPoint * recPoint = 0 ;
607 
608  if(fNumberOfECAClusters >= fRecPoints->GetSize())
609  fRecPoints->Expand(2*fNumberOfECAClusters) ;
610 
611  //add recpoint
612  (*fRecPoints)[fNumberOfECAClusters] = new AliEMCALRecPoint("") ;//fNumberOfECAClusters-1 is old cluster before unfolding
613  recPoint = dynamic_cast<AliEMCALRecPoint *>( fRecPoints->At(fNumberOfECAClusters) ) ;
614  AliEMCALRecPoint * rpUFOne = dynamic_cast<AliEMCALRecPoint *>(list->At(i)) ;
615 
616  if( recPoint && rpUFOne )
617  {
618  //recPoint present -> good
619  recPoint->SetNExMax(list->GetEntriesFast()) ;
620 
621  Int_t *digitsList = rpUFOne->GetDigitsList();
622  Float_t *energyList = rpUFOne->GetEnergiesList();
623 
624  if(!digitsList || ! energyList)
625  {
626  AliDebug(-1,"No digits index or energy available");
627  delete (*fRecPoints)[fNumberOfECAClusters];
628  fRecPoints->RemoveAt(fNumberOfECAClusters);
629  continue;
630  }
631 
632  AliDebug(5,Form("cluster %d, digit no %d, energy %f\n",i,digitsList[0],energyList[0]));
633 
634  for(iDigit = 0 ; iDigit < rpUFOne->GetMultiplicity(); iDigit ++)
635  {
636  digit = dynamic_cast<AliEMCALDigit*>( fDigitsArr->At( digitsList[iDigit] ) ) ;
637  if(digit) recPoint->AddDigit( *digit, energyList[iDigit], kFALSE ) ; //FIXME, need to study the shared case
638  }//digit loop
639 
641  }
642  else
643  {//recPoint empty -> remove from list
644  AliError("NULL RecPoint");
645  delete (*fRecPoints)[fNumberOfECAClusters];
646  fRecPoints->RemoveAt(fNumberOfECAClusters);
647  }
648 
649  }//loop over unfolded clusters
650 
651  // print energy of new unfolded clusters
652  AliDebug(5,Form(" nUnfoldedClusters %d, fNumberOfECAClusters %d",nUnfoldedClusters,fNumberOfECAClusters ));
653 
654  for(Int_t inewclus=0; inewclus<nUnfoldedClusters;inewclus++)
655  {
656  AliEMCALRecPoint * rp = dynamic_cast<AliEMCALRecPoint *>(fRecPoints->At(fNumberOfECAClusters-1-inewclus));
657  if(rp) AliDebug(5,Form(" Unfolded cluster %d E %f",inewclus, rp->GetEnergy() ));
658  }
659 
660  // clear tables
661  list->SetOwner(kTRUE);
662  list->Delete();
663  delete list;
664 
665  if(nUnfoldedClusters>1) return kTRUE;
666 
667  return kFALSE;
668 }
669 
680 //____________________________________________________________________________
682  Int_t nMax,
683  AliEMCALDigit ** maxAt,
684  Float_t * maxAtEnergy)
685 {
686  Int_t nPar = 3 * nMax ;
687  Float_t * fitparameters = new Float_t[nPar] ;
688 
689  if (fGeom==0)
690  AliFatal("Did not get geometry from EMCALLoader") ;
691 
692  Bool_t rv = FindFitV2(iniTower, maxAt, maxAtEnergy, nPar, fitparameters) ;
693  if( !rv )
694  {
695  // Fit failed, return (and remove cluster? - why? I leave the cluster)
696  iniTower->SetNExMax(-1) ;
697  delete[] fitparameters ;
698  return kFALSE;
699  }
700 
701  // create unfolded rec points and fill them with new energy lists
702  // First calculate energy deposited in each sell in accordance with
703  // fit (without fluctuations): efit[]
704  // and later correct this number in acordance with actual energy
705  // deposition
706 
707  Int_t nDigits = iniTower->GetMultiplicity() ;
708  Float_t * efit = new Float_t[nDigits] ;//new fitted energy in cells
709  Float_t xpar=0.,zpar=0.,epar=0. ;//center of gravity in cell units
710 
711  AliEMCALDigit * digit = 0 ;
712  Int_t * digitsList = iniTower->GetDigitsList() ;
713 
714  Int_t iSupMod = 0 ;
715  Int_t iTower = 0 ;
716  Int_t iIphi = 0 ;
717  Int_t iIeta = 0 ;
718  Int_t iphi = 0 ;//x direction
719  Int_t ieta = 0 ;//z direstion
720 
721  Int_t iparam = 0 ;
722  Int_t iDigit = 0 ;
723 
724  for(iDigit = 0 ; iDigit < nDigits ; iDigit ++)
725  {
726  digit = dynamic_cast<AliEMCALDigit*>( fDigitsArr->At(digitsList[iDigit] ) ) ;
727  if(digit){
728  fGeom->GetCellIndex(digit->GetId(),iSupMod,iTower,iIphi,iIeta);
729  fGeom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
730  iIphi, iIeta,iphi,ieta);
732 
733  efit[iDigit] = 0.;
734  iparam = 0;
735  while(iparam < nPar )
736  {
737  xpar = fitparameters[iparam] ;
738  zpar = fitparameters[iparam+1] ;
739  epar = fitparameters[iparam+2] ;
740  iparam += 3 ;
741 
742  efit[iDigit] += epar * ShowerShapeV2((Float_t)iphi - xpar,(Float_t)ieta - zpar) ;
743  }
744  } else AliError("Digit NULL!");
745 
746  }//digit loop
747 
748  // Now create new RecPoints and fill energy lists with efit corrected to fluctuations
749  // so that energy deposited in each cell is distributed between new clusters proportionally
750  // to its contribution to efit
751 
752  Float_t * energiesList = iniTower->GetEnergiesList() ;
753  Float_t ratio = 0 ;
754 
755  iparam = 0 ;
756  while(iparam < nPar )
757  {
758  xpar = fitparameters[iparam] ;
759  zpar = fitparameters[iparam+1] ;
760  epar = fitparameters[iparam+2] ;
761  iparam += 3 ;
762 
763  AliEMCALRecPoint * recPoint = 0 ;
764 
765  if(fNumberOfECAClusters >= fRecPoints->GetSize())
766  fRecPoints->Expand(2*fNumberOfECAClusters) ;
767 
768  //add recpoint
769  (*fRecPoints)[fNumberOfECAClusters] = new AliEMCALRecPoint("") ;
770  recPoint = dynamic_cast<AliEMCALRecPoint *>( fRecPoints->At(fNumberOfECAClusters) ) ;
771 
772  if(recPoint)
773  {
775  recPoint->SetNExMax((Int_t)nPar/3) ;
776 
777  Float_t eDigit = 0. ;
778  for(iDigit = 0 ; iDigit < nDigits ; iDigit ++)
779  {
780  digit = dynamic_cast<AliEMCALDigit*>( fDigitsArr->At( digitsList[iDigit] ) ) ;
781  if(digit)
782  {
783  fGeom->GetCellIndex(digit->GetId(),iSupMod,iTower,iIphi,iIeta);
784  fGeom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
785  iIphi, iIeta,iphi,ieta);
787  if(efit[iDigit]==0) continue;//just for sure
788  ratio = epar * ShowerShapeV2((Float_t)iphi - xpar,(Float_t)ieta - zpar) / efit[iDigit] ;
789  eDigit = energiesList[iDigit] * ratio ;
790  recPoint->AddDigit( *digit, eDigit, kFALSE ) ; //FIXME, need to study the shared case
791  } else AliError("NULL digit");
792  }//digit loop
793  } else AliError("NULL RecPoint");
794  }//while
795 
796  delete[] fitparameters ;
797  delete[] efit ;
798 
799  return kTRUE;
800 }
801 
816 //____________________________________________________________________________
818  AliEMCALDigit ** maxAt,
819  const Float_t* maxAtEnergy,
820  Int_t nPar, Float_t * fitparameters) const
821 {
822  if (fGeom==0) AliFatal("Did not get geometry from EMCALLoader");
823 
824  if(!gMinuit)
825  {
826  // gMinuit = new TMinuit(100) ;//max 100 parameters
827  if(nPar<30) gMinuit = new TMinuit(30);
828  else gMinuit = new TMinuit(nPar) ;//max nPar parameters
829  //
830  }
831  else
832  {
833  if(gMinuit->fMaxpar < nPar)
834  {
835  delete gMinuit;
836  gMinuit = new TMinuit(nPar);
837  }
838  }
839 
840  gMinuit->mncler(); // Reset Minuit's list of paramters
841  gMinuit->SetPrintLevel(-1) ; // No Printout
842  gMinuit->SetFCN(AliEMCALUnfolding::UnfoldingChiSquareV2) ;
843  // To set the address of the minimization function
844  TList * toMinuit = new TList();
845  toMinuit->AddAt(recPoint,0) ;
846  toMinuit->AddAt(fDigitsArr,1) ;
847  toMinuit->AddAt(fGeom,2) ;
848 
849  gMinuit->SetObjectFit(toMinuit) ; // To tranfer pointer to UnfoldingChiSquare
850 
851  // filling initial values for fit parameters
852  AliEMCALDigit * digit ;
853 
854  Int_t ierflg = 0;
855  Int_t index = 0 ;
856  Int_t nDigits = (Int_t) nPar / 3 ;
857 
858  Int_t iDigit ;
859 
860  Int_t iSupMod = 0 ;
861  Int_t iTower = 0 ;
862  Int_t iIphi = 0 ;
863  Int_t iIeta = 0 ;
864  Int_t iphi = 0 ;//x direction
865  Int_t ieta = 0 ;//z direstion
866 
867  for(iDigit = 0; iDigit < nDigits; iDigit++)
868  {
869  digit = maxAt[iDigit];
870  if(!digit)
871  {
872  AliError("Null digit pointer");
873  continue;
874  }
875 
876  fGeom->GetCellIndex(digit->GetId(),iSupMod,iTower,iIphi,iIeta);
877  fGeom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
878  iIphi, iIeta,iphi,ieta);
879 
880  Float_t energy = maxAtEnergy[iDigit] ;
881 
882  //gMinuit->mnparm(index, "x", iphi, 0.1, 0, 0, ierflg) ;//original
883  gMinuit->mnparm(index, "x", iphi, 0.05, 0, 0, ierflg) ;
884  index++ ;
885  if(ierflg != 0){
886  Error("FindFit", "EMCAL Unfolding unable to set initial value for fit procedure: x=%d, param.id=%d, nMaxima=%d",iphi,index-1,nPar/3 ) ;
887  toMinuit->Clear();
888  delete toMinuit ;
889  return kFALSE;
890  }
891  //gMinuit->mnparm(index, "z", ieta, 0.1, 0, 0, ierflg) ;//original
892  gMinuit->mnparm(index, "z", ieta, 0.05, 0, 0, ierflg) ;
893  index++ ;
894  if(ierflg != 0){
895  Error("FindFit", "EMCAL Unfolding unable to set initial value for fit procedure: z=%d, param.id=%d, nMaxima=%d", ieta, index-1,nPar/3) ;
896  toMinuit->Clear();
897  delete toMinuit ;
898  return kFALSE;
899  }
900  //gMinuit->mnparm(index, "Energy", energy , 0.05*energy, 0., 4.*energy, ierflg) ;//original
901  gMinuit->mnparm(index, "Energy", energy , 0.001*energy, 0., 5.*energy, ierflg) ;//was 0.05
902  index++ ;
903  if(ierflg != 0){
904  Error("FindFit", "EMCAL Unfolding unable to set initial value for fit procedure: energy = %f, param.id=%d, nMaxima=%d", energy, index-1, nPar/3) ;
905  toMinuit->Clear();
906  delete toMinuit ;
907  return kFALSE;
908  }
909  }
910 
911  Double_t p0 = 0.1 ; // "Tolerance" Evaluation stops when EDM = 0.0001*p0 ;
912  // The number of function call slightly depends on it.
913  // Double_t p1 = 1.0 ;// par to gradient
914  Double_t p2 = 0.0 ;
915  // Double_t p3 = 3.0 ;
916  gMinuit->mnexcm("SET STR", &p2, 0, ierflg) ; // force TMinuit to reduce function calls
917  // gMinuit->mnexcm("SET GRA", &p1, 1, ierflg) ; // force TMinuit to use my gradient
918  gMinuit->SetMaxIterations(5);//was 5
919  gMinuit->mnexcm("SET NOW", &p2 , 0, ierflg) ; // No Warnings
920  //gMinuit->mnexcm("SET PRI", &p3 , 3, ierflg) ; // printouts
921 
922  gMinuit->mnexcm("MIGRAD", &p0, 0, ierflg) ; // minimize
923  //gMinuit->mnexcm("MINI", &p0, 0, ierflg) ; // minimize
924  if(ierflg == 4)
925  { // Minimum not found
926  AliDebug(1,"EMCAL Unfolding Fit not converged, cluster abandoned " ) ;
927  toMinuit->Clear();
928  delete toMinuit ;
929  return kFALSE ;
930  }
931  for(index = 0; index < nPar; index++)
932  {
933  Double_t err = 0. ;
934  Double_t val = 0. ;
935  gMinuit->GetParameter(index, val, err) ; // Returns value and error ofOA parameter index
936  fitparameters[index] = val ;
937  }
938 
939  toMinuit->Clear();
940  delete toMinuit ;
941 
942  if(gMinuit->fMaxpar>30) delete gMinuit;
943 
944  return kTRUE;
945 
946 }
947 
952 //____________________________________________________________________________
953 Double_t AliEMCALUnfolding::ShowerShapeV2(Double_t x, Double_t y)
954 {
955  Double_t r = fgSSPars[7]*TMath::Sqrt(x*x+y*y);
956  Double_t rp1 = TMath::Power(r, fgSSPars[1]) ;
957  Double_t rp5 = TMath::Power(r, fgSSPars[5]) ;
958  Double_t shape = fgSSPars[0]*TMath::Exp( -rp1 * (1. / (fgSSPars[2] + fgSSPars[3] * rp1) + fgSSPars[4] / (1 + fgSSPars[6] * rp5) ) ) ;
959  return shape ;
960 }
961 
965 //____________________________________________________________________________
966 void AliEMCALUnfolding::UnfoldingChiSquareV2(Int_t & nPar, Double_t * Grad,
967  Double_t & fret,
968  Double_t * x, Int_t iflag)
969 {
970  TList * toMinuit = dynamic_cast<TList*>( gMinuit->GetObjectFit() ) ;
971 
972  if ( toMinuit ) return;
973 
974  AliEMCALRecPoint * recPoint = dynamic_cast<AliEMCALRecPoint*>( toMinuit->At(0) ) ;
975  TClonesArray * digits = dynamic_cast<TClonesArray*>( toMinuit->At(1) ) ;
976 
977  // A bit buggy way to get an access to the geometry
978  // To be revised!
979  AliEMCALGeometry *geom = dynamic_cast<AliEMCALGeometry *>(toMinuit->At(2));
980 
981  if(!recPoint || !digits || !geom) return ;
982 
983  Int_t * digitsList = recPoint->GetDigitsList() ;
984 
985  Int_t nOdigits = recPoint->GetDigitsMultiplicity() ;
986 
987  Float_t * energiesList = recPoint->GetEnergiesList() ;
988 
989  fret = 0. ;
990  Int_t iparam = 0 ;
991 
992  if(iflag == 2)
993  for(iparam = 0 ; iparam < nPar ; iparam++)
994  Grad[iparam] = 0 ; // Will evaluate gradient
995 
996  Double_t efit = 0. ;
997 
998  AliEMCALDigit * digit ;
999  Int_t iDigit ;
1000 
1001  Int_t iSupMod = 0 ;
1002  Int_t iTower = 0 ;
1003  Int_t iIphi = 0 ;
1004  Int_t iIeta = 0 ;
1005  Int_t iphi = 0 ;//x direction
1006  Int_t ieta = 0 ;//z direstion
1007 
1008  for( iDigit = 0 ; iDigit < nOdigits ; iDigit++)
1009  {
1010  if(energiesList[iDigit]==0) continue;
1011 
1012  digit = dynamic_cast<AliEMCALDigit*>( digits->At( digitsList[iDigit] ) );
1013 
1014  if(!digit)
1015  {
1016  printf("AliEMCALUnfoding::UnfoldingChiSquareV2 - NULL digit!, nPar %d \n", nPar); // put nPar here to cheat coverity and rule checker
1017  continue;
1018  }
1019 
1020  geom->GetCellIndex(digit->GetId(),iSupMod,iTower,iIphi,iIeta);
1021  geom->GetCellPhiEtaIndexInSModule(iSupMod,iTower,
1022  iIphi, iIeta,iphi,ieta);
1023  EvalParsPhiDependence(digit->GetId(),geom);
1024 
1025  if(iflag == 2)
1026  { // calculate gradient
1027  Int_t iParam = 0 ;
1028  efit = 0. ;
1029  while(iParam < nPar )
1030  {
1031  Double_t dx = ((Float_t)iphi - x[iParam]) ;
1032  iParam++ ;
1033  Double_t dz = ((Float_t)ieta - x[iParam]) ;
1034  iParam++ ;
1035  efit += x[iParam] * ShowerShapeV2(dx,dz) ;
1036  iParam++ ;
1037  }
1038 
1039  Double_t sum = 2. * (efit - energiesList[iDigit]) / energiesList[iDigit] ; // Here we assume, that sigma = sqrt(E)
1040  iParam = 0 ;
1041  while(iParam < nPar )
1042  {
1043  Double_t xpar = x[iParam] ;
1044  Double_t zpar = x[iParam+1] ;
1045  Double_t epar = x[iParam+2] ;
1046 
1047  Double_t dr = fgSSPars[7]*TMath::Sqrt( ((Float_t)iphi - xpar) * ((Float_t)iphi - xpar) + ((Float_t)ieta - zpar) * ((Float_t)ieta - zpar) );
1048  Double_t shape = sum * ShowerShapeV2((Float_t)iphi - xpar,(Float_t)ieta - zpar) ;
1049  Double_t rp1 = TMath::Power(dr, fgSSPars[1]) ;
1050  Double_t rp5 = TMath::Power(dr, fgSSPars[5]) ;
1051 
1052  Double_t deriv = -2 * TMath::Power(dr,fgSSPars[1]-2.) * fgSSPars[7] * fgSSPars[7] *
1053  (fgSSPars[1] * ( 1/(fgSSPars[2]+fgSSPars[3]*rp1) + fgSSPars[4]/(1+fgSSPars[6]*rp5) ) -
1054  (fgSSPars[1]*fgSSPars[3]*rp1/( (fgSSPars[2]+fgSSPars[3]*rp1)*(fgSSPars[2]+fgSSPars[3]*rp1) ) +
1055  fgSSPars[4]*fgSSPars[5]*fgSSPars[6]*rp5/( (1+fgSSPars[6]*rp5)*(1+fgSSPars[6]*rp5) ) ) );
1056 
1057  //Double_t deriv =-1.33 * TMath::Power(dr,0.33)*dr * ( 1.57 / ( (1.57 + 0.0860 * r133) * (1.57 + 0.0860 * r133) )
1058  // - 0.55 / (1 + 0.000563 * r669) / ( (1 + 0.000563 * r669) * (1 + 0.000563 * r669) ) ) ;
1059 
1060  Grad[iParam] += epar * shape * deriv * ((Float_t)iphi - xpar) ; // Derivative over x
1061  iParam++ ;
1062  Grad[iParam] += epar * shape * deriv * ((Float_t)ieta - zpar) ; // Derivative over z
1063  iParam++ ;
1064  Grad[iParam] += shape ; // Derivative over energy
1065  iParam++ ;
1066  }
1067  }
1068 
1069  efit = 0;
1070  iparam = 0 ;
1071 
1072  while(iparam < nPar )
1073  {
1074  Double_t xpar = x[iparam] ;
1075  Double_t zpar = x[iparam+1] ;
1076  Double_t epar = x[iparam+2] ;
1077  iparam += 3 ;
1078  efit += epar * ShowerShapeV2((Float_t)iphi - xpar,(Float_t)ieta - zpar) ;
1079  }
1080 
1081  fret += (efit-energiesList[iDigit])*(efit-energiesList[iDigit])/energiesList[iDigit] ;
1082  // Here we assume, that sigma = sqrt(E)
1083 
1084  } // digit loop
1085 }
1086 
1087 
1088 //____________________________________________________________________________
1090 {
1091  for(UInt_t i=0;i<7;++i)
1092  fgSSPars[i]=pars[i];
1093  if(pars[2]==0. && pars[3]==0.) fgSSPars[2]=1.;//to avoid dividing by 0
1094 }
1095 
1096 //____________________________________________________________________________
1097 void AliEMCALUnfolding::SetPar5(Double_t *pars)
1098 {
1099  for(UInt_t i=0;i<3;++i)
1100  fgPar5[i]=pars[i];
1101 }
1102 
1103 //____________________________________________________________________________
1104 void AliEMCALUnfolding::SetPar6(Double_t *pars)
1105 {
1106  for(UInt_t i=0;i<3;++i)
1107  fgPar6[i]=pars[i];
1108 }
1109 
1113 //____________________________________________________________________________
1115 {
1116  //fSSPars[5] = 12.31 - phi*0.007381 - phi*phi*0.06936;
1117  fgSSPars[5] = fgPar5[0] + phi * fgPar5[1] + phi*phi * fgPar5[2];
1118 }
1119 
1123 //____________________________________________________________________________
1125 {
1126  //fSSPars[6] = 0.05452 + phi*0.0001228 + phi*phi*0.001361;
1127  fgSSPars[6] = fgPar6[0] + phi * fgPar6[1] + phi*phi * fgPar6[2];
1128 }
1129 
1130 //
1136 //____________________________________________________________________________
1138  const AliEMCALGeometry *geom)
1139 {
1140  Double_t etaGlob = 0.;//eta in global c.s. - unused
1141  Double_t phiGlob = 0.;//phi in global c.s. in radians
1142 
1143  geom->EtaPhiFromIndex(absId, etaGlob, phiGlob);
1144 
1145  if(phiGlob<0)phiGlob+=TMath::TwoPi();
1146  phiGlob*=180./TMath::Pi();
1147  phiGlob-=20.*(Int_t)(phiGlob/20.);
1148 
1149  Int_t superModule=geom->GetSuperModuleNumber(absId);
1150  if(superModule==10 || superModule==11 || superModule==18 || superModule==19) //sm 10,11,18,19 shift by 3.5 deg other 10 deg
1151  phiGlob-=3.5;
1152  else
1153  phiGlob-=10.;
1154 
1155  EvalPar5(phiGlob);
1156  EvalPar6(phiGlob);
1157 }
1158 
static AliRunLoader * Instance()
Definition: AliRunLoader.h:176
printf("Chi2/npoints = %f\n", TMath::Sqrt(chi2/npoints))
virtual Int_t GetNumberOfLocalMax(Int_t nDigitMult, Float_t locMaxCut, TClonesArray *digits) const
static Double_t fgPar6[3]
UF SSPar nr 6 = p0 + phi*p1 + phi^2 *p2.
Float_t fThreshold
Minimum energy for cell to be joined to a cluster.
#define TObjArray
static const Char_t * GetDefaultGeometryName()
static Double_t fgSSPars[8]
Int_t fNumberOfECAClusters
Number of clusters found in EC section.
void EtaPhiFromIndex(Int_t absId, Double_t &eta, Double_t &phi) const
virtual void SetPar5(Double_t *pars)
TClonesArray * fDigitsArr
Array with EMCAL digits.
virtual Int_t GetDigitsMultiplicity(void) const
virtual void SetInput(Int_t numberOfECAClusters, TObjArray *recPoints, TClonesArray *digitsArr)
Bool_t FindFitV2(AliEMCALRecPoint *emcRP, AliEMCALDigit **MaxAt, const Float_t *maxAtEnergy, Int_t NPar, Float_t *FitParametres) const
virtual Float_t GetEnergy() const
virtual int * GetDigitsList(void) const
EMCal digits object.
Definition: AliEMCALDigit.h:30
static void EvalPar5(Double_t phi)
Base class for the cluster unfolding algorithm.
static void UnfoldingChiSquareV2(Int_t &nPar, Double_t *Grad, Double_t &fret, Double_t *x, Int_t iflag)
void GetCellPhiEtaIndexInSModule(Int_t nSupMod, Int_t nModule, Int_t nIphi, Int_t nIeta, Int_t &iphi, Int_t &ieta) const
TObjArray * fRecPoints
Array with EMCAL clusters.
void sum()
Int_t GetMultiplicity(void) const
virtual Int_t UnfoldOneCluster(AliEMCALRecPoint *iniTower, Int_t nMax, AliEMCALDigit **maxAt, Float_t *maxAtEnergy, TObjArray *list)
static Double_t fgPar5[3]
UF SSPar nr 5 = p0 + phi*p1 + phi^2 *p2.
virtual void SetPar6(Double_t *pars)
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)
EMCal rec_points object.
Float_t * GetEnergiesList() const
virtual AliEMCALGeometry * GetGeometry() const
Definition: AliEMCAL.cxx:466
virtual void SetShowerShapeParams(Double_t *pars)
Base Class for EMCAL description.
Definition: AliEMCAL.h:35
virtual void SetRecPoints(TObjArray *rec)
static Double_t ShowerShapeV2(Double_t x, Double_t y)
#define AliFatal(message)
Definition: AliLog.h:640
Float_t fECALocMaxCut
Minimum energy difference to distinguish local maxima in a cluster.
Int_t GetSuperModuleNumber(Int_t absId) const
static void EvalParsPhiDependence(Int_t absId, const AliEMCALGeometry *geom)
AliEMCALGeometry * fGeom
! Pointer to geometry for utilities
#define AliDebug(logLevel, message)
Definition: AliLog.h:300
Bool_t UnfoldClusterV2old(AliEMCALRecPoint *iniEmc, Int_t Nmax, AliEMCALDigit **maxAt, Float_t *maxAtEnergy)
static void EvalPar6(Double_t phi)
Int_t GetId() const
Definition: AliDigitNew.h:23
virtual void SetNumberOfECAClusters(Int_t n)
Bool_t UnfoldClusterV2(AliEMCALRecPoint *iniEmc, Int_t Nmax, AliEMCALDigit **maxAt, Float_t *maxAtEnergy)
AliDetector * GetDetector(const char *name) const
Definition: AliRun.cxx:200
#define AliError(message)
Definition: AliLog.h:591
virtual ~AliEMCALUnfolding()
Destructor.
static AliEMCALGeometry * GetInstance()
TEveGeoShape * geom
Definition: tpc_tracks.C:10
void SetNExMax(Int_t nmax=1)
Bool_t fRejectBelowThreshold
Split (false) or reject (true) cell energy below threshold after UF.
EMCal geometry, singleton.
AliRun * GetAliRun() const
virtual void SetDigitsArr(TClonesArray *digit)