2 // Class to do the energy correction of FMD ESD data
4 #include "AliFMDEnergyFitter.h"
11 #include "AliFMDAnaParameters.h"
13 #include <TClonesArray.h>
14 #include <TFitResult.h>
17 ClassImp(AliFMDEnergyFitter)
19 ; // This is for Emacs
22 #define N_A(N) (4+N-2)
23 #define N2_A(N) (4+(N-2)*3)
24 #define N2_D(N) (4+(N-2)*3+1)
25 #define N2_X(N) (4+(N-2)*3+2)
27 //____________________________________________________________________
30 NLandau(Double_t* xp, Double_t* pp)
33 Double_t constant = pp[0];
35 Double_t fwhm = pp[2];
36 Int_t n = Int_t(pp[3]);
38 for (Int_t i = 1; i <= n; i++) {
39 Double_t mpvi = i*(mpv+fwhm*TMath::Log(i));
40 Double_t fwhmi = i*fwhm;
41 Double_t ai = (i == 1 ? 1 : pp[N_A(i)]);
42 result += ai * TMath::Landau(e,mpvi,fwhmi,kTRUE);
49 NLandau2(Double_t* xp, Double_t* pp)
52 Double_t constant = pp[0];
54 Double_t fwhm = pp[2];
55 Int_t n = Int_t(pp[3]);
56 Double_t result = TMath::Landau(e,mpv,fwhm,kTRUE);
57 for (Int_t i = 2; i <= n; i++) {
58 Double_t ai = pp[N2_A(i)];
59 Double_t mpvi = pp[N2_D(i)];
60 Double_t fwhmi = pp[N2_X(i)];
61 result += ai * TMath::Landau(e,mpvi,fwhmi,kTRUE);
68 TripleLandau(Double_t *x, Double_t *par)
70 Double_t energy = x[0];
71 Double_t constant = par[0];
72 Double_t mpv = par[1];
73 Double_t fwhm = par[2];
74 Double_t alpha = par[3];
75 Double_t beta = par[4];
76 Double_t mpv2 = 2*mpv+2*fwhm*TMath::Log(2);
77 Double_t mpv3 = 3*mpv+3*fwhm*TMath::Log(3);
79 Double_t f = constant * (TMath::Landau(energy,mpv,fwhm,kTRUE)+
80 alpha * TMath::Landau(energy,mpv2,2*fwhm,kTRUE)+
81 beta * TMath::Landau(energy,mpv3,3*fwhm,kTRUE));
86 DoubleLandau(Double_t *x, Double_t *par)
88 Double_t energy = x[0];
89 Double_t constant = par[0];
90 Double_t mpv = par[1];
91 Double_t fwhm = par[2];
92 Double_t alpha = par[3];
93 Double_t mpv2 = 2*mpv+2*fwhm*TMath::Log(2);
95 Double_t f = constant * (TMath::Landau(energy,mpv,fwhm,kTRUE)+
96 alpha * TMath::Landau(energy,mpv2,2*fwhm,kTRUE));
101 SingleLandau(Double_t *x, Double_t *par)
103 Double_t energy = x[0];
104 Double_t constant = par[0];
105 Double_t mpv = par[1];
106 Double_t fwhm = par[2];
108 Double_t f = constant * TMath::Landau(energy,mpv,fwhm,kTRUE);
114 //____________________________________________________________________
115 AliFMDEnergyFitter::AliFMDEnergyFitter()
127 //____________________________________________________________________
128 AliFMDEnergyFitter::AliFMDEnergyFitter(const char* title)
129 : TNamed("fmdEnergyFitter", title),
139 fEtaAxis.SetName("etaAxis");
140 fEtaAxis.SetTitle("#eta");
141 fRingHistos.Add(new RingHistos(1, 'I'));
142 fRingHistos.Add(new RingHistos(2, 'I'));
143 fRingHistos.Add(new RingHistos(2, 'O'));
144 fRingHistos.Add(new RingHistos(3, 'I'));
145 fRingHistos.Add(new RingHistos(3, 'O'));
148 //____________________________________________________________________
149 AliFMDEnergyFitter::AliFMDEnergyFitter(const AliFMDEnergyFitter& o)
153 fNLandau(o.fNLandau),
154 fMinEntries(o.fMinEntries),
155 fBinsToSubtract(o.fBinsToSubtract),
157 fEtaAxis(o.fEtaAxis),
160 TIter next(&o.fRingHistos);
162 while ((obj = next())) fRingHistos.Add(obj);
165 //____________________________________________________________________
166 AliFMDEnergyFitter::~AliFMDEnergyFitter()
168 fRingHistos.Delete();
171 //____________________________________________________________________
173 AliFMDEnergyFitter::operator=(const AliFMDEnergyFitter& o)
175 TNamed::operator=(o);
178 fNLandau = o.fNLandau;
179 fMinEntries = o.fMinEntries;
180 fBinsToSubtract= o.fBinsToSubtract;
182 fEtaAxis.Set(o.fEtaAxis.GetNbins(),o.fEtaAxis.GetXmin(),o.fEtaAxis.GetXmax());
185 fRingHistos.Delete();
186 TIter next(&o.fRingHistos);
188 while ((obj = next())) fRingHistos.Add(obj);
193 //____________________________________________________________________
194 AliFMDEnergyFitter::RingHistos*
195 AliFMDEnergyFitter::GetRingHistos(UShort_t d, Char_t r) const
199 case 1: idx = 0; break;
200 case 2: idx = 1 + (r == 'I' || r == 'i' ? 0 : 1); break;
201 case 3: idx = 3 + (r == 'I' || r == 'i' ? 0 : 1); break;
203 if (idx < 0 || idx >= fRingHistos.GetEntries()) return 0;
205 return static_cast<RingHistos*>(fRingHistos.At(idx));
208 //____________________________________________________________________
210 AliFMDEnergyFitter::Init(const TAxis& eAxis)
212 fEtaAxis.Set(eAxis.GetNbins(),eAxis.GetXmin(),eAxis.GetXmax());
213 TIter next(&fRingHistos);
215 while ((o = static_cast<RingHistos*>(next())))
218 //____________________________________________________________________
220 AliFMDEnergyFitter::Accumulate(const AliESDFMD& input,
223 for(UShort_t d = 1; d <= 3; d++) {
224 Int_t nRings = (d == 1 ? 1 : 2);
225 for (UShort_t q = 0; q < nRings; q++) {
226 Char_t r = (q == 0 ? 'I' : 'O');
227 UShort_t nsec = (q == 0 ? 20 : 40);
228 UShort_t nstr = (q == 0 ? 512 : 256);
230 RingHistos* histos = GetRingHistos(d, r);
232 for(UShort_t s = 0; s < nsec; s++) {
233 for(UShort_t t = 0; t < nstr; t++) {
234 Float_t mult = input.Multiplicity(d,r,s,t);
236 // Keep dead-channel information.
237 if(mult == AliESDFMD::kInvalidMult || mult > 10 || mult <= 0)
240 // Get the pseudo-rapidity
241 Double_t eta1 = input.Eta(d,r,s,t);
242 Int_t ieta = fEtaAxis.FindBin(eta1);
243 if (ieta < 1 || ieta > fEtaAxis.GetNbins()) continue;
245 histos->Fill(empty, ieta-1, mult);
255 //____________________________________________________________________
257 AliFMDEnergyFitter::Fit(TList* dir)
259 if (!fDoFits) return;
261 TList* d = static_cast<TList*>(dir->FindObject(GetName()));
267 // +fNLandau-1 for weights
268 Int_t nStack = 1+3+1+fNLandau-1;
269 THStack* stack[nStack];
270 stack[0] = new THStack("chi2", "#chi^{2}/#nu");
271 stack[1] = new THStack("c", "constant");
272 stack[2] = new THStack("mpv", "#Delta_{p}");
273 stack[3] = new THStack("w", "w");
274 stack[4] = new THStack("n", "# of Landaus");
275 for (Int_t i = 2; i <= fNLandau; i++)
276 stack[i-1+4] = new THStack(Form("a%d", i),
277 Form("Weight of %d signal", i));
278 for (Int_t i = 0; i < nStack; i++)
281 TIter next(&fRingHistos);
283 while ((o = static_cast<RingHistos*>(next()))) {
284 TObjArray* l = o->Fit(d, fEtaAxis, fLowCut, fNLandau,
285 fMinEntries, fBinsToSubtract);
287 for (Int_t i = 0; i < l->GetEntriesFast(); i++) {
288 stack[i % nStack]->Add(static_cast<TH1*>(l->At(i)));
293 //____________________________________________________________________
295 AliFMDEnergyFitter::DefineOutput(TList* dir)
297 TList* d = new TList;
298 d->SetName(GetName());
301 TIter next(&fRingHistos);
303 while ((o = static_cast<RingHistos*>(next()))) {
307 //____________________________________________________________________
309 AliFMDEnergyFitter::SetDebug(Int_t dbg)
312 TIter next(&fRingHistos);
314 while ((o = static_cast<RingHistos*>(next())))
318 //====================================================================
319 AliFMDEnergyFitter::RingHistos::RingHistos()
320 : AliForwardUtil::RingHistos(),
328 //____________________________________________________________________
329 AliFMDEnergyFitter::RingHistos::RingHistos(UShort_t d, Char_t r)
330 : AliForwardUtil::RingHistos(d,r),
337 fEtaEDists.SetName("EDists");
339 //____________________________________________________________________
340 AliFMDEnergyFitter::RingHistos::RingHistos(const RingHistos& o)
341 : AliForwardUtil::RingHistos(o),
348 TIter next(&o.fEtaEDists);
350 while ((obj = next())) fEtaEDists.Add(obj->Clone());
353 fList->SetName(fName);
354 TIter next2(o.fList);
355 while ((obj = next2())) fList->Add(obj->Clone());
359 //____________________________________________________________________
360 AliFMDEnergyFitter::RingHistos&
361 AliFMDEnergyFitter::RingHistos::operator=(const RingHistos& o)
363 AliForwardUtil::RingHistos::operator=(o);
365 if (fEDist) delete fEDist;
366 if (fEmpty) delete fEmpty;
368 if (fList) fList->Delete();
370 fEDist = static_cast<TH1D*>(o.fEDist->Clone());
371 fEmpty = static_cast<TH1D*>(o.fEmpty->Clone());
373 TIter next(&o.fEtaEDists);
375 while ((obj = next())) fEtaEDists.Add(obj->Clone());
379 fList->SetName(fName);
380 TIter next2(o.fList);
381 while ((obj = next2())) fList->Add(obj->Clone());
386 //____________________________________________________________________
387 AliFMDEnergyFitter::RingHistos::~RingHistos()
389 if (fEDist) delete fEDist;
393 //____________________________________________________________________
395 AliFMDEnergyFitter::RingHistos::Fill(Bool_t empty, Int_t ieta, Double_t mult)
403 if (ieta < 0 || ieta >= fEtaEDists.GetEntries()) return;
405 TH1D* h = static_cast<TH1D*>(fEtaEDists.At(ieta));
411 //__________________________________________________________________
413 AliFMDEnergyFitter::RingHistos::MakeIncreasingAxis(Int_t n, Double_t min,
416 // Service function to define a logarithmic axis.
419 // min Minimum of axis
420 // max Maximum of axis
422 Double_t dx = (max-min) / n;
425 for (i = 1; i < n+1; i++) {
426 Double_t dI = float(i)/n;
427 Double_t next = bins[i-1] + dx + dI * dI * dx;
429 if (next > max) break;
435 //____________________________________________________________________
437 AliFMDEnergyFitter::RingHistos::Make(Int_t ieta, Double_t emin, Double_t emax,
438 Double_t deMax, Int_t nDeBins,
442 TString name = Form("%s_etabin%03d", fName.Data(), ieta);
443 TString title = Form("#DeltaE/#DeltaE_{mip} for %s %+5.3f#leq#eta<%+5.3f "
444 "(#eta bin %d)", fName.Data(), emin, emax, ieta);
446 h = new TH1D(name.Data(), title.Data(), nDeBins, 0, deMax);
448 TArrayD deAxis = MakeIncreasingAxis(nDeBins, 0, deMax);
449 h = new TH1D(name.Data(), title.Data(), deAxis.fN-1, deAxis.fArray);
453 h->SetXTitle("#DeltaE/#DeltaE_{mip}");
454 h->SetFillColor(Color());
455 h->SetMarkerColor(Color());
456 h->SetLineColor(Color());
457 h->SetFillStyle(3001);
460 fEtaEDists.AddAt(h, ieta-1);
462 //____________________________________________________________________
464 AliFMDEnergyFitter::RingHistos::MakePar(const char* name,
466 const TAxis& eta) const
468 TH1D* h = new TH1D(Form("%s_%s", fName.Data(), name),
469 Form("%s for %s", title, fName.Data()),
470 eta.GetNbins(), eta.GetXmin(), eta.GetXmax());
471 h->SetXTitle("#eta");
474 h->SetFillColor(Color());
475 h->SetMarkerColor(Color());
476 h->SetLineColor(Color());
477 h->SetFillStyle(3001);
482 //____________________________________________________________________
484 AliFMDEnergyFitter::RingHistos::MakeTotal(const char* name,
492 Double_t xlow = eta.GetBinLowEdge(low);
493 Double_t xhigh = eta.GetBinUpEdge(high);
494 TH1D* h = new TH1D(Form("%s_%s", fName.Data(), name),
495 Form("%s for %s", title, fName.Data()),
497 h->SetBinContent(1, val);
498 h->SetBinError(1, err);
499 h->SetXTitle("#eta");
503 h->SetMarkerColor(Color());
504 h->SetLineColor(Color());
512 //____________________________________________________________________
514 AliFMDEnergyFitter::RingHistos::Init(const TAxis& eAxis,
515 Double_t maxDE, Int_t nDEbins,
518 fEDist = new TH1D(Form("%s_edist", fName.Data()),
519 Form("#DeltaE/#DeltaE_{mip} for %s", fName.Data()),
521 fEmpty = new TH1D(Form("%s_empty", fName.Data()),
522 Form("#DeltaE/#DeltaE_{mip} for %s (empty events)",
523 fName.Data()), 200, 0, 6);
526 // fEtaEDists.Expand(eAxis.GetNbins());
527 for (Int_t i = 1; i <= eAxis.GetNbins(); i++) {
528 Double_t min = eAxis.GetBinLowEdge(i);
529 Double_t max = eAxis.GetBinUpEdge(i);
530 Make(i, min, max, maxDE, nDEbins, useIncrBin);
532 fList->Add(&fEtaEDists);
534 //____________________________________________________________________
536 AliFMDEnergyFitter::RingHistos::Fit(TList* dir, const TAxis& eta,
537 Double_t lowCut, UShort_t nLandau,
539 UShort_t minusBins) const
541 TList* l = GetOutputList(dir);
544 TList* dists = static_cast<TList*>(l->FindObject("EDists"));
546 AliWarning(Form("Didn't find %s_EtaEDists in %s",
547 fName.Data(), l->GetName()));
552 TObjArray* pars = new TObjArray(3+nLandau+1);
553 pars->SetName("FitResults");
563 pars->Add(hChi2 = MakePar("chi2", "#chi^{2}/#nu", eta));
564 pars->Add(hC = MakePar("c", "Constant", eta));
565 pars->Add(hMpv = MakePar("mpv", "#Delta_{p}", eta));
566 pars->Add(hW = MakePar("w", "#xi", eta));
567 pars->Add(hS = MakePar("s", "#sigma", eta));
568 pars->Add(hN = MakePar("n", "N", eta));
569 for (UShort_t i = 1; i < nLandau; i++)
570 pars->Add(hA[i-1] = MakePar(Form("a%d",i+1), Form("a_{%d}",i+1), eta));
573 Int_t nDists = dists->GetEntries();
576 for (Int_t i = 0; i < nDists; i++) {
577 TH1D* dist = static_cast<TH1D*>(dists->At(i));
581 TF1* res = FitHist(dist,lowCut,nLandau,minEntries,minusBins);
584 low = TMath::Min(low,i+1);
585 high = TMath::Max(high,i+1);
587 Double_t chi2 = res->GetChisquare();
588 Int_t ndf = res->GetNDF();
589 hChi2->SetBinContent(i+1, ndf > 0 ? chi2 / ndf : 0);
590 hC ->SetBinContent(i+1, res->GetParameter(0));
591 hMpv->SetBinContent(i+1, res->GetParameter(1));
592 hW ->SetBinContent(i+1, res->GetParameter(2));
593 hN ->SetBinContent(i+1, res->GetParameter(3));
595 hC ->SetBinError(i+1, res->GetParError(1));
596 hMpv->SetBinError(i+1, res->GetParError(2));
597 hW ->SetBinError(i+1, res->GetParError(2));
598 // hN ->SetBinError(i, res->GetParError(3));
600 for (UShort_t j = 0; j < nLandau-1; j++) {
601 hA[j]->SetBinContent(i+1, res->GetParameter(4+j));
602 hA[j]->SetBinError(i+1, res->GetParError(4+j));
606 TH1* total = GetOutputHist(l, Form("%s_edist", fName.Data()));
608 TF1* res = FitHist(total,lowCut,nLandau,minEntries,minusBins);
610 Double_t chi2 = res->GetChisquare();
611 Int_t ndf = res->GetNDF();
612 pars->Add(MakeTotal("t_chi2", "#chi^{2}/#nu", eta, low, high,
613 ndf > 0 ? chi2/ndf : 0, 0));
614 pars->Add(MakeTotal("t_c", "Constant", eta, low, high,
615 res->GetParameter(0),res->GetParError(0)));
616 pars->Add(MakeTotal("t_mpv", "#Delta_{p}", eta, low, high,
617 res->GetParameter(1),res->GetParError(1)));
618 pars->Add(MakeTotal("t_w", "#xi", eta, low, high,
619 res->GetParameter(2),res->GetParError(2)));
620 pars->Add(MakeTotal("t_n", "N", eta, low, high,
621 res->GetParameter(3),0));
622 for (UShort_t j = 1; j < nLandau; j++)
623 pars->Add(MakeTotal(Form("a%d_t",j+1),
624 Form("a_{%d}",j+1), eta, low, high,
625 res->GetParameter(3+j), res->GetParError(3+j)));
629 TObjLink* lnk = dists->FirstLink();
631 TH1* h = static_cast<TH1*>(lnk->GetObject());
632 if (h->GetEntries() <= 0 ||
633 h->GetListOfFunctions()->GetEntries() <= 0) {
634 TObjLink* keep = lnk->Next();
645 //____________________________________________________________________
647 AliFMDEnergyFitter::RingHistos::FitHist(TH1* dist,Double_t lowCut,
650 UShort_t minusBins) const
652 Double_t maxRange = 10;
654 if (dist->GetEntries() <= minEntries) return 0;
656 // Find the fit range
657 dist->GetXaxis()->SetRangeUser(lowCut, maxRange);
659 // Normalize peak to 1
660 Double_t max = dist->GetMaximum();
663 // Get the bin with maximum
664 Int_t maxBin = dist->GetMaximumBin();
665 Double_t maxE = dist->GetBinLowEdge(maxBin);
668 dist->GetXaxis()->SetRangeUser(lowCut, maxE);
669 Int_t minBin = maxBin - minusBins; // dist->GetMinimumBin();
670 Double_t minE = TMath::Max(dist->GetBinCenter(minBin),lowCut);
671 Double_t maxEE = dist->GetBinCenter(maxBin+2*minusBins);
674 dist->GetXaxis()->SetRangeUser(0, maxRange);
676 // First do a single landau fit
677 TF1* landau1 = new TF1("landau1", "landau", minE, maxEE);
678 // landau1->SetParameters(1,1,1,1);
679 landau1->SetParNames("C","#Delta_{p}","#xi");
680 landau1->SetParLimits(1,minE,maxRange);
681 landau1->SetParLimits(2,0,maxRange);
682 landau1->SetLineColor(Color());
683 // Tight fit around peak - make sure we get that right.
684 TFitResultPtr r = dist->Fit(landau1, "RQNS", "", minE, maxEE);
686 return FitMore2(dist, nLandau, *r, landau1, minE, maxRange);
689 //____________________________________________________________________
691 AliFMDEnergyFitter::RingHistos::FitMore(TH1* dist,
696 Double_t maxRange) const
698 static TClonesArray res("TFitResult");
699 static TObjArray funcs;
706 new(res[nRes++]) TFitResult(r);
707 funcs.AddAtAndExpand(landau1, 0);
710 for (UShort_t n = 2; n <= nLandau; n++) {
711 TFitResult* rr = static_cast<TFitResult*>(res.At(nRes-1));
713 AliError(Form("No previous result (%p, %d) for n=%d", rr, nRes, n));
716 // Create the function object
717 Double_t mpvi = rr->Parameter(1);
718 Double_t wi = rr->Parameter(2);
719 Double_t maxEi = n*(mpvi+wi*TMath::Log(n))+2*n*wi;
720 TF1* landaui = new TF1(Form("landau%d", n), &NLandau, minE, maxEi,3+n);
721 landaui->SetLineStyle((n % 10)+1);
722 landaui->SetLineWidth(2);
723 landaui->SetLineColor(Color());
724 landaui->SetParameter(0, rr->Parameter(0));
725 landaui->SetParameter(1, rr->Parameter(1));
726 landaui->SetParameter(2, rr->Parameter(2));
727 landaui->SetParLimits(1, minE, maxRange);
728 landaui->SetParLimits(2,0,maxRange);
729 landaui->FixParameter(3, n);
730 landaui->SetParNames("C","#Delta_{p}","#xi", "N");
731 for (UShort_t i = 2; i < n; i++) {// Take parameters from last fit
732 landaui->SetParameter(N_A(i), rr->Parameter(N_A(i)));
733 landaui->SetParLimits(N_A(i), 0,1);
734 landaui->SetParName(i, Form("a_{%d}", i));
736 landaui->SetParameter(N_A(n), (n == 2 ? 0.05 : rr->Parameter(N_A(n-1))/5));
737 landaui->SetParLimits(N_A(n), 0, 1);
738 landaui->SetParName(N_A(n), Form("a_{%d}", n));
741 TFitResultPtr tr = dist->Fit(landaui, "RNSQ", "", minE, maxEi);
743 if (CheckResult(*tr)) {
744 new(res[nRes++]) TFitResult(*tr);
745 funcs.AddAtAndExpand(landaui,n-1);
752 if (funcs.At(nRes-1)) ret = static_cast<TF1*>(funcs.At(nRes-1)->Clone());
753 dist->GetListOfFunctions()->Add(ret);
761 //____________________________________________________________________
763 AliFMDEnergyFitter::RingHistos::FitMore2(TH1* dist,
768 Double_t maxRange) const
770 static TClonesArray res("TFitResult");
771 static TObjArray funcs;
778 new(res[nRes++]) TFitResult(r);
779 funcs.AddAtAndExpand(landau1, 0);
782 for (UShort_t n = 2; n <= nLandau; n++) {
783 TFitResult* rr = static_cast<TFitResult*>(res.At(nRes-1));
785 AliError(Form("No previous result (%p, %d) for n=%d", rr, nRes, n));
788 // Create the function object
789 Double_t mpvi = rr->Parameter(1);
790 Double_t wi = rr->Parameter(2);
791 Double_t maxEi = n*(mpvi+wi*TMath::Log(n))+2*n*wi;
792 TF1* landaui = new TF1(Form("landau%d", n), &NLandau, minE, maxEi,
794 landaui->SetLineStyle((n % 10)+1);
795 landaui->SetLineWidth(2);
796 landaui->SetLineColor(Color());
797 landaui->SetParameter(0, rr->Parameter(0));
798 landaui->SetParameter(1, rr->Parameter(1));
799 landaui->SetParameter(2, rr->Parameter(2));
800 landaui->SetParLimits(1, minE, maxRange);
801 landaui->SetParLimits(2,0,maxRange);
802 landaui->FixParameter(3, n);
803 landaui->SetParNames("C","#Delta_{p}","#xi", "N");
804 for (UShort_t i = 2; i < n; i++) {// Take parameters from last fit
805 landaui->SetParameter(N2_A(i), rr->Parameter(N2_A(i)));
806 landaui->SetParameter(N2_D(i), rr->Parameter(N2_D(i)));
807 landaui->SetParameter(N2_X(i), rr->Parameter(N2_X(i)));
808 landaui->SetParLimits(N2_A(i), 0,1);
809 landaui->SetParLimits(N2_D(i), minE,maxEi);
810 landaui->SetParLimits(N2_X(i), 0,maxRange);
811 landaui->SetParName(N2_A(i), Form("a_{%d}", i));
812 landaui->SetParName(N2_D(i), Form("#Delta_{p,%d}", i));
813 landaui->SetParName(N2_X(i), Form("#xi_{%d}", i));
815 landaui->SetParameter(N2_A(n), n == 2 ? 0.05 : rr->Parameter(N2_A(n-1))/5);
816 landaui->SetParameter(N2_D(n), mpvi);
817 landaui->SetParameter(N2_X(n), wi);
818 landaui->SetParLimits(N2_A(n), 0,1);
819 landaui->SetParLimits(N2_D(n), minE,maxEi);
820 landaui->SetParLimits(N2_X(n), 0,maxRange);
821 landaui->SetParName(N2_A(n), Form("a_{%d}", n));
822 landaui->SetParName(N2_D(n), Form("#Delta_{p,%d}", n));
823 landaui->SetParName(N2_X(n), Form("#xi_{%d}", n));
824 if (fDebug > 2) landaui->Print();
826 TFitResultPtr tr = dist->Fit(landaui, "RNSQ", "", minE, maxEi);
827 if (fDebug > 2) tr->Print();
828 if (CheckResult(*tr)) {
829 new(res[nRes++]) TFitResult(*tr);
830 funcs.AddAtAndExpand(landaui,n-1);
837 if (funcs.At(nRes-1)) ret = static_cast<TF1*>(funcs.At(nRes-1)->Clone());
838 dist->GetListOfFunctions()->Add(ret);
846 //____________________________________________________________________
848 AliFMDEnergyFitter::RingHistos::CheckResult(TFitResult& r) const
850 Double_t chi2 = r.Chi2();
852 // Double_t prob = r.Prob();
853 if (ndf <= 0 || chi2 / ndf > 5) {
855 AliWarning(Form("Fit %s has chi^2/ndf=%f/%d=%f",
856 r.GetName(), chi2, ndf, (ndf<0 ? 0 : chi2/ndf)));
860 UShort_t nPar = r.NPar();
861 for (UShort_t i = 0; i < nPar; i++) {
862 if (i == 3) continue;
864 Double_t v = r.Parameter(i);
865 Double_t e = r.ParError(i);
866 if (v == 0) continue;
867 if (v == 0 || e / v > 0.2) {
869 AliWarning(Form("Fit %s has Delta %s/%s=%f/%f=%f%%",
870 r.GetName(), r.ParName(i).c_str(),
871 r.ParName(i).c_str(), e, v, 100*(v == 0 ? 0 : e/v)));
876 if (r.Parameter(nPar-1) <= 1e-10) {
878 AliWarning(Form("Last scale %s is too small %f<1e-10",
879 r.ParName(nPar-1).c_str(), r.Parameter(nPar-1)));
887 //____________________________________________________________________
889 AliFMDEnergyFitter::RingHistos::Output(TList* dir)
891 fList = DefineOutputList(dir);
894 //____________________________________________________________________