17 #include "TClonesArray.h" 53 fNumberOfECAClusters(0),
56 fRejectBelowThreshold(0),
82 AliFatal(
"AliEMCALUnfolding: Geometry not initialized.");
99 Double_t *ssPars,Double_t *par5,Double_t *par6):
110 AliFatal(
"AliEMCALUnfolding: Geometry not initialized.");
114 for (i = 0; i < 8; i++)
fgSSPars[i] = ssPars[i];
115 for (i = 0; i < 3; i++)
141 gMinuit =
new TMinuit(30) ;
180 AliFatal(
"Did not get geometry from EMCALLoader") ;
191 for(index = 0 ; index < numberOfClustersToUnfold ; index++)
196 AliError(Form(
"RecPoint NULL, index = %d, fNumberOfECAClusters = %d, numberOfClustersToUnfold = %d",index,
fNumberOfECAClusters,numberOfClustersToUnfold)) ;
202 Float_t * maxAtEnergy =
new Float_t[nMultipl] ;
217 numberOfClustersToUnfold--;
228 delete[] maxAtEnergy ;
261 Float_t * maxAtEnergy,
268 AliDebug(5,Form(
" Original cluster E %f, nMax = %d",iniTower->
GetEnergy(),nMax ));
270 Int_t nPar = 3 * nMax ;
271 Float_t * fitparameters =
new Float_t[nPar] ;
274 AliFatal(
"Did not get geometry from EMCALLoader") ;
276 Bool_t rv =
FindFitV2(iniTower, maxAt, maxAtEnergy, nPar, fitparameters) ;
281 delete[] fitparameters ;
289 AliDebug(1,
"One of fitted energy below threshold");
291 delete[] fitparameters ;
305 Float_t * efit =
new Float_t[nDigits] ;
306 Float_t xpar=0.,zpar=0.,epar=0. ;
321 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++)
328 iIphi, iIeta,iphi,ieta);
333 while(iparam < nPar )
335 xpar = fitparameters[iparam] ;
336 zpar = fitparameters[iparam+1] ;
337 epar = fitparameters[iparam+2] ;
339 efit[iDigit] += epar *
ShowerShapeV2((Float_t)iphi - xpar,(Float_t)ieta - zpar) ;
342 }
else AliDebug(1,
"Digit NULL part 2!");
353 Float_t eDigit = 0. ;
354 Int_t nSplittedClusters=(Int_t)nPar/3;
356 Float_t * correctedEnergyList =
new Float_t[nDigits*nSplittedClusters];
369 while(iparam < nPar )
371 xpar = fitparameters[iparam] ;
372 zpar = fitparameters[iparam+1] ;
373 epar = fitparameters[iparam+2] ;
375 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++)
382 iIphi, iIeta,iphi,ieta);
388 correctedEnergyList[iparam/3*nDigits+iDigit] = 0.;
392 ratio = epar *
ShowerShapeV2((Float_t)iphi - xpar,(Float_t)ieta - zpar) / efit[iDigit] ;
393 eDigit = energiesList[iDigit] * ratio ;
396 correctedEnergyList[iparam/3*nDigits+iDigit] = eDigit;
398 }
else AliDebug(1,
"NULL digit part 3");
420 for(iDigit = 0 ; iDigit < nDigits ; iDigit++)
422 for(iparam = 0 ; iparam < nPar ; iparam+=3)
424 if(correctedEnergyList[iparam/3*nDigits+iDigit] <
fThreshold ) correctedEnergyList[iparam/3*nDigits+iDigit]=0.;
430 Float_t maximumEne=0.;
431 Int_t maximumIndex=0;
432 Bool_t isAnyBelowThreshold=kFALSE;
434 Float_t * energyFraction =
new Float_t[nSplittedClusters];
436 for(iDigit = 0 ; iDigit < nDigits ; iDigit++)
438 isAnyBelowThreshold=kFALSE;
440 for(iparam = 0 ; iparam < nPar ; iparam+=3)
442 if(correctedEnergyList[iparam/3*nDigits+iDigit] <
fThreshold ) isAnyBelowThreshold = kTRUE;
443 if(correctedEnergyList[iparam/3*nDigits+iDigit] > maximumEne)
445 maximumEne = correctedEnergyList[iparam/3*nDigits+iDigit];
446 maximumIndex = iparam;
450 if(!isAnyBelowThreshold)
continue;
455 for(iparam = 0 ; iparam < nPar ; iparam+=3)
457 maximumEne+=correctedEnergyList[iparam/3*nDigits+iDigit];
458 correctedEnergyList[iparam/3*nDigits+iDigit]=0;
460 correctedEnergyList[maximumIndex/3*nDigits+iDigit]=maximumEne;
466 for(iparam = 0 ; iparam < nPar ; iparam+=3)
468 if(correctedEnergyList[iparam/3*nDigits+iDigit] <
fThreshold) energyFraction[iparam/3]=0;
471 energyFraction[iparam/3]=1.;
472 maximumEne+=correctedEnergyList[iparam/3*nDigits+iDigit];
477 for(iparam = 0 ; iparam < nPar ; iparam+=3){
478 energyFraction[iparam/3] = energyFraction[iparam/3] * correctedEnergyList[iparam/3*nDigits+iDigit] / maximumEne;
481 for(iparam = 0 ; iparam < nPar ; iparam+=3)
483 if(energyFraction[iparam/3]>0.)
continue;
486 for(iparam2 = 0 ; iparam2 < nPar ; iparam2+=3)
488 correctedEnergyList[iparam2/3*nDigits+iDigit] += (energyFraction[iparam2/3] *
489 correctedEnergyList[iparam/3*nDigits+iDigit]) ;
491 correctedEnergyList[iparam/3*nDigits+iDigit] = 0.;
498 for(iparam = 0 ; iparam < nPar ; iparam+=3)
500 correctedEnergyList[iparam/3*nDigits+iDigit] = 0.;
505 delete[] energyFraction;
514 Int_t newClusterIndex=0;
516 while(iparam < nPar )
520 if(nSplittedClusters >= list->GetSize())
521 list->Expand(nSplittedClusters);
530 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++)
534 if(digit && correctedEnergyList[iparam/3*nDigits+iDigit]>0. )
537 recPoint->
AddDigit( *digit, correctedEnergyList[iparam/3*nDigits+iDigit], kFALSE ) ;
541 AliDebug(1,Form(
"NULL digit part3.3 or NULL energy=%f",correctedEnergyList[iparam/3*nDigits+iDigit]));
547 delete (*list)[newClusterIndex];
548 list->RemoveAt(newClusterIndex);
561 delete (*list)[newClusterIndex];
562 list->RemoveAt(newClusterIndex);
571 delete[] fitparameters ;
573 delete[] correctedEnergyList ;
576 AliDebug(5,Form(
" nSplittedClusters %d, fNumberOfECAClusters %d, newClusterIndex %d,list->Entries() %d\n",nSplittedClusters,
fNumberOfECAClusters,newClusterIndex,list->GetEntriesFast() ));
579 return nSplittedClusters;
595 Float_t * maxAtEnergy)
598 Int_t nUnfoldedClusters=
UnfoldOneCluster(iniTower,nMax,maxAt,maxAtEnergy,list);
601 AliDebug(5,Form(
"Number of clusters after unfolding %d",list->GetEntriesFast()));
604 for(Int_t i=0;i<list->GetEntriesFast();i++)
616 if( recPoint && rpUFOne )
619 recPoint->
SetNExMax(list->GetEntriesFast()) ;
624 if(!digitsList || ! energyList)
626 AliDebug(-1,
"No digits index or energy available");
632 AliDebug(5,Form(
"cluster %d, digit no %d, energy %f\n",i,digitsList[0],energyList[0]));
637 if(digit) recPoint->
AddDigit( *digit, energyList[iDigit], kFALSE ) ;
654 for(Int_t inewclus=0; inewclus<nUnfoldedClusters;inewclus++)
661 list->SetOwner(kTRUE);
665 if(nUnfoldedClusters>1)
return kTRUE;
684 Float_t * maxAtEnergy)
686 Int_t nPar = 3 * nMax ;
687 Float_t * fitparameters =
new Float_t[nPar] ;
690 AliFatal(
"Did not get geometry from EMCALLoader") ;
692 Bool_t rv =
FindFitV2(iniTower, maxAt, maxAtEnergy, nPar, fitparameters) ;
697 delete[] fitparameters ;
708 Float_t * efit =
new Float_t[nDigits] ;
709 Float_t xpar=0.,zpar=0.,epar=0. ;
724 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++)
730 iIphi, iIeta,iphi,ieta);
735 while(iparam < nPar )
737 xpar = fitparameters[iparam] ;
738 zpar = fitparameters[iparam+1] ;
739 epar = fitparameters[iparam+2] ;
742 efit[iDigit] += epar *
ShowerShapeV2((Float_t)iphi - xpar,(Float_t)ieta - zpar) ;
756 while(iparam < nPar )
758 xpar = fitparameters[iparam] ;
759 zpar = fitparameters[iparam+1] ;
760 epar = fitparameters[iparam+2] ;
777 Float_t eDigit = 0. ;
778 for(iDigit = 0 ; iDigit < nDigits ; iDigit ++)
785 iIphi, iIeta,iphi,ieta);
787 if(efit[iDigit]==0)
continue;
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 ) ;
796 delete[] fitparameters ;
819 const Float_t* maxAtEnergy,
820 Int_t nPar, Float_t * fitparameters)
const 822 if (
fGeom==0)
AliFatal(
"Did not get geometry from EMCALLoader");
827 if(nPar<30) gMinuit =
new TMinuit(30);
828 else gMinuit =
new TMinuit(nPar) ;
833 if(gMinuit->fMaxpar < nPar)
836 gMinuit =
new TMinuit(nPar);
841 gMinuit->SetPrintLevel(-1) ;
844 TList * toMinuit =
new TList();
845 toMinuit->AddAt(recPoint,0) ;
847 toMinuit->AddAt(
fGeom,2) ;
849 gMinuit->SetObjectFit(toMinuit) ;
856 Int_t nDigits = (Int_t) nPar / 3 ;
867 for(iDigit = 0; iDigit < nDigits; iDigit++)
869 digit = maxAt[iDigit];
878 iIphi, iIeta,iphi,ieta);
880 Float_t energy = maxAtEnergy[iDigit] ;
883 gMinuit->mnparm(index,
"x", iphi, 0.05, 0, 0, ierflg) ;
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 ) ;
892 gMinuit->mnparm(index,
"z", ieta, 0.05, 0, 0, ierflg) ;
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) ;
901 gMinuit->mnparm(index,
"Energy", energy , 0.001*energy, 0., 5.*energy, ierflg) ;
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) ;
916 gMinuit->mnexcm(
"SET STR", &p2, 0, ierflg) ;
918 gMinuit->SetMaxIterations(5);
919 gMinuit->mnexcm(
"SET NOW", &p2 , 0, ierflg) ;
922 gMinuit->mnexcm(
"MIGRAD", &p0, 0, ierflg) ;
926 AliDebug(1,
"EMCAL Unfolding Fit not converged, cluster abandoned " ) ;
931 for(index = 0; index < nPar; index++)
935 gMinuit->GetParameter(index, val, err) ;
936 fitparameters[index] = val ;
942 if(gMinuit->fMaxpar>30)
delete gMinuit;
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]) ;
968 Double_t * x, Int_t iflag)
970 TList * toMinuit =
dynamic_cast<TList*
>( gMinuit->GetObjectFit() ) ;
972 if ( toMinuit )
return;
975 TClonesArray * digits =
dynamic_cast<TClonesArray*
>( toMinuit->At(1) ) ;
981 if(!recPoint || !digits || !geom)
return ;
993 for(iparam = 0 ; iparam < nPar ; iparam++)
1008 for( iDigit = 0 ; iDigit < nOdigits ; iDigit++)
1010 if(energiesList[iDigit]==0)
continue;
1012 digit =
dynamic_cast<AliEMCALDigit*
>( digits->At( digitsList[iDigit] ) );
1016 printf(
"AliEMCALUnfoding::UnfoldingChiSquareV2 - NULL digit!, nPar %d \n", nPar);
1022 iIphi, iIeta,iphi,ieta);
1029 while(iParam < nPar )
1031 Double_t dx = ((Float_t)iphi - x[iParam]) ;
1033 Double_t dz = ((Float_t)ieta - x[iParam]) ;
1039 Double_t
sum = 2. * (efit - energiesList[iDigit]) / energiesList[iDigit] ;
1041 while(iParam < nPar )
1043 Double_t xpar = x[iParam] ;
1044 Double_t zpar = x[iParam+1] ;
1045 Double_t epar = x[iParam+2] ;
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]) ;
1060 Grad[iParam] += epar * shape * deriv * ((Float_t)iphi - xpar) ;
1062 Grad[iParam] += epar * shape * deriv * ((Float_t)ieta - zpar) ;
1064 Grad[iParam] += shape ;
1072 while(iparam < nPar )
1074 Double_t xpar = x[iparam] ;
1075 Double_t zpar = x[iparam+1] ;
1076 Double_t epar = x[iparam+2] ;
1078 efit += epar *
ShowerShapeV2((Float_t)iphi - xpar,(Float_t)ieta - zpar) ;
1081 fret += (efit-energiesList[iDigit])*(efit-energiesList[iDigit])/energiesList[iDigit] ;
1091 for(UInt_t i=0;i<7;++i)
1093 if(pars[2]==0. && pars[3]==0.)
fgSSPars[2]=1.;
1099 for(UInt_t i=0;i<3;++i)
1106 for(UInt_t i=0;i<3;++i)
1140 Double_t etaGlob = 0.;
1141 Double_t phiGlob = 0.;
1145 if(phiGlob<0)phiGlob+=TMath::TwoPi();
1146 phiGlob*=180./TMath::Pi();
1147 phiGlob-=20.*(Int_t)(phiGlob/20.);
1150 if(superModule==10 || superModule==11 || superModule==18 || superModule==19)
static AliRunLoader * Instance()
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.
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
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.
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)
Float_t * GetEnergiesList() const
virtual AliEMCALGeometry * GetGeometry() const
virtual void SetShowerShapeParams(Double_t *pars)
Base Class for EMCAL description.
virtual void SetRecPoints(TObjArray *rec)
static Double_t ShowerShapeV2(Double_t x, Double_t y)
#define AliFatal(message)
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)
Bool_t UnfoldClusterV2old(AliEMCALRecPoint *iniEmc, Int_t Nmax, AliEMCALDigit **maxAt, Float_t *maxAtEnergy)
static void EvalPar6(Double_t phi)
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
#define AliError(message)
virtual ~AliEMCALUnfolding()
Destructor.
static AliEMCALGeometry * GetInstance()
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)