]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG2/FORWARD/analysis2/AliForwardUtil.cxx
More code clean up.
[u/mrichter/AliRoot.git] / PWG2 / FORWARD / analysis2 / AliForwardUtil.cxx
index 1dae159df5a8cc326e3a030c0b9c27cbb4a50930..a4867c086244a40603715e31384a243a65f67e75 100644 (file)
 #include <TMath.h>
 #include <TError.h>
 
+//====================================================================
+UShort_t
+AliForwardUtil::ParseCollisionSystem(const char* sys)
+{
+  TString s(sys);
+  s.ToLower();
+  if (s.Contains("p-p")   || s.Contains("pp"))   return AliForwardUtil::kPP; 
+  if (s.Contains("pb-pb") || s.Contains("pbpb")) return AliForwardUtil::kPbPb;
+  if (s.Contains("a-a")   || s.Contains("aa"))   return AliForwardUtil::kPbPb;
+  return AliForwardUtil::kUnknown;
+}
+//____________________________________________________________________
+const char*
+AliForwardUtil::CollisionSystemString(UShort_t sys)
+{
+  switch (sys) { 
+  case AliForwardUtil::kPP:   return "pp";
+  case AliForwardUtil::kPbPb: return "PbPb";
+  }
+  return "unknown";
+}
+//____________________________________________________________________
+UShort_t
+AliForwardUtil::ParseCenterOfMassEnergy(UShort_t sys, Float_t v)
+{
+  Float_t energy = v; 
+  if (sys != AliForwardUtil::kPP) energy = energy / 208 * 82;
+  if (TMath::Abs(energy - 900.)   < 10)  return 900;
+  if (TMath::Abs(energy - 2400.)  < 10)  return 2400;
+  if (TMath::Abs(energy - 2750.)  < 10)  return 2750;
+  if (TMath::Abs(energy - 5500.)  < 40)  return 5500;
+  if (TMath::Abs(energy - 7000.)  < 10)  return 7000;
+  if (TMath::Abs(energy - 10000.) < 10)  return 10000;
+  if (TMath::Abs(energy - 14000.) < 10)  return 14000;
+  return 0;
+}
+//____________________________________________________________________
+const char* 
+AliForwardUtil::CenterOfMassEnergyString(UShort_t cms)
+{
+  return Form("%04dGeV", cms);
+}
+//____________________________________________________________________
+Short_t
+AliForwardUtil::ParseMagneticField(Float_t v)
+{
+  if (TMath::Abs(v - 5.) < 1 ) return +5;
+  if (TMath::Abs(v + 5.) < 1 ) return -5;
+  if (TMath::Abs(v) < 1)       return 0;
+  return 999;
+}
+//____________________________________________________________________
+const char* 
+AliForwardUtil::MagneticFieldString(Short_t f)
+{
+  return Form("%01dkG", f);
+}
+
+
 //====================================================================
 Int_t    AliForwardUtil::fgConvolutionSteps  = 100;
 Double_t AliForwardUtil::fgConvolutionNSigma = 5;
@@ -33,11 +92,11 @@ namespace {
   Double_t landauGaus1(Double_t* xp, Double_t* pp) 
   {
     Double_t x        = xp[0];
-    Double_t constant = pp[0];
-    Double_t delta    = pp[1];
-    Double_t xi       = pp[2];
-    Double_t sigma    = pp[3];
-    Double_t sigma_n  = pp[4];
+    Double_t constant = pp[AliForwardUtil::ELossFitter::kC];
+    Double_t delta    = pp[AliForwardUtil::ELossFitter::kDelta];
+    Double_t xi       = pp[AliForwardUtil::ELossFitter::kXi];
+    Double_t sigma    = pp[AliForwardUtil::ELossFitter::kSigma];
+    Double_t sigma_n  = pp[AliForwardUtil::ELossFitter::kSigmaN];
 
     return constant * AliForwardUtil::LandauGaus(x, delta, xi, sigma, sigma_n);
   }
@@ -48,17 +107,32 @@ namespace {
   Double_t landauGausN(Double_t* xp, Double_t* pp) 
   {
     Double_t  x        = xp[0];
-    Double_t  constant = pp[0];
-    Double_t  delta    = pp[1];
-    Double_t  xi       = pp[2];
-    Double_t  sigma    = pp[3];
-    Double_t  sigma_n  = pp[4];
-    Int_t     n        = Int_t(pp[5]);
-    Double_t* a        = &(pp[6]);
+    Double_t constant  = pp[AliForwardUtil::ELossFitter::kC];
+    Double_t delta     = pp[AliForwardUtil::ELossFitter::kDelta];
+    Double_t xi        = pp[AliForwardUtil::ELossFitter::kXi];
+    Double_t sigma     = pp[AliForwardUtil::ELossFitter::kSigma];
+    Double_t sigma_n   = pp[AliForwardUtil::ELossFitter::kSigmaN];
+    Int_t     n        = Int_t(pp[AliForwardUtil::ELossFitter::kN]);
+    Double_t* a        = &(pp[AliForwardUtil::ELossFitter::kA]);
 
     return constant * AliForwardUtil::NLandauGaus(x, delta, xi, sigma, sigma_n,
                                                  n, a);
   }
+  /** 
+   * Utility function to use in TF1 defintition 
+   */
+  Double_t landauGausI(Double_t* xp, Double_t* pp) 
+  {
+    Double_t x         = xp[0];
+    Double_t constant  = pp[AliForwardUtil::ELossFitter::kC];
+    Double_t delta     = pp[AliForwardUtil::ELossFitter::kDelta];
+    Double_t xi        = pp[AliForwardUtil::ELossFitter::kXi];
+    Double_t sigma     = pp[AliForwardUtil::ELossFitter::kSigma];
+    Double_t sigma_n   = pp[AliForwardUtil::ELossFitter::kSigmaN];
+    Int_t    i         = Int_t(pp[AliForwardUtil::ELossFitter::kN]);
+
+    return constant * AliForwardUtil::ILandauGaus(x,delta,xi,sigma,sigma_n,i);
+  }
 
 
 }
@@ -75,15 +149,15 @@ AliForwardUtil::LandauGaus(Double_t x, Double_t delta, Double_t xi,
 {
   Double_t deltap = delta - xi * mpshift;
   Double_t sigma2 = sigma_n*sigma_n + sigma*sigma;
-  Double_t sigma1 = TMath::Sqrt(sigma2);
+  Double_t sigma1 = sigma_n == 0 ? sigma : TMath::Sqrt(sigma2);
   Double_t xlow   = x - fgConvolutionNSigma * sigma1;
-  Double_t xhigh  = x - fgConvolutionNSigma * sigma1;
+  Double_t xhigh  = x + fgConvolutionNSigma * sigma1;
   Double_t step   = (xhigh - xlow) / fgConvolutionSteps;
   Double_t sum    = 0;
   
   for (Int_t i = 0; i <= fgConvolutionSteps/2; i++) { 
-    Double_t x1 = xlow + (i - .5) * step;
-    Double_t x2 = xlow - (i - .5) * step;
+    Double_t x1 = xlow  + (i - .5) * step;
+    Double_t x2 = xhigh - (i - .5) * step;
     
     sum += TMath::Landau(x1, deltap, xi, kTRUE) * TMath::Gaus(x, x1, sigma1);
     sum += TMath::Landau(x2, deltap, xi, kTRUE) * TMath::Gaus(x, x2, sigma1);
@@ -91,23 +165,159 @@ AliForwardUtil::LandauGaus(Double_t x, Double_t delta, Double_t xi,
   return step * sum * invSq2pi / sigma1;
 }
 
+//____________________________________________________________________
+Double_t 
+AliForwardUtil::ILandauGaus(Double_t x, Double_t delta, Double_t xi, 
+                           Double_t sigma, Double_t sigma_n, Int_t i)
+{
+  Double_t delta_i =  (i == 1 ? delta : i * (delta + xi * TMath::Log(i)));
+  Double_t xi_i    =  i * xi;
+  Double_t sigma_i =  (i == 1 ? sigma : TMath::Sqrt(Double_t(i))*sigma);
+  if (sigma_i < 1e-10) { 
+    // Fall back to landau 
+    return AliForwardUtil::Landau(x, delta_i, xi_i);
+  }
+  return AliForwardUtil::LandauGaus(x, delta_i, xi_i, sigma_i, sigma_n);
+}
+
+//____________________________________________________________________
+Double_t 
+AliForwardUtil::IdLandauGausdPar(Double_t x, 
+                                UShort_t par,   Double_t dPar, 
+                                Double_t delta, Double_t xi, 
+                                Double_t sigma, Double_t sigma_n, 
+                                Int_t    i)
+{
+  if (dPar == 0) return 0;
+  Double_t dp      = dPar;
+  Double_t d2      = dPar / 2;
+  Double_t delta_i =  i * (delta + xi * TMath::Log(i));
+  Double_t xi_i    =  i * xi;
+  Double_t si      =  TMath::Sqrt(Double_t(i));
+  Double_t sigma_i =  si*sigma;
+  Double_t y1      = 0;
+  Double_t y2      = 0;
+  Double_t y3      = 0;
+  Double_t y4      = 0;
+  switch (par) {
+  case 0: 
+    y1 = ILandauGaus(x, delta_i+i*dp, xi_i, sigma_i, sigma_n, i);
+    y2 = ILandauGaus(x, delta_i+i*d2, xi_i, sigma_i, sigma_n, i);
+    y3 = ILandauGaus(x, delta_i-i*d2, xi_i, sigma_i, sigma_n, i);
+    y4 = ILandauGaus(x, delta_i-i*dp, xi_i, sigma_i, sigma_n, i);
+    break;
+  case 1: 
+    y1 = ILandauGaus(x, delta_i, xi_i+i*dp, sigma_i, sigma_n, i);
+    y2 = ILandauGaus(x, delta_i, xi_i+i*d2, sigma_i, sigma_n, i);
+    y3 = ILandauGaus(x, delta_i, xi_i-i*d2, sigma_i, sigma_n, i);
+    y4 = ILandauGaus(x, delta_i, xi_i-i*dp, sigma_i, sigma_n, i);
+    break;
+  case 2: 
+    y1 = ILandauGaus(x, delta_i, xi_i, sigma_i+si*dp, sigma_n, i);
+    y2 = ILandauGaus(x, delta_i, xi_i, sigma_i+si*d2, sigma_n, i);
+    y3 = ILandauGaus(x, delta_i, xi_i, sigma_i-si*d2, sigma_n, i);
+    y4 = ILandauGaus(x, delta_i, xi_i, sigma_i-si*dp, sigma_n, i);
+    break;
+  case 3: 
+    y1 = ILandauGaus(x, delta_i, xi_i, sigma_i, sigma_n+dp, i);
+    y2 = ILandauGaus(x, delta_i, xi_i, sigma_i, sigma_n+d2, i);
+    y3 = ILandauGaus(x, delta_i, xi_i, sigma_i, sigma_n-d2, i);
+    y4 = ILandauGaus(x, delta_i, xi_i, sigma_i, sigma_n-dp, i);
+    break;
+  default:
+    return 0;
+  } 
+  
+  Double_t d0  = y1 - y4;
+  Double_t d1  = 2 * (y2 - y3);
+  
+  Double_t g   = 1/(2*dp) * (4*d1 - d0) / 3;
+   
+  return g;
+}
+
 //____________________________________________________________________
 Double_t 
 AliForwardUtil::NLandauGaus(Double_t x, Double_t delta, Double_t xi, 
                            Double_t sigma, Double_t sigma_n, Int_t n, 
                            Double_t* a)
 {
-  Double_t result = LandauGaus(x, delta, xi, sigma, sigma_n);
-  for (Int_t i = 2; i <= n; i++) { 
-    Double_t delta_i =  i * (delta + xi * TMath::Log(i));
-    Double_t xi_i    =  i * xi;
-    Double_t sigma_i =  TMath::Sqrt(Double_t(n)*sigma);
-    Double_t a_i     =  a[i];
-    result           += a_i * AliForwardUtil::LandauGaus(x, delta_i, xi_i, 
-                                                        sigma_i, sigma_n);
-  }
+  Double_t result = ILandauGaus(x, delta, xi, sigma, sigma_n, 1);
+  for (Int_t i = 2; i <= n; i++) 
+    result += a[i-2] * AliForwardUtil::ILandauGaus(x,delta,xi,sigma,sigma_n,i);
   return result;
 }
+namespace { 
+  const Int_t kColors[] = { kRed+1, 
+                           kPink+3, 
+                           kMagenta+2, 
+                           kViolet+2, 
+                           kBlue+1, 
+                           kAzure+3, 
+                           kCyan+1, 
+                           kTeal+2, 
+                           kGreen+2, 
+                           kSpring+3, 
+                           kYellow+2, 
+                           kOrange+2 };
+}
+
+//____________________________________________________________________
+TF1*
+AliForwardUtil::MakeNLandauGaus(Double_t  c, 
+                               Double_t  delta, Double_t xi, 
+                               Double_t  sigma, Double_t sigma_n, Int_t n, 
+                               Double_t* a, 
+                               Double_t  xmin, Double_t xmax)
+{
+  Int_t npar       = AliForwardUtil::ELossFitter::kN+n;
+  TF1* landaun     = new TF1(Form("nlandau%d", n), &landauGausN,xmin,xmax,npar);
+  // landaun->SetLineStyle(((n-2) % 10)+2); // start at dashed
+  landaun->SetLineColor(kColors[((n-1) % 12)]); // start at red
+  landaun->SetLineWidth(2);
+  landaun->SetNpx(500);
+  landaun->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}", "N");
+
+  // Set the initial parameters from the seed fit 
+  landaun->SetParameter(AliForwardUtil::ELossFitter::kC,      c);       
+  landaun->SetParameter(AliForwardUtil::ELossFitter::kDelta,  delta);   
+  landaun->SetParameter(AliForwardUtil::ELossFitter::kXi,     xi);      
+  landaun->SetParameter(AliForwardUtil::ELossFitter::kSigma,  sigma);   
+  landaun->SetParameter(AliForwardUtil::ELossFitter::kSigmaN, sigma_n); 
+  landaun->FixParameter(AliForwardUtil::ELossFitter::kN,      n);       
+
+  // Set the range and name of the scale parameters 
+  for (UShort_t i = 2; i <= n; i++) {// Take parameters from last fit 
+    landaun->SetParameter(AliForwardUtil::ELossFitter::kA+i-2, a[i-2]);
+    landaun->SetParName(AliForwardUtil::ELossFitter::kA+i-2, Form("a_{%d}", i));
+  }
+  return landaun;
+}
+//____________________________________________________________________
+TF1*
+AliForwardUtil::MakeILandauGaus(Double_t  c, 
+                               Double_t  delta, Double_t xi, 
+                               Double_t  sigma, Double_t sigma_n, Int_t i, 
+                               Double_t  xmin, Double_t xmax)
+{
+  Int_t npar       = AliForwardUtil::ELossFitter::kN+1;
+  TF1* landaui     = new TF1(Form("ilandau%d", i), &landauGausI,xmin,xmax,npar);
+  // landaui->SetLineStyle(((i-2) % 10)+2); // start at dashed
+  landaui->SetLineColor(kColors[((i-1) % 12)]); // start at red
+  landaui->SetLineWidth(1);
+  landaui->SetNpx(500);
+  landaui->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}", "i");
+
+  // Set the initial parameters from the seed fit 
+  landaui->SetParameter(AliForwardUtil::ELossFitter::kC,      c);       
+  landaui->SetParameter(AliForwardUtil::ELossFitter::kDelta,  delta);   
+  landaui->SetParameter(AliForwardUtil::ELossFitter::kXi,     xi);      
+  landaui->SetParameter(AliForwardUtil::ELossFitter::kSigma,  sigma);   
+  landaui->SetParameter(AliForwardUtil::ELossFitter::kSigmaN, sigma_n); 
+  landaui->FixParameter(AliForwardUtil::ELossFitter::kN,      i);       
+
+  return landaui;
+}
 
 //====================================================================
 AliForwardUtil::ELossFitter::ELossFitter(Double_t lowCut, 
@@ -142,10 +352,6 @@ AliForwardUtil::ELossFitter::Fit1Particle(TH1* dist, Double_t sigman)
   // Find the fit range 
   dist->GetXaxis()->SetRangeUser(fLowCut, fMaxRange);
   
-  // Normalize peak to 1 
-  Double_t max = dist->GetMaximum(); 
-  dist->Scale(1/max);
-  
   // Get the bin with maximum 
   Int_t    maxBin = dist->GetMaximumBin();
   Double_t maxE   = dist->GetBinLowEdge(maxBin);
@@ -160,20 +366,21 @@ AliForwardUtil::ELossFitter::Fit1Particle(TH1* dist, Double_t sigman)
   dist->GetXaxis()->SetRangeUser(0, fMaxRange);
   
   // Define the function to fit 
-  TF1*          landau1 = new TF1("landau1", landauGaus1, minE, maxEE, 5);
+  TF1* landau1 = new TF1("landau1", landauGaus1, minE,maxEE,kSigmaN+1);
 
   // Set initial guesses, parameter names, and limits  
-  landau1->SetParameters(5,.5,.07,1,sigman);
+  landau1->SetParameters(1,0.5,0.07,0.1,sigman);
   landau1->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}");
-  landau1->SetParLimits(1, minE, fMaxRange);
-  landau1->SetParLimits(2, 0.00, fMaxRange);
-  landau1->SetParLimits(3, 0.01, fMaxRange);
-  if (sigman <= 0)  landau1->FixParameter(4, 0);
-  else              landau1->SetParLimits(4, 0, fMaxRange);
+  landau1->SetNpx(500);
+  landau1->SetParLimits(kDelta, minE, fMaxRange);
+  landau1->SetParLimits(kXi,    0.00, fMaxRange);
+  landau1->SetParLimits(kSigma, 0.01, 0.1);
+  if (sigman <= 0)  landau1->FixParameter(kSigmaN, 0);
+  else              landau1->SetParLimits(kSigmaN, 0, fMaxRange);
 
   // Do the fit, getting the result object 
   TFitResultPtr r = dist->Fit(landau1, "RNQS", "", minE, maxEE);
-
+  landau1->SetRange(minE, fMaxRange);
   fFitResults.AddAtAndExpand(new TFitResult(*r), 0);
   fFunctions.AddAtAndExpand(landau1, 0);
 
@@ -197,40 +404,38 @@ AliForwardUtil::ELossFitter::FitNParticle(TH1* dist, UShort_t n,
   }
 
   // Get some parameters from seed fit 
-  Double_t delta1  = r->Parameter(1);
-  Double_t xi1     = r->Parameter(2);
+  Double_t delta1  = r->Parameter(kDelta);
+  Double_t xi1     = r->Parameter(kXi);
   Double_t maxEi   = n * (delta1 + xi1 * TMath::Log(n)) + 2 * n * xi1;
   Double_t minE    = f->GetXmin();
 
+  // Array of weights 
+  TArrayD a(n-1);
+  for (UShort_t i = 2; i <= n; i++) 
+    a.fArray[i-2] = (n == 2 ? 0.05 : 0.000001);
   // Make the fit function 
-  TF1* landaun     = new TF1(Form("landau%d", n), &landauGausN,minE,maxEi,5+n);
-  landaun->SetLineStyle((n % 10)+1);
-  landaun->SetLineWidth(2);
-  landaun->SetParNames("C","#Delta_{p}","#xi", "#sigma", "#sigma_{n}", "N");
-
-  // Set the initial parameters from the seed fit 
-  landaun->SetParameter(0, r->Parameter(0)); // Constant
-  landaun->SetParameter(1, r->Parameter(1)); // Delta 
-  landaun->SetParameter(2, r->Parameter(2)); // xi
-  landaun->SetParameter(3, r->Parameter(3)); // sigma
-  landaun->SetParameter(4, r->Parameter(4)); // sigma_n
-  landaun->SetParLimits(1, minE, fMaxRange); // Delta
-  landaun->SetParLimits(2, 0.00, fMaxRange); // xi
-  landaun->SetParLimits(3, 0.01, fMaxRange); // sigma
-  landaun->SetParLimits(4, 0.00, fMaxRange); // sigma_n
-  // Fix the number parameter 
-  landaun->FixParameter(5, n);               // N
+  TF1* landaun     = MakeNLandauGaus(r->Parameter(kC),
+                                    r->Parameter(kDelta),
+                                    r->Parameter(kXi),
+                                    r->Parameter(kSigma),
+                                    r->Parameter(kSigmaN),
+                                    n,a.fArray,minE,maxEi);
+  landaun->SetParLimits(kDelta,  minE, fMaxRange);       // Delta
+  landaun->SetParLimits(kXi,     0.00, fMaxRange);       // xi
+  landaun->SetParLimits(kSigma,  0.01, 1);            // sigma
+  // Check if we're using the noise sigma 
+  if (sigman <= 0)  landaun->FixParameter(kSigmaN, 0);
+  else              landaun->SetParLimits(kSigmaN, 0, fMaxRange);
 
   // Set the range and name of the scale parameters 
   for (UShort_t i = 2; i <= n; i++) {// Take parameters from last fit 
-    landaun->SetParameter(5+i-2, n == 2 ? 0.05 : 0);
-    landaun->SetParLimits(5+i-2, 0,1);
-    landaun->SetParName(5+i-2, Form("a_{%d}", i));
+    landaun->SetParLimits(kA+i-2, 0,1);
   }
 
   // Do the fit 
   TFitResultPtr tr = dist->Fit(landaun, "RSQN", "", minE, maxEi);
   
+  landaun->SetRange(minE, fMaxRange);
   fFitResults.AddAtAndExpand(new TFitResult(*tr), n-1);
   fFunctions.AddAtAndExpand(landaun, n-1);