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 if (sys != AliForwardUtil::kPP) energy = energy / 208 * 82;
84 if (TMath::Abs(energy - 900.) < 10) return 900;
85 if (TMath::Abs(energy - 2400.) < 10) return 2400;
86 if (TMath::Abs(energy - 2750.) < 10) return 2750;
87 if (TMath::Abs(energy - 5500.) < 40) return 5500;
88 if (TMath::Abs(energy - 7000.) < 10) return 7000;
89 if (TMath::Abs(energy - 10000.) < 10) return 10000;
90 if (TMath::Abs(energy - 14000.) < 10) return 14000;
93 //____________________________________________________________________
95 AliForwardUtil::CenterOfMassEnergyString(UShort_t cms)
98 // Get a string representation of the center of mass energy per nuclean
101 // cms Center of mass energy per nucleon
104 // String representation of the center of mass energy per nuclean
106 return Form("%04dGeV", cms);
108 //____________________________________________________________________
110 AliForwardUtil::ParseMagneticField(Float_t v)
113 // Parse the magnetic field (in kG) as given by a floating point number
116 // field Magnetic field in kG
119 // Short integer value of magnetic field in kG
121 if (TMath::Abs(v - 5.) < 1 ) return +5;
122 if (TMath::Abs(v + 5.) < 1 ) return -5;
123 if (TMath::Abs(v) < 1) return 0;
126 //____________________________________________________________________
128 AliForwardUtil::MagneticFieldString(Short_t f)
131 // Get a string representation of the magnetic field
134 // field Magnetic field in kG
137 // String representation of the magnetic field
139 return Form("%01dkG", f);
143 //====================================================================
144 Int_t AliForwardUtil::fgConvolutionSteps = 100;
145 Double_t AliForwardUtil::fgConvolutionNSigma = 5;
148 // The shift of the most probable value for the ROOT function TMath::Landau
150 const Double_t mpshift = -0.22278298;
152 // Integration normalisation
154 const Double_t invSq2pi = 1. / TMath::Sqrt(2*TMath::Pi());
157 // Utility function to use in TF1 defintition
159 Double_t landauGaus1(Double_t* xp, Double_t* pp)
162 Double_t constant = pp[AliForwardUtil::ELossFitter::kC];
163 Double_t delta = pp[AliForwardUtil::ELossFitter::kDelta];
164 Double_t xi = pp[AliForwardUtil::ELossFitter::kXi];
165 Double_t sigma = pp[AliForwardUtil::ELossFitter::kSigma];
166 Double_t sigma_n = pp[AliForwardUtil::ELossFitter::kSigmaN];
168 return constant * AliForwardUtil::LandauGaus(x, delta, xi, sigma, sigma_n);
172 // Utility function to use in TF1 defintition
174 Double_t landauGausN(Double_t* xp, Double_t* pp)
177 Double_t constant = pp[AliForwardUtil::ELossFitter::kC];
178 Double_t delta = pp[AliForwardUtil::ELossFitter::kDelta];
179 Double_t xi = pp[AliForwardUtil::ELossFitter::kXi];
180 Double_t sigma = pp[AliForwardUtil::ELossFitter::kSigma];
181 Double_t sigma_n = pp[AliForwardUtil::ELossFitter::kSigmaN];
182 Int_t n = Int_t(pp[AliForwardUtil::ELossFitter::kN]);
183 Double_t* a = &(pp[AliForwardUtil::ELossFitter::kA]);
185 return constant * AliForwardUtil::NLandauGaus(x, delta, xi, sigma, sigma_n,
189 // Utility function to use in TF1 defintition
191 Double_t landauGausI(Double_t* xp, Double_t* pp)
194 Double_t constant = pp[AliForwardUtil::ELossFitter::kC];
195 Double_t delta = pp[AliForwardUtil::ELossFitter::kDelta];
196 Double_t xi = pp[AliForwardUtil::ELossFitter::kXi];
197 Double_t sigma = pp[AliForwardUtil::ELossFitter::kSigma];
198 Double_t sigma_n = pp[AliForwardUtil::ELossFitter::kSigmaN];
199 Int_t i = Int_t(pp[AliForwardUtil::ELossFitter::kN]);
201 return constant * AliForwardUtil::ILandauGaus(x,delta,xi,sigma,sigma_n,i);
206 //____________________________________________________________________
208 AliForwardUtil::Landau(Double_t x, Double_t delta, Double_t xi)
211 // Calculate the shifted Landau
213 // f'_{L}(x;\Delta,\xi) = f_L(x;\Delta+0.22278298\xi)
216 // where @f$ f_{L}@f$ is the ROOT implementation of the Landau
217 // distribution (known to have @f$ \Delta_{p}=-0.22278298@f$ for
218 // @f$\Delta=0,\xi=1@f$.
221 // x Where to evaluate @f$ f'_{L}@f$
222 // delta Most probable value
223 // xi The 'width' of the distribution
226 // @f$ f'_{L}(x;\Delta,\xi) @f$
228 return TMath::Landau(x, delta - xi * mpshift, xi);
230 //____________________________________________________________________
232 AliForwardUtil::LandauGaus(Double_t x, Double_t delta, Double_t xi,
233 Double_t sigma, Double_t sigma_n)
236 // Calculate the value of a Landau convolved with a Gaussian
239 // f(x;\Delta,\xi,\sigma') = \frac{1}{\sigma' \sqrt{2 \pi}}
240 // \int_{-\infty}^{+\infty} d\Delta' f'_{L}(x;\Delta',\xi)
241 // \exp{-\frac{(\Delta-\Delta')^2}{2\sigma'^2}}
244 // where @f$ f'_{L}@f$ is the Landau distribution, @f$ \Delta@f$ the
245 // energy loss, @f$ \xi@f$ the width of the Landau, and
246 // @f$ \sigma'^2=\sigma^2-\sigma_n^2 @f$. Here, @f$\sigma@f$ is the
247 // variance of the Gaussian, and @f$\sigma_n@f$ is a parameter modelling
248 // noise in the detector.
250 // Note that this function uses the constants fgConvolutionSteps and
251 // fgConvolutionNSigma
254 // - <a href="http://dx.doi.org/10.1016/0168-583X(84)90472-5">Nucl.Instrum.Meth.B1:16</a>
255 // - <a href="http://dx.doi.org/10.1103/PhysRevA.28.615">Phys.Rev.A28:615</a>
256 // - <a href="http://root.cern.ch/root/htmldoc/tutorials/fit/langaus.C.html">ROOT implementation</a>
259 // x where to evaluate @f$ f@f$
260 // delta @f$ \Delta@f$ of @f$ f(x;\Delta,\xi,\sigma')@f$
261 // xi @f$ \xi@f$ of @f$ f(x;\Delta,\xi,\sigma')@f$
262 // sigma @f$ \sigma@f$ of @f$\sigma'^2=\sigma^2-\sigma_n^2 @f$
263 // sigma_n @f$ \sigma_n@f$ of @f$\sigma'^2=\sigma^2-\sigma_n^2 @f$
266 // @f$ f@f$ evaluated at @f$ x@f$.
268 Double_t deltap = delta - xi * mpshift;
269 Double_t sigma2 = sigma_n*sigma_n + sigma*sigma;
270 Double_t sigma1 = sigma_n == 0 ? sigma : TMath::Sqrt(sigma2);
271 Double_t xlow = x - fgConvolutionNSigma * sigma1;
272 Double_t xhigh = x + fgConvolutionNSigma * sigma1;
273 Double_t step = (xhigh - xlow) / fgConvolutionSteps;
276 for (Int_t i = 0; i <= fgConvolutionSteps/2; i++) {
277 Double_t x1 = xlow + (i - .5) * step;
278 Double_t x2 = xhigh - (i - .5) * step;
280 sum += TMath::Landau(x1, deltap, xi, kTRUE) * TMath::Gaus(x, x1, sigma1);
281 sum += TMath::Landau(x2, deltap, xi, kTRUE) * TMath::Gaus(x, x2, sigma1);
283 return step * sum * invSq2pi / sigma1;
286 //____________________________________________________________________
288 AliForwardUtil::ILandauGaus(Double_t x, Double_t delta, Double_t xi,
289 Double_t sigma, Double_t sigma_n, Int_t i)
294 // f_i(x;\Delta,\xi,\sigma') = f(x;\Delta_i,\xi_i,\sigma_i')
296 // corresponding to @f$ i@f$ particles i.e., with the substitutions
298 // \Delta \rightarrow \Delta_i &=& i(\Delta + \xi\log(i))
299 // \xi \rightarrow \xi_i &=& i \xi
300 // \sigma \rightarrow \sigma_i &=& \sqrt{i}\sigma
301 // \sigma'^2 \rightarrow \sigma_i'^2 &=& \sigma_n^2 + \sigma_i^2
305 // x Where to evaluate
306 // delta @f$ \Delta@f$
308 // sigma @f$ \sigma@f$
309 // sigma_n @f$ \sigma_n@f$
313 // @f$ f_i @f$ evaluated
315 Double_t delta_i = (i == 1 ? delta : i * (delta + xi * TMath::Log(i)));
316 Double_t xi_i = i * xi;
317 Double_t sigma_i = (i == 1 ? sigma : TMath::Sqrt(Double_t(i))*sigma);
318 if (sigma_i < 1e-10) {
319 // Fall back to landau
320 return AliForwardUtil::Landau(x, delta_i, xi_i);
322 return AliForwardUtil::LandauGaus(x, delta_i, xi_i, sigma_i, sigma_n);
325 //____________________________________________________________________
327 AliForwardUtil::IdLandauGausdPar(Double_t x,
328 UShort_t par, Double_t dPar,
329 Double_t delta, Double_t xi,
330 Double_t sigma, Double_t sigma_n,
334 // Numerically evaluate
336 // \left.\frac{\partial f_i}{\partial p_i}\right|_{x}
338 // where @f$ p_i@f$ is the @f$ i^{\mbox{th}}@f$ parameter. The mapping
339 // of the parameters is given by
344 // - 3: @f$\sigma_n@f$
346 // This is the partial derivative with respect to the parameter of
347 // the response function corresponding to @f$ i@f$ particles i.e.,
348 // with the substitutions
350 // \Delta \rightarrow \Delta_i = i(\Delta + \xi\log(i))
351 // \xi \rightarrow \xi_i = i \xi
352 // \sigma \rightarrow \sigma_i = \sqrt{i}\sigma
353 // \sigma'^2 \rightarrow \sigma_i'^2 = \sigma_n^2 + \sigma_i^2
357 // x Where to evaluate
358 // ipar Parameter number
359 // dp @f$ \epsilon\delta p_i@f$ for some value of @f$\epsilon@f$
360 // delta @f$ \Delta@f$
362 // sigma @f$ \sigma@f$
363 // sigma_n @f$ \sigma_n@f$
367 // @f$ f_i@f$ evaluated
369 if (dPar == 0) return 0;
371 Double_t d2 = dPar / 2;
372 Double_t delta_i = i * (delta + xi * TMath::Log(i));
373 Double_t xi_i = i * xi;
374 Double_t si = TMath::Sqrt(Double_t(i));
375 Double_t sigma_i = si*sigma;
382 y1 = ILandauGaus(x, delta_i+i*dp, xi_i, sigma_i, sigma_n, i);
383 y2 = ILandauGaus(x, delta_i+i*d2, xi_i, sigma_i, sigma_n, i);
384 y3 = ILandauGaus(x, delta_i-i*d2, xi_i, sigma_i, sigma_n, i);
385 y4 = ILandauGaus(x, delta_i-i*dp, xi_i, sigma_i, sigma_n, i);
388 y1 = ILandauGaus(x, delta_i, xi_i+i*dp, sigma_i, sigma_n, i);
389 y2 = ILandauGaus(x, delta_i, xi_i+i*d2, sigma_i, sigma_n, i);
390 y3 = ILandauGaus(x, delta_i, xi_i-i*d2, sigma_i, sigma_n, i);
391 y4 = ILandauGaus(x, delta_i, xi_i-i*dp, sigma_i, sigma_n, i);
394 y1 = ILandauGaus(x, delta_i, xi_i, sigma_i+si*dp, sigma_n, i);
395 y2 = ILandauGaus(x, delta_i, xi_i, sigma_i+si*d2, sigma_n, i);
396 y3 = ILandauGaus(x, delta_i, xi_i, sigma_i-si*d2, sigma_n, i);
397 y4 = ILandauGaus(x, delta_i, xi_i, sigma_i-si*dp, sigma_n, i);
400 y1 = ILandauGaus(x, delta_i, xi_i, sigma_i, sigma_n+dp, i);
401 y2 = ILandauGaus(x, delta_i, xi_i, sigma_i, sigma_n+d2, i);
402 y3 = ILandauGaus(x, delta_i, xi_i, sigma_i, sigma_n-d2, i);
403 y4 = ILandauGaus(x, delta_i, xi_i, sigma_i, sigma_n-dp, i);
409 Double_t d0 = y1 - y4;
410 Double_t d1 = 2 * (y2 - y3);
412 Double_t g = 1/(2*dp) * (4*d1 - d0) / 3;
417 //____________________________________________________________________
419 AliForwardUtil::NLandauGaus(Double_t x, Double_t delta, Double_t xi,
420 Double_t sigma, Double_t sigma_n, Int_t n,
426 // f_N(x;\Delta,\xi,\sigma') = \sum_{i=1}^N a_i f_i(x;\Delta,\xi,\sigma'a)
429 // where @f$ f(x;\Delta,\xi,\sigma')@f$ is the convolution of a
430 // Landau with a Gaussian (see LandauGaus). Note that
431 // @f$ a_1 = 1@f$, @f$\Delta_i = i(\Delta_1 + \xi\log(i))@f$,
432 // @f$\xi_i=i\xi_1@f$, and @f$\sigma_i'^2 = \sigma_n^2 + i\sigma_1^2@f$.
435 // - <a href="http://dx.doi.org/10.1016/0168-583X(84)90472-5">Nucl.Instrum.Meth.B1:16</a>
436 // - <a href="http://dx.doi.org/10.1103/PhysRevA.28.615">Phys.Rev.A28:615</a>
437 // - <a href="http://root.cern.ch/root/htmldoc/tutorials/fit/langaus.C.html">ROOT implementation</a>
440 // x Where to evaluate @f$ f_N@f$
441 // delta @f$ \Delta_1@f$
443 // sigma @f$ \sigma_1@f$
444 // sigma_n @f$ \sigma_n@f$
445 // n @f$ N@f$ in the sum above.
446 // a Array of size @f$ N-1@f$ of the weights @f$ a_i@f$ for
450 // @f$ f_N(x;\Delta,\xi,\sigma')@f$
452 Double_t result = ILandauGaus(x, delta, xi, sigma, sigma_n, 1);
453 for (Int_t i = 2; i <= n; i++)
454 result += a[i-2] * AliForwardUtil::ILandauGaus(x,delta,xi,sigma,sigma_n,i);
458 const Int_t kColors[] = { kRed+1,
472 //____________________________________________________________________
474 AliForwardUtil::MakeNLandauGaus(Double_t c,
475 Double_t delta, Double_t xi,
476 Double_t sigma, Double_t sigma_n, Int_t n,
478 Double_t xmin, Double_t xmax)
481 // Generate a TF1 object of @f$ f_N@f$
485 // delta @f$ \Delta@f$
487 // sigma @f$ \sigma_1@f$
488 // sigma_n @f$ \sigma_n@f$
489 // n @f$ N@f$ - how many particles to sum to
490 // a Array of size @f$ N-1@f$ of the weights @f$ a_i@f$ for
492 // xmin Least value of range
493 // xmax Largest value of range
496 // Newly allocated TF1 object
498 Int_t npar = AliForwardUtil::ELossFitter::kN+n;
499 TF1* landaun = new TF1(Form("nlandau%d", n), &landauGausN,xmin,xmax,npar);
500 // landaun->SetLineStyle(((n-2) % 10)+2); // start at dashed
501 landaun->SetLineColor(kColors[((n-1) % 12)]); // start at red
502 landaun->SetLineWidth(2);
503 landaun->SetNpx(500);
504 landaun->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}", "N");
506 // Set the initial parameters from the seed fit
507 landaun->SetParameter(AliForwardUtil::ELossFitter::kC, c);
508 landaun->SetParameter(AliForwardUtil::ELossFitter::kDelta, delta);
509 landaun->SetParameter(AliForwardUtil::ELossFitter::kXi, xi);
510 landaun->SetParameter(AliForwardUtil::ELossFitter::kSigma, sigma);
511 landaun->SetParameter(AliForwardUtil::ELossFitter::kSigmaN, sigma_n);
512 landaun->FixParameter(AliForwardUtil::ELossFitter::kN, n);
514 // Set the range and name of the scale parameters
515 for (UShort_t i = 2; i <= n; i++) {// Take parameters from last fit
516 landaun->SetParameter(AliForwardUtil::ELossFitter::kA+i-2, a[i-2]);
517 landaun->SetParName(AliForwardUtil::ELossFitter::kA+i-2, Form("a_{%d}", i));
521 //____________________________________________________________________
523 AliForwardUtil::MakeILandauGaus(Double_t c,
524 Double_t delta, Double_t xi,
525 Double_t sigma, Double_t sigma_n, Int_t i,
526 Double_t xmin, Double_t xmax)
529 // Generate a TF1 object of @f$ f_I@f$
533 // delta @f$ \Delta@f$
535 // sigma @f$ \sigma_1@f$
536 // sigma_n @f$ \sigma_n@f$
537 // i @f$ i@f$ - the number of particles
538 // xmin Least value of range
539 // xmax Largest value of range
542 // Newly allocated TF1 object
544 Int_t npar = AliForwardUtil::ELossFitter::kN+1;
545 TF1* landaui = new TF1(Form("ilandau%d", i), &landauGausI,xmin,xmax,npar);
546 // landaui->SetLineStyle(((i-2) % 10)+2); // start at dashed
547 landaui->SetLineColor(kColors[((i-1) % 12)]); // start at red
548 landaui->SetLineWidth(1);
549 landaui->SetNpx(500);
550 landaui->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}", "i");
552 // Set the initial parameters from the seed fit
553 landaui->SetParameter(AliForwardUtil::ELossFitter::kC, c);
554 landaui->SetParameter(AliForwardUtil::ELossFitter::kDelta, delta);
555 landaui->SetParameter(AliForwardUtil::ELossFitter::kXi, xi);
556 landaui->SetParameter(AliForwardUtil::ELossFitter::kSigma, sigma);
557 landaui->SetParameter(AliForwardUtil::ELossFitter::kSigmaN, sigma_n);
558 landaui->FixParameter(AliForwardUtil::ELossFitter::kN, i);
563 //====================================================================
564 AliForwardUtil::ELossFitter::ELossFitter(Double_t lowCut,
567 : fLowCut(lowCut), fMaxRange(maxRange), fMinusBins(minusBins),
568 fFitResults(0), fFunctions(0)
574 // lowCut Lower cut of spectrum - data below this cuts is ignored
575 // maxRange Maximum range to fit to
576 // minusBins The number of bins below maximum to use
578 fFitResults.SetOwner();
579 fFunctions.SetOwner();
581 //____________________________________________________________________
582 AliForwardUtil::ELossFitter::~ELossFitter()
588 fFitResults.Delete();
591 //____________________________________________________________________
593 AliForwardUtil::ELossFitter::Clear()
596 // Clear internal arrays
602 //____________________________________________________________________
604 AliForwardUtil::ELossFitter::Fit1Particle(TH1* dist, Double_t sigman)
607 // Fit a 1-particle signal to the passed energy loss distribution
609 // Note that this function clears the internal arrays first
612 // dist Data to fit the function to
613 // sigman If larger than zero, the initial guess of the
614 // detector induced noise. If zero or less, then this
615 // parameter is ignored in the fit (fixed at 0)
618 // The function fitted to the data
624 // Find the fit range
625 dist->GetXaxis()->SetRangeUser(fLowCut, fMaxRange);
627 // Get the bin with maximum
628 Int_t maxBin = dist->GetMaximumBin();
629 Double_t maxE = dist->GetBinLowEdge(maxBin);
632 dist->GetXaxis()->SetRangeUser(fLowCut, maxE);
633 Int_t minBin = maxBin - fMinusBins; // dist->GetMinimumBin();
634 Double_t minE = TMath::Max(dist->GetBinCenter(minBin),fLowCut);
635 Double_t maxEE = dist->GetBinCenter(maxBin+2*fMinusBins);
638 dist->GetXaxis()->SetRangeUser(0, fMaxRange);
640 // Define the function to fit
641 TF1* landau1 = new TF1("landau1", landauGaus1, minE,maxEE,kSigmaN+1);
643 // Set initial guesses, parameter names, and limits
644 landau1->SetParameters(1,0.5,0.07,0.1,sigman);
645 landau1->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}");
646 landau1->SetNpx(500);
647 landau1->SetParLimits(kDelta, minE, fMaxRange);
648 landau1->SetParLimits(kXi, 0.00, fMaxRange);
649 landau1->SetParLimits(kSigma, 0.01, 0.1);
650 if (sigman <= 0) landau1->FixParameter(kSigmaN, 0);
651 else landau1->SetParLimits(kSigmaN, 0, fMaxRange);
653 // Do the fit, getting the result object
654 TFitResultPtr r = dist->Fit(landau1, "RNQS", "", minE, maxEE);
655 landau1->SetRange(minE, fMaxRange);
656 fFitResults.AddAtAndExpand(new TFitResult(*r), 0);
657 fFunctions.AddAtAndExpand(landau1, 0);
661 //____________________________________________________________________
663 AliForwardUtil::ELossFitter::FitNParticle(TH1* dist, UShort_t n,
667 // Fit a N-particle signal to the passed energy loss distribution
669 // If there's no 1-particle fit present, it does that first
672 // dist Data to fit the function to
673 // n Number of particle signals to fit
674 // sigman If larger than zero, the initial guess of the
675 // detector induced noise. If zero or less, then this
676 // parameter is ignored in the fit (fixed at 0)
679 // The function fitted to the data
682 // Get the seed fit result
683 TFitResult* r = static_cast<TFitResult*>(fFitResults.At(0));
684 TF1* f = static_cast<TF1*>(fFunctions.At(0));
686 f = Fit1Particle(dist, sigman);
687 r = static_cast<TFitResult*>(fFitResults.At(0));
689 ::Warning("FitNLandau", "No first shot at landau fit");
694 // Get some parameters from seed fit
695 Double_t delta1 = r->Parameter(kDelta);
696 Double_t xi1 = r->Parameter(kXi);
697 Double_t maxEi = n * (delta1 + xi1 * TMath::Log(n)) + 2 * n * xi1;
698 Double_t minE = f->GetXmin();
702 for (UShort_t i = 2; i <= n; i++)
703 a.fArray[i-2] = (n == 2 ? 0.05 : 0.000001);
704 // Make the fit function
705 TF1* landaun = MakeNLandauGaus(r->Parameter(kC),
706 r->Parameter(kDelta),
708 r->Parameter(kSigma),
709 r->Parameter(kSigmaN),
710 n,a.fArray,minE,maxEi);
711 landaun->SetParLimits(kDelta, minE, fMaxRange); // Delta
712 landaun->SetParLimits(kXi, 0.00, fMaxRange); // xi
713 landaun->SetParLimits(kSigma, 0.01, 1); // sigma
714 // Check if we're using the noise sigma
715 if (sigman <= 0) landaun->FixParameter(kSigmaN, 0);
716 else landaun->SetParLimits(kSigmaN, 0, fMaxRange);
718 // Set the range and name of the scale parameters
719 for (UShort_t i = 2; i <= n; i++) {// Take parameters from last fit
720 landaun->SetParLimits(kA+i-2, 0,1);
724 TFitResultPtr tr = dist->Fit(landaun, "RSQN", "", minE, maxEi);
726 landaun->SetRange(minE, fMaxRange);
727 fFitResults.AddAtAndExpand(new TFitResult(*tr), n-1);
728 fFunctions.AddAtAndExpand(landaun, n-1);
733 //====================================================================
734 AliForwardUtil::Histos::~Histos()
739 if (fFMD1i) delete fFMD1i;
740 if (fFMD2i) delete fFMD2i;
741 if (fFMD2o) delete fFMD2o;
742 if (fFMD3i) delete fFMD3i;
743 if (fFMD3o) delete fFMD3o;
746 //____________________________________________________________________
748 AliForwardUtil::Histos::Make(UShort_t d, Char_t r,
749 const TAxis& etaAxis) const
757 // etaAxis Eta axis to use
760 // Newly allocated histogram
762 Int_t ns = (r == 'I' || r == 'i') ? 20 : 40;
763 TH2D* hist = new TH2D(Form("FMD%d%c_cache", d, r),
764 Form("FMD%d%c cache", d, r),
765 etaAxis.GetNbins(), etaAxis.GetXmin(),
766 etaAxis.GetXmax(), ns, 0, 2*TMath::Pi());
767 hist->SetXTitle("#eta");
768 hist->SetYTitle("#phi [radians]");
769 hist->SetZTitle("d^{2}N_{ch}/d#etad#phi");
771 hist->SetDirectory(0);
775 //____________________________________________________________________
777 AliForwardUtil::Histos::Init(const TAxis& etaAxis)
780 // Initialize the object
783 // etaAxis Eta axis to use
785 fFMD1i = Make(1, 'I', etaAxis);
786 fFMD2i = Make(2, 'I', etaAxis);
787 fFMD2o = Make(2, 'O', etaAxis);
788 fFMD3i = Make(3, 'I', etaAxis);
789 fFMD3o = Make(3, 'O', etaAxis);
791 //____________________________________________________________________
793 AliForwardUtil::Histos::Clear(Option_t* option)
801 fFMD1i->Reset(option);
802 fFMD2i->Reset(option);
803 fFMD2o->Reset(option);
804 fFMD3i->Reset(option);
805 fFMD3o->Reset(option);
808 //____________________________________________________________________
810 AliForwardUtil::Histos::Get(UShort_t d, Char_t r) const
813 // Get the histogram for a particular detector,ring
820 // Histogram for detector,ring or nul
823 case 1: return fFMD1i;
824 case 2: return (r == 'I' || r == 'i' ? fFMD2i : fFMD2o);
825 case 3: return (r == 'I' || r == 'i' ? fFMD3i : fFMD3o);
829 //====================================================================
831 AliForwardUtil::RingHistos::DefineOutputList(TList* d) const
834 // Define the outout list in @a d
837 // d Where to put the output list
840 // Newly allocated TList object or null
843 TList* list = new TList;
844 list->SetName(fName.Data());
848 //____________________________________________________________________
850 AliForwardUtil::RingHistos::GetOutputList(TList* d) const
853 // Get our output list from the container @a d
856 // d where to get the output list from
859 // The found TList or null
862 TList* list = static_cast<TList*>(d->FindObject(fName.Data()));
866 //____________________________________________________________________
868 AliForwardUtil::RingHistos::GetOutputHist(TList* d, const char* name) const
871 // Find a specific histogram in the source list @a d
875 // name Name of histogram
878 // Found histogram or null
880 return static_cast<TH1*>(d->FindObject(name));