2 // Utilities used in the forward multiplcity analysis
5 #include "AliForwardUtil.h"
6 #include <AliAnalysisManager.h>
7 #include "AliAODForwardMult.h"
9 #include <AliInputEventHandler.h>
10 #include <AliESDEvent.h>
11 #include <AliPhysicsSelection.h>
12 #include <AliTriggerAnalysis.h>
13 #include <AliMultiplicity.h>
17 #include <TFitResult.h>
21 //====================================================================
23 AliForwardUtil::ParseCollisionSystem(const char* sys)
26 // Parse a collision system spec given in a string. Known values are
28 // - "pp", "p-p" which returns kPP
29 // - "PbPb", "Pb-Pb", "A-A", which returns kPbPb
30 // - Everything else gives kUnknown
33 // sys Collision system spec
36 // Collision system id
40 if (s.Contains("p-p") || s.Contains("pp")) return AliForwardUtil::kPP;
41 if (s.Contains("pb-pb") || s.Contains("pbpb")) return AliForwardUtil::kPbPb;
42 if (s.Contains("a-a") || s.Contains("aa")) return AliForwardUtil::kPbPb;
43 return AliForwardUtil::kUnknown;
45 //____________________________________________________________________
47 AliForwardUtil::CollisionSystemString(UShort_t sys)
50 // Get a string representation of the collision system
53 // sys Collision system
56 // - anything else gives "unknown"
59 // String representation of the collision system
62 case AliForwardUtil::kPP: return "pp";
63 case AliForwardUtil::kPbPb: return "PbPb";
67 //____________________________________________________________________
69 AliForwardUtil::ParseCenterOfMassEnergy(UShort_t /* sys */, Float_t v)
72 // Parse the center of mass energy given as a float and return known
73 // values as a unsigned integer
76 // sys Collision system (needed for AA)
77 // cms Center of mass energy * total charge
80 // Center of mass energy per nucleon
83 // Below no longer needed apparently
84 // if (sys == AliForwardUtil::kPbPb) energy = energy / 208 * 82;
85 if (TMath::Abs(energy - 900.) < 10) return 900;
86 if (TMath::Abs(energy - 2400.) < 10) return 2400;
87 if (TMath::Abs(energy - 2750.) < 10) return 2750;
88 if (TMath::Abs(energy - 5500.) < 40) return 5500;
89 if (TMath::Abs(energy - 7000.) < 10) return 7000;
90 if (TMath::Abs(energy - 10000.) < 10) return 10000;
91 if (TMath::Abs(energy - 14000.) < 10) return 14000;
94 //____________________________________________________________________
96 AliForwardUtil::CenterOfMassEnergyString(UShort_t cms)
99 // Get a string representation of the center of mass energy per nuclean
102 // cms Center of mass energy per nucleon
105 // String representation of the center of mass energy per nuclean
107 return Form("%04dGeV", cms);
109 //____________________________________________________________________
111 AliForwardUtil::ParseMagneticField(Float_t v)
114 // Parse the magnetic field (in kG) as given by a floating point number
117 // field Magnetic field in kG
120 // Short integer value of magnetic field in kG
122 if (TMath::Abs(v - 5.) < 1 ) return +5;
123 if (TMath::Abs(v + 5.) < 1 ) return -5;
124 if (TMath::Abs(v) < 1) return 0;
127 //____________________________________________________________________
129 AliForwardUtil::MagneticFieldString(Short_t f)
132 // Get a string representation of the magnetic field
135 // field Magnetic field in kG
138 // String representation of the magnetic field
140 return Form("%01dkG", f);
144 //====================================================================
145 Int_t AliForwardUtil::fgConvolutionSteps = 100;
146 Double_t AliForwardUtil::fgConvolutionNSigma = 5;
149 // The shift of the most probable value for the ROOT function TMath::Landau
151 const Double_t mpshift = -0.22278298;
153 // Integration normalisation
155 const Double_t invSq2pi = 1. / TMath::Sqrt(2*TMath::Pi());
158 // Utility function to use in TF1 defintition
160 Double_t landauGaus1(Double_t* xp, Double_t* pp)
163 Double_t constant = pp[AliForwardUtil::ELossFitter::kC];
164 Double_t delta = pp[AliForwardUtil::ELossFitter::kDelta];
165 Double_t xi = pp[AliForwardUtil::ELossFitter::kXi];
166 Double_t sigma = pp[AliForwardUtil::ELossFitter::kSigma];
167 Double_t sigmaN = pp[AliForwardUtil::ELossFitter::kSigmaN];
169 return constant * AliForwardUtil::LandauGaus(x, delta, xi, sigma, sigmaN);
173 // Utility function to use in TF1 defintition
175 Double_t landauGausN(Double_t* xp, Double_t* pp)
178 Double_t constant = pp[AliForwardUtil::ELossFitter::kC];
179 Double_t delta = pp[AliForwardUtil::ELossFitter::kDelta];
180 Double_t xi = pp[AliForwardUtil::ELossFitter::kXi];
181 Double_t sigma = pp[AliForwardUtil::ELossFitter::kSigma];
182 Double_t sigmaN = pp[AliForwardUtil::ELossFitter::kSigmaN];
183 Int_t n = Int_t(pp[AliForwardUtil::ELossFitter::kN]);
184 Double_t* a = &(pp[AliForwardUtil::ELossFitter::kA]);
186 return constant * AliForwardUtil::NLandauGaus(x, delta, xi, sigma, sigmaN,
190 // Utility function to use in TF1 defintition
192 Double_t landauGausI(Double_t* xp, Double_t* pp)
195 Double_t constant = pp[AliForwardUtil::ELossFitter::kC];
196 Double_t delta = pp[AliForwardUtil::ELossFitter::kDelta];
197 Double_t xi = pp[AliForwardUtil::ELossFitter::kXi];
198 Double_t sigma = pp[AliForwardUtil::ELossFitter::kSigma];
199 Double_t sigmaN = pp[AliForwardUtil::ELossFitter::kSigmaN];
200 Int_t i = Int_t(pp[AliForwardUtil::ELossFitter::kN]);
202 return constant * AliForwardUtil::ILandauGaus(x,delta,xi,sigma,sigmaN,i);
207 //____________________________________________________________________
209 AliForwardUtil::Landau(Double_t x, Double_t delta, Double_t xi)
212 // Calculate the shifted Landau
214 // f'_{L}(x;\Delta,\xi) = f_L(x;\Delta+0.22278298\xi)
217 // where @f$ f_{L}@f$ is the ROOT implementation of the Landau
218 // distribution (known to have @f$ \Delta_{p}=-0.22278298@f$ for
219 // @f$\Delta=0,\xi=1@f$.
222 // x Where to evaluate @f$ f'_{L}@f$
223 // delta Most probable value
224 // xi The 'width' of the distribution
227 // @f$ f'_{L}(x;\Delta,\xi) @f$
229 return TMath::Landau(x, delta - xi * mpshift, xi);
231 //____________________________________________________________________
233 AliForwardUtil::LandauGaus(Double_t x, Double_t delta, Double_t xi,
234 Double_t sigma, Double_t sigmaN)
237 // Calculate the value of a Landau convolved with a Gaussian
240 // f(x;\Delta,\xi,\sigma') = \frac{1}{\sigma' \sqrt{2 \pi}}
241 // \int_{-\infty}^{+\infty} d\Delta' f'_{L}(x;\Delta',\xi)
242 // \exp{-\frac{(\Delta-\Delta')^2}{2\sigma'^2}}
245 // where @f$ f'_{L}@f$ is the Landau distribution, @f$ \Delta@f$ the
246 // energy loss, @f$ \xi@f$ the width of the Landau, and
247 // @f$ \sigma'^2=\sigma^2-\sigma_n^2 @f$. Here, @f$\sigma@f$ is the
248 // variance of the Gaussian, and @f$\sigma_n@f$ is a parameter modelling
249 // noise in the detector.
251 // Note that this function uses the constants fgConvolutionSteps and
252 // fgConvolutionNSigma
255 // - <a href="http://dx.doi.org/10.1016/0168-583X(84)90472-5">Nucl.Instrum.Meth.B1:16</a>
256 // - <a href="http://dx.doi.org/10.1103/PhysRevA.28.615">Phys.Rev.A28:615</a>
257 // - <a href="http://root.cern.ch/root/htmldoc/tutorials/fit/langaus.C.html">ROOT implementation</a>
260 // x where to evaluate @f$ f@f$
261 // delta @f$ \Delta@f$ of @f$ f(x;\Delta,\xi,\sigma')@f$
262 // xi @f$ \xi@f$ of @f$ f(x;\Delta,\xi,\sigma')@f$
263 // sigma @f$ \sigma@f$ of @f$\sigma'^2=\sigma^2-\sigma_n^2 @f$
264 // sigma_n @f$ \sigma_n@f$ of @f$\sigma'^2=\sigma^2-\sigma_n^2 @f$
267 // @f$ f@f$ evaluated at @f$ x@f$.
269 Double_t deltap = delta - xi * mpshift;
270 Double_t sigma2 = sigmaN*sigmaN + sigma*sigma;
271 Double_t sigma1 = sigmaN == 0 ? sigma : TMath::Sqrt(sigma2);
272 Double_t xlow = x - fgConvolutionNSigma * sigma1;
273 Double_t xhigh = x + fgConvolutionNSigma * sigma1;
274 Double_t step = (xhigh - xlow) / fgConvolutionSteps;
277 for (Int_t i = 0; i <= fgConvolutionSteps/2; i++) {
278 Double_t x1 = xlow + (i - .5) * step;
279 Double_t x2 = xhigh - (i - .5) * step;
281 sum += TMath::Landau(x1, deltap, xi, kTRUE) * TMath::Gaus(x, x1, sigma1);
282 sum += TMath::Landau(x2, deltap, xi, kTRUE) * TMath::Gaus(x, x2, sigma1);
284 return step * sum * invSq2pi / sigma1;
287 //____________________________________________________________________
289 AliForwardUtil::ILandauGaus(Double_t x, Double_t delta, Double_t xi,
290 Double_t sigma, Double_t sigmaN, Int_t i)
295 // f_i(x;\Delta,\xi,\sigma') = f(x;\Delta_i,\xi_i,\sigma_i')
297 // corresponding to @f$ i@f$ particles i.e., with the substitutions
299 // \Delta \rightarrow \Delta_i &=& i(\Delta + \xi\log(i))
300 // \xi \rightarrow \xi_i &=& i \xi
301 // \sigma \rightarrow \sigma_i &=& \sqrt{i}\sigma
302 // \sigma'^2 \rightarrow \sigma_i'^2 &=& \sigma_n^2 + \sigma_i^2
306 // x Where to evaluate
307 // delta @f$ \Delta@f$
309 // sigma @f$ \sigma@f$
310 // sigma_n @f$ \sigma_n@f$
314 // @f$ f_i @f$ evaluated
316 Double_t deltaI = (i == 1 ? delta : i * (delta + xi * TMath::Log(i)));
317 Double_t xiI = i * xi;
318 Double_t sigmaI = (i == 1 ? sigma : TMath::Sqrt(Double_t(i))*sigma);
319 if (sigmaI < 1e-10) {
320 // Fall back to landau
321 return AliForwardUtil::Landau(x, deltaI, xiI);
323 return AliForwardUtil::LandauGaus(x, deltaI, xiI, sigmaI, sigmaN);
326 //____________________________________________________________________
328 AliForwardUtil::IdLandauGausdPar(Double_t x,
329 UShort_t par, Double_t dPar,
330 Double_t delta, Double_t xi,
331 Double_t sigma, Double_t sigmaN,
335 // Numerically evaluate
337 // \left.\frac{\partial f_i}{\partial p_i}\right|_{x}
339 // where @f$ p_i@f$ is the @f$ i^{\mbox{th}}@f$ parameter. The mapping
340 // of the parameters is given by
345 // - 3: @f$\sigma_n@f$
347 // This is the partial derivative with respect to the parameter of
348 // the response function corresponding to @f$ i@f$ particles i.e.,
349 // with the substitutions
351 // \Delta \rightarrow \Delta_i = i(\Delta + \xi\log(i))
352 // \xi \rightarrow \xi_i = i \xi
353 // \sigma \rightarrow \sigma_i = \sqrt{i}\sigma
354 // \sigma'^2 \rightarrow \sigma_i'^2 = \sigma_n^2 + \sigma_i^2
358 // x Where to evaluate
359 // ipar Parameter number
360 // dp @f$ \epsilon\delta p_i@f$ for some value of @f$\epsilon@f$
361 // delta @f$ \Delta@f$
363 // sigma @f$ \sigma@f$
364 // sigma_n @f$ \sigma_n@f$
368 // @f$ f_i@f$ evaluated
370 if (dPar == 0) return 0;
372 Double_t d2 = dPar / 2;
373 Double_t deltaI = i * (delta + xi * TMath::Log(i));
374 Double_t xiI = i * xi;
375 Double_t si = TMath::Sqrt(Double_t(i));
376 Double_t sigmaI = si*sigma;
383 y1 = ILandauGaus(x, deltaI+i*dp, xiI, sigmaI, sigmaN, i);
384 y2 = ILandauGaus(x, deltaI+i*d2, xiI, sigmaI, sigmaN, i);
385 y3 = ILandauGaus(x, deltaI-i*d2, xiI, sigmaI, sigmaN, i);
386 y4 = ILandauGaus(x, deltaI-i*dp, xiI, sigmaI, sigmaN, i);
389 y1 = ILandauGaus(x, deltaI, xiI+i*dp, sigmaI, sigmaN, i);
390 y2 = ILandauGaus(x, deltaI, xiI+i*d2, sigmaI, sigmaN, i);
391 y3 = ILandauGaus(x, deltaI, xiI-i*d2, sigmaI, sigmaN, i);
392 y4 = ILandauGaus(x, deltaI, xiI-i*dp, sigmaI, sigmaN, i);
395 y1 = ILandauGaus(x, deltaI, xiI, sigmaI+si*dp, sigmaN, i);
396 y2 = ILandauGaus(x, deltaI, xiI, sigmaI+si*d2, sigmaN, i);
397 y3 = ILandauGaus(x, deltaI, xiI, sigmaI-si*d2, sigmaN, i);
398 y4 = ILandauGaus(x, deltaI, xiI, sigmaI-si*dp, sigmaN, i);
401 y1 = ILandauGaus(x, deltaI, xiI, sigmaI, sigmaN+dp, i);
402 y2 = ILandauGaus(x, deltaI, xiI, sigmaI, sigmaN+d2, i);
403 y3 = ILandauGaus(x, deltaI, xiI, sigmaI, sigmaN-d2, i);
404 y4 = ILandauGaus(x, deltaI, xiI, sigmaI, sigmaN-dp, i);
410 Double_t d0 = y1 - y4;
411 Double_t d1 = 2 * (y2 - y3);
413 Double_t g = 1/(2*dp) * (4*d1 - d0) / 3;
418 //____________________________________________________________________
420 AliForwardUtil::NLandauGaus(Double_t x, Double_t delta, Double_t xi,
421 Double_t sigma, Double_t sigmaN, Int_t n,
427 // f_N(x;\Delta,\xi,\sigma') = \sum_{i=1}^N a_i f_i(x;\Delta,\xi,\sigma'a)
430 // where @f$ f(x;\Delta,\xi,\sigma')@f$ is the convolution of a
431 // Landau with a Gaussian (see LandauGaus). Note that
432 // @f$ a_1 = 1@f$, @f$\Delta_i = i(\Delta_1 + \xi\log(i))@f$,
433 // @f$\xi_i=i\xi_1@f$, and @f$\sigma_i'^2 = \sigma_n^2 + i\sigma_1^2@f$.
436 // - <a href="http://dx.doi.org/10.1016/0168-583X(84)90472-5">Nucl.Instrum.Meth.B1:16</a>
437 // - <a href="http://dx.doi.org/10.1103/PhysRevA.28.615">Phys.Rev.A28:615</a>
438 // - <a href="http://root.cern.ch/root/htmldoc/tutorials/fit/langaus.C.html">ROOT implementation</a>
441 // x Where to evaluate @f$ f_N@f$
442 // delta @f$ \Delta_1@f$
444 // sigma @f$ \sigma_1@f$
445 // sigma_n @f$ \sigma_n@f$
446 // n @f$ N@f$ in the sum above.
447 // a Array of size @f$ N-1@f$ of the weights @f$ a_i@f$ for
451 // @f$ f_N(x;\Delta,\xi,\sigma')@f$
453 Double_t result = ILandauGaus(x, delta, xi, sigma, sigmaN, 1);
454 for (Int_t i = 2; i <= n; i++)
455 result += a[i-2] * AliForwardUtil::ILandauGaus(x,delta,xi,sigma,sigmaN,i);
459 const Int_t kColors[] = { kRed+1,
473 //____________________________________________________________________
475 AliForwardUtil::MakeNLandauGaus(Double_t c,
476 Double_t delta, Double_t xi,
477 Double_t sigma, Double_t sigmaN, Int_t n,
479 Double_t xmin, Double_t xmax)
482 // Generate a TF1 object of @f$ f_N@f$
486 // delta @f$ \Delta@f$
488 // sigma @f$ \sigma_1@f$
489 // sigma_n @f$ \sigma_n@f$
490 // n @f$ N@f$ - how many particles to sum to
491 // a Array of size @f$ N-1@f$ of the weights @f$ a_i@f$ for
493 // xmin Least value of range
494 // xmax Largest value of range
497 // Newly allocated TF1 object
499 Int_t npar = AliForwardUtil::ELossFitter::kN+n;
500 TF1* landaun = new TF1(Form("nlandau%d", n), &landauGausN,xmin,xmax,npar);
501 // landaun->SetLineStyle(((n-2) % 10)+2); // start at dashed
502 landaun->SetLineColor(kColors[((n-1) % 12)]); // start at red
503 landaun->SetLineWidth(2);
504 landaun->SetNpx(500);
505 landaun->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}", "N");
507 // Set the initial parameters from the seed fit
508 landaun->SetParameter(AliForwardUtil::ELossFitter::kC, c);
509 landaun->SetParameter(AliForwardUtil::ELossFitter::kDelta, delta);
510 landaun->SetParameter(AliForwardUtil::ELossFitter::kXi, xi);
511 landaun->SetParameter(AliForwardUtil::ELossFitter::kSigma, sigma);
512 landaun->SetParameter(AliForwardUtil::ELossFitter::kSigmaN, sigmaN);
513 landaun->FixParameter(AliForwardUtil::ELossFitter::kN, n);
515 // Set the range and name of the scale parameters
516 for (UShort_t i = 2; i <= n; i++) {// Take parameters from last fit
517 landaun->SetParameter(AliForwardUtil::ELossFitter::kA+i-2, a[i-2]);
518 landaun->SetParName(AliForwardUtil::ELossFitter::kA+i-2, Form("a_{%d}", i));
522 //____________________________________________________________________
524 AliForwardUtil::MakeILandauGaus(Double_t c,
525 Double_t delta, Double_t xi,
526 Double_t sigma, Double_t sigmaN, Int_t i,
527 Double_t xmin, Double_t xmax)
530 // Generate a TF1 object of @f$ f_I@f$
534 // delta @f$ \Delta@f$
536 // sigma @f$ \sigma_1@f$
537 // sigma_n @f$ \sigma_n@f$
538 // i @f$ i@f$ - the number of particles
539 // xmin Least value of range
540 // xmax Largest value of range
543 // Newly allocated TF1 object
545 Int_t npar = AliForwardUtil::ELossFitter::kN+1;
546 TF1* landaui = new TF1(Form("ilandau%d", i), &landauGausI,xmin,xmax,npar);
547 // landaui->SetLineStyle(((i-2) % 10)+2); // start at dashed
548 landaui->SetLineColor(kColors[((i-1) % 12)]); // start at red
549 landaui->SetLineWidth(1);
550 landaui->SetNpx(500);
551 landaui->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}", "i");
553 // Set the initial parameters from the seed fit
554 landaui->SetParameter(AliForwardUtil::ELossFitter::kC, c);
555 landaui->SetParameter(AliForwardUtil::ELossFitter::kDelta, delta);
556 landaui->SetParameter(AliForwardUtil::ELossFitter::kXi, xi);
557 landaui->SetParameter(AliForwardUtil::ELossFitter::kSigma, sigma);
558 landaui->SetParameter(AliForwardUtil::ELossFitter::kSigmaN, sigmaN);
559 landaui->FixParameter(AliForwardUtil::ELossFitter::kN, i);
564 //====================================================================
565 AliForwardUtil::ELossFitter::ELossFitter(Double_t lowCut,
568 : fLowCut(lowCut), fMaxRange(maxRange), fMinusBins(minusBins),
569 fFitResults(0), fFunctions(0)
575 // lowCut Lower cut of spectrum - data below this cuts is ignored
576 // maxRange Maximum range to fit to
577 // minusBins The number of bins below maximum to use
579 fFitResults.SetOwner();
580 fFunctions.SetOwner();
582 //____________________________________________________________________
583 AliForwardUtil::ELossFitter::~ELossFitter()
589 fFitResults.Delete();
592 //____________________________________________________________________
594 AliForwardUtil::ELossFitter::Clear()
597 // Clear internal arrays
603 //____________________________________________________________________
605 AliForwardUtil::ELossFitter::Fit1Particle(TH1* dist, Double_t sigman)
608 // Fit a 1-particle signal to the passed energy loss distribution
610 // Note that this function clears the internal arrays first
613 // dist Data to fit the function to
614 // sigman If larger than zero, the initial guess of the
615 // detector induced noise. If zero or less, then this
616 // parameter is ignored in the fit (fixed at 0)
619 // The function fitted to the data
625 // Find the fit range
626 dist->GetXaxis()->SetRangeUser(fLowCut, fMaxRange);
628 // Get the bin with maximum
629 Int_t maxBin = dist->GetMaximumBin();
630 Double_t maxE = dist->GetBinLowEdge(maxBin);
633 dist->GetXaxis()->SetRangeUser(fLowCut, maxE);
634 Int_t minBin = maxBin - fMinusBins; // dist->GetMinimumBin();
635 Double_t minE = TMath::Max(dist->GetBinCenter(minBin),fLowCut);
636 Double_t maxEE = dist->GetBinCenter(maxBin+2*fMinusBins);
639 dist->GetXaxis()->SetRangeUser(0, fMaxRange);
641 // Define the function to fit
642 TF1* landau1 = new TF1("landau1", landauGaus1, minE,maxEE,kSigmaN+1);
644 // Set initial guesses, parameter names, and limits
645 landau1->SetParameters(1,0.5,0.07,0.1,sigman);
646 landau1->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}");
647 landau1->SetNpx(500);
648 landau1->SetParLimits(kDelta, minE, fMaxRange);
649 landau1->SetParLimits(kXi, 0.00, fMaxRange);
650 landau1->SetParLimits(kSigma, 0.01, 0.1);
651 if (sigman <= 0) landau1->FixParameter(kSigmaN, 0);
652 else landau1->SetParLimits(kSigmaN, 0, fMaxRange);
654 // Do the fit, getting the result object
655 TFitResultPtr r = dist->Fit(landau1, "RNQS", "", minE, maxEE);
656 landau1->SetRange(minE, fMaxRange);
657 fFitResults.AddAtAndExpand(new TFitResult(*r), 0);
658 fFunctions.AddAtAndExpand(landau1, 0);
662 //____________________________________________________________________
664 AliForwardUtil::ELossFitter::FitNParticle(TH1* dist, UShort_t n,
668 // Fit a N-particle signal to the passed energy loss distribution
670 // If there's no 1-particle fit present, it does that first
673 // dist Data to fit the function to
674 // n Number of particle signals to fit
675 // sigman If larger than zero, the initial guess of the
676 // detector induced noise. If zero or less, then this
677 // parameter is ignored in the fit (fixed at 0)
680 // The function fitted to the data
683 // Get the seed fit result
684 TFitResult* r = static_cast<TFitResult*>(fFitResults.At(0));
685 TF1* f = static_cast<TF1*>(fFunctions.At(0));
687 f = Fit1Particle(dist, sigman);
688 r = static_cast<TFitResult*>(fFitResults.At(0));
690 ::Warning("FitNLandau", "No first shot at landau fit");
695 // Get some parameters from seed fit
696 Double_t delta1 = r->Parameter(kDelta);
697 Double_t xi1 = r->Parameter(kXi);
698 Double_t maxEi = n * (delta1 + xi1 * TMath::Log(n)) + 2 * n * xi1;
699 Double_t minE = f->GetXmin();
703 for (UShort_t i = 2; i <= n; i++)
704 a.fArray[i-2] = (n == 2 ? 0.05 : 0.000001);
705 // Make the fit function
706 TF1* landaun = MakeNLandauGaus(r->Parameter(kC),
707 r->Parameter(kDelta),
709 r->Parameter(kSigma),
710 r->Parameter(kSigmaN),
711 n,a.fArray,minE,maxEi);
712 landaun->SetParLimits(kDelta, minE, fMaxRange); // Delta
713 landaun->SetParLimits(kXi, 0.00, fMaxRange); // xi
714 landaun->SetParLimits(kSigma, 0.01, 1); // sigma
715 // Check if we're using the noise sigma
716 if (sigman <= 0) landaun->FixParameter(kSigmaN, 0);
717 else landaun->SetParLimits(kSigmaN, 0, fMaxRange);
719 // Set the range and name of the scale parameters
720 for (UShort_t i = 2; i <= n; i++) {// Take parameters from last fit
721 landaun->SetParLimits(kA+i-2, 0,1);
725 TFitResultPtr tr = dist->Fit(landaun, "RSQN", "", minE, maxEi);
727 landaun->SetRange(minE, fMaxRange);
728 fFitResults.AddAtAndExpand(new TFitResult(*tr), n-1);
729 fFunctions.AddAtAndExpand(landaun, n-1);
734 //====================================================================
735 AliForwardUtil::Histos::~Histos()
740 if (fFMD1i) delete fFMD1i;
741 if (fFMD2i) delete fFMD2i;
742 if (fFMD2o) delete fFMD2o;
743 if (fFMD3i) delete fFMD3i;
744 if (fFMD3o) delete fFMD3o;
747 //____________________________________________________________________
749 AliForwardUtil::Histos::Make(UShort_t d, Char_t r,
750 const TAxis& etaAxis) const
758 // etaAxis Eta axis to use
761 // Newly allocated histogram
763 Int_t ns = (r == 'I' || r == 'i') ? 20 : 40;
764 TH2D* hist = new TH2D(Form("FMD%d%c_cache", d, r),
765 Form("FMD%d%c cache", d, r),
766 etaAxis.GetNbins(), etaAxis.GetXmin(),
767 etaAxis.GetXmax(), ns, 0, 2*TMath::Pi());
768 hist->SetXTitle("#eta");
769 hist->SetYTitle("#phi [radians]");
770 hist->SetZTitle("d^{2}N_{ch}/d#etad#phi");
772 hist->SetDirectory(0);
776 //____________________________________________________________________
778 AliForwardUtil::Histos::Init(const TAxis& etaAxis)
781 // Initialize the object
784 // etaAxis Eta axis to use
786 fFMD1i = Make(1, 'I', etaAxis);
787 fFMD2i = Make(2, 'I', etaAxis);
788 fFMD2o = Make(2, 'O', etaAxis);
789 fFMD3i = Make(3, 'I', etaAxis);
790 fFMD3o = Make(3, 'O', etaAxis);
792 //____________________________________________________________________
794 AliForwardUtil::Histos::Clear(Option_t* option)
802 fFMD1i->Reset(option);
803 fFMD2i->Reset(option);
804 fFMD2o->Reset(option);
805 fFMD3i->Reset(option);
806 fFMD3o->Reset(option);
809 //____________________________________________________________________
811 AliForwardUtil::Histos::Get(UShort_t d, Char_t r) const
814 // Get the histogram for a particular detector,ring
821 // Histogram for detector,ring or nul
824 case 1: return fFMD1i;
825 case 2: return (r == 'I' || r == 'i' ? fFMD2i : fFMD2o);
826 case 3: return (r == 'I' || r == 'i' ? fFMD3i : fFMD3o);
830 //====================================================================
832 AliForwardUtil::RingHistos::DefineOutputList(TList* d) const
835 // Define the outout list in @a d
838 // d Where to put the output list
841 // Newly allocated TList object or null
844 TList* list = new TList;
845 list->SetName(fName.Data());
849 //____________________________________________________________________
851 AliForwardUtil::RingHistos::GetOutputList(TList* d) const
854 // Get our output list from the container @a d
857 // d where to get the output list from
860 // The found TList or null
863 TList* list = static_cast<TList*>(d->FindObject(fName.Data()));
867 //____________________________________________________________________
869 AliForwardUtil::RingHistos::GetOutputHist(TList* d, const char* name) const
872 // Find a specific histogram in the source list @a d
876 // name Name of histogram
879 // Found histogram or null
881 return static_cast<TH1*>(d->FindObject(name));