1 #include "AliForwardUtil.h"
2 #include <AliAnalysisManager.h>
3 #include "AliAODForwardMult.h"
5 #include <AliInputEventHandler.h>
6 #include <AliESDEvent.h>
7 #include <AliPhysicsSelection.h>
8 #include <AliTriggerAnalysis.h>
9 #include <AliMultiplicity.h>
13 #include <TFitResult.h>
17 //====================================================================
18 Int_t AliForwardUtil::fgConvolutionSteps = 100;
19 Double_t AliForwardUtil::fgConvolutionNSigma = 5;
22 * The shift of the most probable value for the ROOT function TMath::Landau
24 const Double_t mpshift = -0.22278298;
26 * Integration normalisation
28 const Double_t invSq2pi = 1. / TMath::Sqrt(2*TMath::Pi());
31 * Utility function to use in TF1 defintition
33 Double_t landauGaus1(Double_t* xp, Double_t* pp)
36 Double_t constant = pp[0];
37 Double_t delta = pp[1];
39 Double_t sigma = pp[3];
40 Double_t sigma_n = pp[4];
42 return constant * AliForwardUtil::LandauGaus(x, delta, xi, sigma, sigma_n);
46 * Utility function to use in TF1 defintition
48 Double_t landauGausN(Double_t* xp, Double_t* pp)
51 Double_t constant = pp[0];
52 Double_t delta = pp[1];
54 Double_t sigma = pp[3];
55 Double_t sigma_n = pp[4];
56 Int_t n = Int_t(pp[5]);
57 Double_t* a = &(pp[6]);
59 return constant * AliForwardUtil::NLandauGaus(x, delta, xi, sigma, sigma_n,
65 //____________________________________________________________________
67 AliForwardUtil::Landau(Double_t x, Double_t delta, Double_t xi)
69 return TMath::Landau(x, delta - xi * mpshift, xi);
71 //____________________________________________________________________
73 AliForwardUtil::LandauGaus(Double_t x, Double_t delta, Double_t xi,
74 Double_t sigma, Double_t sigma_n)
76 Double_t deltap = delta - xi * mpshift;
77 Double_t sigma2 = sigma_n*sigma_n + sigma*sigma;
78 Double_t sigma1 = TMath::Sqrt(sigma2);
79 Double_t xlow = x - fgConvolutionNSigma * sigma1;
80 Double_t xhigh = x - fgConvolutionNSigma * sigma1;
81 Double_t step = (xhigh - xlow) / fgConvolutionSteps;
84 for (Int_t i = 0; i <= fgConvolutionSteps/2; i++) {
85 Double_t x1 = xlow + (i - .5) * step;
86 Double_t x2 = xlow - (i - .5) * step;
88 sum += TMath::Landau(x1, deltap, xi, kTRUE) * TMath::Gaus(x, x1, sigma1);
89 sum += TMath::Landau(x2, deltap, xi, kTRUE) * TMath::Gaus(x, x2, sigma1);
91 return step * sum * invSq2pi / sigma1;
94 //____________________________________________________________________
96 AliForwardUtil::NLandauGaus(Double_t x, Double_t delta, Double_t xi,
97 Double_t sigma, Double_t sigma_n, Int_t n,
100 Double_t result = LandauGaus(x, delta, xi, sigma, sigma_n);
101 for (Int_t i = 2; i <= n; i++) {
102 Double_t delta_i = i * (delta + xi * TMath::Log(i));
103 Double_t xi_i = i * xi;
104 Double_t sigma_i = TMath::Sqrt(Double_t(n)*sigma);
106 result += a_i * AliForwardUtil::LandauGaus(x, delta_i, xi_i,
112 //====================================================================
113 AliForwardUtil::ELossFitter::ELossFitter(Double_t lowCut,
116 : fLowCut(lowCut), fMaxRange(maxRange), fMinusBins(minusBins),
117 fFitResults(0), fFunctions(0)
119 fFitResults.SetOwner();
120 fFunctions.SetOwner();
122 //____________________________________________________________________
123 AliForwardUtil::ELossFitter::~ELossFitter()
125 fFitResults.Delete();
128 //____________________________________________________________________
130 AliForwardUtil::ELossFitter::Clear()
135 //____________________________________________________________________
137 AliForwardUtil::ELossFitter::Fit1Particle(TH1* dist, Double_t sigman)
142 // Find the fit range
143 dist->GetXaxis()->SetRangeUser(fLowCut, fMaxRange);
145 // Normalize peak to 1
146 Double_t max = dist->GetMaximum();
149 // Get the bin with maximum
150 Int_t maxBin = dist->GetMaximumBin();
151 Double_t maxE = dist->GetBinLowEdge(maxBin);
154 dist->GetXaxis()->SetRangeUser(fLowCut, maxE);
155 Int_t minBin = maxBin - fMinusBins; // dist->GetMinimumBin();
156 Double_t minE = TMath::Max(dist->GetBinCenter(minBin),fLowCut);
157 Double_t maxEE = dist->GetBinCenter(maxBin+2*fMinusBins);
160 dist->GetXaxis()->SetRangeUser(0, fMaxRange);
162 // Define the function to fit
163 TF1* landau1 = new TF1("landau1", landauGaus1, minE, maxEE, 5);
165 // Set initial guesses, parameter names, and limits
166 landau1->SetParameters(5,.5,.07,1,sigman);
167 landau1->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}");
168 landau1->SetParLimits(1, minE, fMaxRange);
169 landau1->SetParLimits(2, 0.00, fMaxRange);
170 landau1->SetParLimits(3, 0.01, fMaxRange);
171 if (sigman <= 0) landau1->FixParameter(4, 0);
172 else landau1->SetParLimits(4, 0, fMaxRange);
174 // Do the fit, getting the result object
175 TFitResultPtr r = dist->Fit(landau1, "RNQS", "", minE, maxEE);
177 fFitResults.AddAtAndExpand(new TFitResult(*r), 0);
178 fFunctions.AddAtAndExpand(landau1, 0);
182 //____________________________________________________________________
184 AliForwardUtil::ELossFitter::FitNParticle(TH1* dist, UShort_t n,
187 // Get the seed fit result
188 TFitResult* r = static_cast<TFitResult*>(fFitResults.At(0));
189 TF1* f = static_cast<TF1*>(fFunctions.At(0));
191 f = Fit1Particle(dist, sigman);
192 r = static_cast<TFitResult*>(fFitResults.At(0));
194 ::Warning("FitNLandau", "No first shot at landau fit");
199 // Get some parameters from seed fit
200 Double_t delta1 = r->Parameter(1);
201 Double_t xi1 = r->Parameter(2);
202 Double_t maxEi = n * (delta1 + xi1 * TMath::Log(n)) + 2 * n * xi1;
203 Double_t minE = f->GetXmin();
205 // Make the fit function
206 TF1* landaun = new TF1(Form("landau%d", n), &landauGausN,minE,maxEi,5+n);
207 landaun->SetLineStyle((n % 10)+1);
208 landaun->SetLineWidth(2);
209 landaun->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}", "N");
211 // Set the initial parameters from the seed fit
212 landaun->SetParameter(0, r->Parameter(0)); // Constant
213 landaun->SetParameter(1, r->Parameter(1)); // Delta
214 landaun->SetParameter(2, r->Parameter(2)); // xi
215 landaun->SetParameter(3, r->Parameter(3)); // sigma
216 landaun->SetParameter(4, r->Parameter(4)); // sigma_n
217 landaun->SetParLimits(1, minE, fMaxRange); // Delta
218 landaun->SetParLimits(2, 0.00, fMaxRange); // xi
219 landaun->SetParLimits(3, 0.01, fMaxRange); // sigma
220 landaun->SetParLimits(4, 0.00, fMaxRange); // sigma_n
221 // Fix the number parameter
222 landaun->FixParameter(5, n); // N
224 // Set the range and name of the scale parameters
225 for (UShort_t i = 2; i <= n; i++) {// Take parameters from last fit
226 landaun->SetParameter(5+i-2, n == 2 ? 0.05 : 0);
227 landaun->SetParLimits(5+i-2, 0,1);
228 landaun->SetParName(5+i-2, Form("a_{%d}", i));
232 TFitResultPtr tr = dist->Fit(landaun, "RSQN", "", minE, maxEi);
234 fFitResults.AddAtAndExpand(new TFitResult(*tr), n-1);
235 fFunctions.AddAtAndExpand(landaun, n-1);
240 //====================================================================
241 AliForwardUtil::Histos::~Histos()
243 if (fFMD1i) delete fFMD1i;
244 if (fFMD2i) delete fFMD2i;
245 if (fFMD2o) delete fFMD2o;
246 if (fFMD3i) delete fFMD3i;
247 if (fFMD3o) delete fFMD3o;
250 //____________________________________________________________________
252 AliForwardUtil::Histos::Make(UShort_t d, Char_t r,
253 const TAxis& etaAxis) const
255 Int_t ns = (r == 'I' || r == 'i') ? 20 : 40;
256 TH2D* hist = new TH2D(Form("FMD%d%c_cache", d, r),
257 Form("FMD%d%c cache", d, r),
258 etaAxis.GetNbins(), etaAxis.GetXmin(),
259 etaAxis.GetXmax(), ns, 0, 2*TMath::Pi());
260 hist->SetXTitle("#eta");
261 hist->SetYTitle("#phi [radians]");
262 hist->SetZTitle("d^{2}N_{ch}/d#etad#phi");
264 hist->SetDirectory(0);
268 //____________________________________________________________________
270 AliForwardUtil::Histos::Init(const TAxis& etaAxis)
272 fFMD1i = Make(1, 'I', etaAxis);
273 fFMD2i = Make(2, 'I', etaAxis);
274 fFMD2o = Make(2, 'O', etaAxis);
275 fFMD3i = Make(3, 'I', etaAxis);
276 fFMD3o = Make(3, 'O', etaAxis);
278 //____________________________________________________________________
280 AliForwardUtil::Histos::Clear(Option_t* option)
282 fFMD1i->Reset(option);
283 fFMD2i->Reset(option);
284 fFMD2o->Reset(option);
285 fFMD3i->Reset(option);
286 fFMD3o->Reset(option);
289 //____________________________________________________________________
291 AliForwardUtil::Histos::Get(UShort_t d, Char_t r) const
294 case 1: return fFMD1i;
295 case 2: return (r == 'I' || r == 'i' ? fFMD2i : fFMD2o);
296 case 3: return (r == 'I' || r == 'i' ? fFMD3i : fFMD3o);
300 //====================================================================
302 AliForwardUtil::RingHistos::DefineOutputList(TList* d) const
305 TList* list = new TList;
306 list->SetName(fName.Data());
310 //____________________________________________________________________
312 AliForwardUtil::RingHistos::GetOutputList(TList* d) const
315 TList* list = static_cast<TList*>(d->FindObject(fName.Data()));
319 //____________________________________________________________________
321 AliForwardUtil::RingHistos::GetOutputHist(TList* d, const char* name) const
323 return static_cast<TH1*>(d->FindObject(name));