From 728661538134afa86ba54426a57b09daeb74ee6a Mon Sep 17 00:00:00 2001
From: Viktor Klochkov <v.klochkov@gsi.de>
Date: Fri, 19 Jul 2019 11:16:57 +0200
Subject: [PATCH] fix alignment & add openmp

---
 CMakeLists.txt         |   2 +-
 glauber/Fitter.cpp     | 538 ++++++++++++++++++++---------------------
 glauber/Fitter.h       | 174 ++++++-------
 glauber/FitterHelper.h | 146 +++++------
 glauber/main.cpp       | 119 ++++-----
 5 files changed, 494 insertions(+), 485 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 359f4c8..04f3815 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,8 +21,8 @@ if (CMAKE_BUILD_TYPE MATCHES DEBUG)
 endif ()
 
 set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb -DDEBUG -D__DEBUG -Wall")
+set(CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native -ftree-vectorize -ffast-math -DNODEBUG -fopenmp")
 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -ggdb")
-set(CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native -ftree-vectorize -ffast-math -DNODEBUG")
 message(STATUS "Using CXX flags for ${CMAKE_BUILD_TYPE}: ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}")
 
 set(SOURCES
diff --git a/glauber/Fitter.cpp b/glauber/Fitter.cpp
index f8c54e9..91e86e2 100644
--- a/glauber/Fitter.cpp
+++ b/glauber/Fitter.cpp
@@ -13,78 +13,78 @@ ClassImp(Glauber::Fitter)
 // -----   Default constructor   -------------------------------------------
 Glauber::Fitter::Fitter(std::unique_ptr<TTree> tree) 
 {
-    fSimTree = std::move(tree);    
-    std::cout << fSimTree->GetEntries() << std::endl;
-    
-    if (!fSimTree) {
-        std::cout << "SetSimHistos: *** Error - " << std::endl;
-        exit(EXIT_FAILURE);
-    }
-    
-    fSimTree->SetBranchAddress("Npart", &fNpart);
-    fSimTree->SetBranchAddress("Ncoll", &fNcoll);
+  fSimTree = std::move(tree);    
+  std::cout << fSimTree->GetEntries() << std::endl;
+  
+  if (!fSimTree) {
+    std::cout << "SetSimHistos: *** Error - " << std::endl;
+    exit(EXIT_FAILURE);
+  }
+  
+  fSimTree->SetBranchAddress("Npart", &fNpart);
+  fSimTree->SetBranchAddress("Ncoll", &fNcoll);
 }
 
 void Glauber::Fitter::Init(int nEntries)
 {
-    if ( nEntries < 0 || nEntries > fSimTree->GetEntries() ){
-        std::cout << "Init: *** ERROR - number of entries < 0 or less that number of entries in input tree" << std::endl;
-        std::cout << "Init: *** number of entries in input tree = " << fSimTree->GetEntries() << std::endl;        
-        exit(EXIT_FAILURE);
-    }
-    
-    const int NpartMax = int (fSimTree->GetMaximum("Npart") );
-    const int NcollMax = int (fSimTree->GetMaximum("Ncoll") );
-    
-    fNpartHisto = TH1F ("fNpartHisto", "Npart", NpartMax/fBinSize, 0, NpartMax );
-    fNcollHisto = TH1F ("fNcollHisto", "Ncoll", NcollMax/fBinSize, 0, NcollMax );
-    
-    for (int i=0; i<nEntries; i++)
-    {
-        fSimTree->GetEntry(i);
-        fNcollHisto.Fill(fNcoll);
-        fNpartHisto.Fill(fNpart);
-    }
-    std::cout << fSimTree->GetEntries() << std::endl;
-    
-    fNbins = fDataHisto.GetNbinsX();
-
-    while ( fDataHisto.GetBinContent(fNbins-1) == 0)
-        fNbins--;
-    
-    fNbins++;
-    
-    const float min = fDataHisto.GetXaxis()->GetXmin();
-    const float max = fDataHisto.GetXaxis()->GetXmax();
-    
-    fMaxValue = min + (max - min)*fNbins/fDataHisto.GetNbinsX() ;
-    
-    std::cout << "fNbins = " << fNbins << std::endl;
-    std::cout << "fMaxValue = " << fMaxValue << std::endl;
-    
+  if ( nEntries < 0 || nEntries > fSimTree->GetEntries() ){
+    std::cout << "Init: *** ERROR - number of entries < 0 or less that number of entries in input tree" << std::endl;
+    std::cout << "Init: *** number of entries in input tree = " << fSimTree->GetEntries() << std::endl;        
+    exit(EXIT_FAILURE);
+  }
+  
+  const int NpartMax = int (fSimTree->GetMaximum("Npart") );
+  const int NcollMax = int (fSimTree->GetMaximum("Ncoll") );
+  
+  fNpartHisto = TH1F ("fNpartHisto", "Npart", NpartMax/fBinSize, 0, NpartMax );
+  fNcollHisto = TH1F ("fNcollHisto", "Ncoll", NcollMax/fBinSize, 0, NcollMax );
+  
+  for (int i=0; i<nEntries; i++)
+  {
+    fSimTree->GetEntry(i);
+    fNcollHisto.Fill(fNcoll);
+    fNpartHisto.Fill(fNpart);
+  }
+  std::cout << fSimTree->GetEntries() << std::endl;
+  
+  fNbins = fDataHisto.GetNbinsX();
+  
+  while ( fDataHisto.GetBinContent(fNbins-1) == 0)
+    fNbins--;
+  
+  fNbins++;
+  
+  const float min = fDataHisto.GetXaxis()->GetXmin();
+  const float max = fDataHisto.GetXaxis()->GetXmax();
+  
+  fMaxValue = min + (max - min)*fNbins/fDataHisto.GetNbinsX() ;
+  
+  std::cout << "fNbins = " << fNbins << std::endl;
+  std::cout << "fMaxValue = " << fMaxValue << std::endl;
+  
 }
 
 float Glauber::Fitter::Nancestors(float f) const
 {
-    if       (fMode == "Default")    return f*fNpart + (1-f)*fNcoll;
-    else if  (fMode == "PSD")        return f - fNpart;
-    else if  (fMode == "Npart")      return TMath::Power(fNpart, f); 
-    else if  (fMode == "Ncoll")      return TMath::Power(fNcoll, f);
-    
-    return -1.;
+  if       (fMode == "Default")    return f*fNpart + (1-f)*fNcoll;
+  else if  (fMode == "PSD")        return f - fNpart;
+  else if  (fMode == "Npart")      return TMath::Power(fNpart, f); 
+  else if  (fMode == "Ncoll")      return TMath::Power(fNcoll, f);
+  
+  return -1.;
 }
 
 float Glauber::Fitter::NancestorsMax(float f) const
 {
-    const int NpartMax = fNpartHisto.GetXaxis()->GetXmax() ;  // some magic
-    const int NcollMax = fNcollHisto.GetXaxis()->GetXmax() ; //TODO 
-    
-    if       (fMode == "Default")    return f*NpartMax + (1-f)*NcollMax;
-    else if  (fMode == "PSD")        return NpartMax;
-    else if  (fMode == "Npart")      return TMath::Power(NpartMax, f); 
-    else if  (fMode == "Ncoll")      return TMath::Power(NcollMax, f);
-    
-    return -1.;
+  const int NpartMax = fNpartHisto.GetXaxis()->GetXmax() ;  // some magic
+  const int NcollMax = fNcollHisto.GetXaxis()->GetXmax() ; //TODO 
+  
+  if       (fMode == "Default")    return f*NpartMax + (1-f)*NcollMax;
+  else if  (fMode == "PSD")        return NpartMax;
+  else if  (fMode == "Npart")      return TMath::Power(NpartMax, f); 
+  else if  (fMode == "Ncoll")      return TMath::Power(NcollMax, f);
+  
+  return -1.;
 }
 
 /*
@@ -93,52 +93,52 @@ float Glauber::Fitter::NancestorsMax(float f) const
  */
 void Glauber::Fitter::SetGlauberFitHisto (float f, float mu, float k, int n, Bool_t Norm2Data)
 {    
-    fGlauberFitHisto = TH1F("glaub", "", fNbins*1.3, 0, 1.3*fMaxValue);
-    fGlauberFitHisto.SetName(Form("glaub_%4.2f_%6.4f_%4.2f_%d", f, mu, k, n ));
-    
-    SetNBDhist(mu,  k);
-
-    std::unique_ptr<TH1F> htemp {(TH1F*)fNbdHisto.Clone("htemp")}; // WTF??? Not working without pointer
-    for (int i=0; i<n; i++)
-    {
-        fSimTree->GetEntry(i);
-        const int Na = int(Nancestors(f));
-                
-        float nHits {0.};
-        for (int j=0; j<Na; j++){
-            nHits += int(htemp->GetRandom());
-        }
-        fGlauberFitHisto.Fill(nHits);
+  fGlauberFitHisto = TH1F("glaub", "", fNbins*1.3, 0, 1.3*fMaxValue);
+  fGlauberFitHisto.SetName(Form("glaub_%4.2f_%6.4f_%4.2f_%d", f, mu, k, n ));
+  
+  SetNBDhist(mu,  k);
+  
+  std::unique_ptr<TH1F> htemp {(TH1F*)fNbdHisto.Clone("htemp")}; // WTF??? Not working without pointer
+  for (int i=0; i<n; i++)
+  {
+    fSimTree->GetEntry(i);
+    const int Na = int(Nancestors(f));
+    
+    float nHits {0.};
+    for (int j=0; j<Na; j++){
+      nHits += int(htemp->GetRandom());
     }
-    
-    if (Norm2Data)
-        NormalizeGlauberFit();
+    fGlauberFitHisto.Fill(nHits);
+  }
+  
+  if (Norm2Data)
+    NormalizeGlauberFit();
 }
 
 
 void Glauber::Fitter::NormalizeGlauberFit ()
 {
-    
-    int fGlauberFitHistoInt {0}; 
-    int fDataHistoInt {0};
-    
-    const int lowchibin = fFitMinBin;
-    const int highchibin = fFitMaxBin<fNbins ? fFitMaxBin : fNbins;
-    
-    for (int i=lowchibin; i<highchibin; i++)
-    {
-        fGlauberFitHistoInt += fGlauberFitHisto.GetBinContent(i+1);
-        fDataHistoInt += fDataHisto.GetBinContent(i+1);
-    }
-
-    const float ScaleFactor = (float)fDataHistoInt/fGlauberFitHistoInt;
-    
-//     std::cout << "Scale = " << Scale << std::endl;
-    fGlauberFitHisto.Scale(ScaleFactor);    
+  
+  int fGlauberFitHistoInt {0}; 
+  int fDataHistoInt {0};
+  
+  const int lowchibin = fFitMinBin;
+  const int highchibin = fFitMaxBin<fNbins ? fFitMaxBin : fNbins;
+  
+  for (int i=lowchibin; i<highchibin; i++)
+  {
+    fGlauberFitHistoInt += fGlauberFitHisto.GetBinContent(i+1);
+    fDataHistoInt += fDataHisto.GetBinContent(i+1);
+  }
+  
+  const float ScaleFactor = (float)fDataHistoInt/fGlauberFitHistoInt;
+  
+  //     std::cout << "Scale = " << Scale << std::endl;
+  fGlauberFitHisto.Scale(ScaleFactor);    
 }
 
 /**
- *
+ * 
  * @param mu mean value of negative binominal distribution (we are looking for it)
  * @param chi2 return value (indicates good match)
  * @param mu_min lower search edge for mean value NBD
@@ -150,48 +150,48 @@ void Glauber::Fitter::NormalizeGlauberFit ()
  */
 void Glauber::Fitter::FindMuGoldenSection (float *mu, float *chi2, float mu_min, float mu_max, float f, float k, int nEvents, int nIter)
 {
-    const float phi {(1+TMath::Sqrt(5))/2};
-
-    /* left */
-    float mu_1 = mu_max - (mu_max-mu_min)/phi;
-
-    /* right */
-    float mu_2 = mu_min + (mu_max-mu_min)/phi;
-    
-    SetGlauberFitHisto (f, mu_1, k, nEvents);
-    float chi2_mu1 = GetChi2 ();
-    
-    SetGlauberFitHisto (f, mu_2, k, nEvents);
-    float chi2_mu2 = GetChi2 ();
-    
-    for (int j=0; j<nIter; j++)
-    {        
-        if (chi2_mu1 > chi2_mu2)
-        {
-            mu_min = mu_1;
-            mu_1 = mu_2;
-            mu_2 = mu_min + (mu_max-mu_min)/phi;
-            chi2_mu1 = chi2_mu2;
-            SetGlauberFitHisto (f, mu_2, k, nEvents);
-            chi2_mu2 = GetChi2 ();
-        }
-        else
-        {
-            mu_max = mu_2;
-            mu_2 = mu_1;
-            mu_1 = mu_max - (mu_max-mu_min)/phi; 
-            chi2_mu2 = chi2_mu1;
-            SetGlauberFitHisto (f, mu_1, k, nEvents);
-            chi2_mu1 = GetChi2 ();            
-        }
-        
-        std::cout << "mu1 = " << mu_1 << " mu2 = " << mu_2 << " chi2_mu1 = " << chi2_mu1  << " chi2_mu2 = " << chi2_mu2 << std::endl;
+  const float phi {(1+TMath::Sqrt(5))/2};
+  
+  /* left */
+  float mu_1 = mu_max - (mu_max-mu_min)/phi;
+  
+  /* right */
+  float mu_2 = mu_min + (mu_max-mu_min)/phi;
+  
+  SetGlauberFitHisto (f, mu_1, k, nEvents);
+  float chi2_mu1 = GetChi2 ();
+  
+  SetGlauberFitHisto (f, mu_2, k, nEvents);
+  float chi2_mu2 = GetChi2 ();
+  
+  for (int j=0; j<nIter; j++)
+  {        
+    if (chi2_mu1 > chi2_mu2)
+    {
+      mu_min = mu_1;
+      mu_1 = mu_2;
+      mu_2 = mu_min + (mu_max-mu_min)/phi;
+      chi2_mu1 = chi2_mu2;
+      SetGlauberFitHisto (f, mu_2, k, nEvents);
+      chi2_mu2 = GetChi2 ();
     }
-
-    /* take min(mu) */
-    *mu = (chi2_mu1 < chi2_mu2) ? mu_1 : mu_2;
-    /* take min(chi2) */
-    *chi2 = (chi2_mu1 < chi2_mu2) ? chi2_mu1 : chi2_mu2;
+    else
+    {
+      mu_max = mu_2;
+      mu_2 = mu_1;
+      mu_1 = mu_max - (mu_max-mu_min)/phi; 
+      chi2_mu2 = chi2_mu1;
+      SetGlauberFitHisto (f, mu_1, k, nEvents);
+      chi2_mu1 = GetChi2 ();            
+    }
+    
+    std::cout << "mu1 = " << mu_1 << " mu2 = " << mu_2 << " chi2_mu1 = " << chi2_mu1  << " chi2_mu2 = " << chi2_mu2 << std::endl;
+  }
+  
+  /* take min(mu) */
+  *mu = (chi2_mu1 < chi2_mu2) ? mu_1 : mu_2;
+  /* take min(chi2) */
+  *chi2 = (chi2_mu1 < chi2_mu2) ? chi2_mu1 : chi2_mu2;
 }
 
 /**
@@ -205,63 +205,63 @@ void Glauber::Fitter::FindMuGoldenSection (float *mu, float *chi2, float mu_min,
  */
 float Glauber::Fitter::FitGlauber (float *par, Float_t f0, Int_t k0, Int_t k1, Int_t nEvents)
 {
-    float f_fit{-1};
-    float mu_fit{-1}; 
-    float k_fit{-1};
-    float Chi2Min {1e10};
-
-    const TString filename = Form ( "%s/fit_%4.2f_%d_%d_%d.root", fOutDirName.Data(), f0, k0, k1, fFitMinBin );
+  float f_fit{-1};
+  float mu_fit{-1}; 
+  float k_fit{-1};
+  float Chi2Min {1e10};
+  
+  const TString filename = Form ( "%s/fit_%4.2f_%d_%d_%d.root", fOutDirName.Data(), f0, k0, k1, fFitMinBin );
+  
+  //     std::unique_ptr<TFile> file {TFile::Open(filename, "recreate")};    
+  //     std::unique_ptr<TTree> tree {new TTree("test_tree", "tree" )};
+  
+  TFile* file {TFile::Open(filename, "recreate")};    
+  TTree* tree {new TTree("test_tree", "tree" )};
+  
+  TH1F h1("h1", "", fNbins, 0, fMaxValue);
+  
+  float f, mu, k, chi2, sigma;
+  
+  tree->Branch("histo", "TH1F", &h1);
+  tree->Branch("f",    &f,    "f/F");   
+  tree->Branch("mu",   &mu,   "mu/F");   
+  tree->Branch("k",    &k,    "k/F");   
+  tree->Branch("chi2", &chi2, "chi2/F");   
+  tree->Branch("sigma",&sigma,"sigma/F");   
+  
+  f = f0;
+  for (int j=k0; j<=k1; j++)
+  {
+    mu = fMaxValue / NancestorsMax(f) ;
+    k = j;
+    const float mu_min = 0.7*mu;
+    const float mu_max = 1.0*mu;
     
-//     std::unique_ptr<TFile> file {TFile::Open(filename, "recreate")};    
-//     std::unique_ptr<TTree> tree {new TTree("test_tree", "tree" )};
-
-    TFile* file {TFile::Open(filename, "recreate")};    
-    TTree* tree {new TTree("test_tree", "tree" )};
+    FindMuGoldenSection (&mu, &chi2, mu_min, mu_max, f, k, nEvents, 10);
+    sigma = ( mu/k + 1 ) * mu;
+    h1 = fGlauberFitHisto;
     
-    TH1F h1("h1", "", fNbins, 0, fMaxValue);
-           
-    float f, mu, k, chi2, sigma;
-
-    tree->Branch("histo", "TH1F", &h1);
-    tree->Branch("f",    &f,    "f/F");   
-    tree->Branch("mu",   &mu,   "mu/F");   
-    tree->Branch("k",    &k,    "k/F");   
-    tree->Branch("chi2", &chi2, "chi2/F");   
-    tree->Branch("sigma",&sigma,"sigma/F");   
-
-    f = f0;
-    for (int j=k0; j<=k1; j++)
-    {
-        mu = fMaxValue / NancestorsMax(f) ;
-        k = j;
-        const float mu_min = 0.7*mu;
-        const float mu_max = 1.0*mu;
-
-        FindMuGoldenSection (&mu, &chi2, mu_min, mu_max, f, k, nEvents, 10);
-        sigma = ( mu/k + 1 ) * mu;
-        h1 = fGlauberFitHisto;
-        
-        tree->Fill();
-        
-        if (chi2 < Chi2Min)
-        {
-            f_fit = f;
-            mu_fit = mu;
-            k_fit = k;
-            Chi2Min = chi2;
-            fBestFitHisto = fGlauberFitHisto;
-        }            
-
-    } 
-    tree->Write();
-    file->Write();
-    file->Close();
-
-    par[0] = f_fit;
-    par[1] = mu_fit;
-    par[2] = k_fit;
+    tree->Fill();
     
-    return Chi2Min;
+    if (chi2 < Chi2Min)
+    {
+      f_fit = f;
+      mu_fit = mu;
+      k_fit = k;
+      Chi2Min = chi2;
+      fBestFitHisto = fGlauberFitHisto;
+    }            
+    
+  } 
+  tree->Write();
+  file->Write();
+  file->Close();
+  
+  par[0] = f_fit;
+  par[1] = mu_fit;
+  par[2] = k_fit;
+  
+  return Chi2Min;
 }
 
 /**
@@ -270,22 +270,22 @@ float Glauber::Fitter::FitGlauber (float *par, Float_t f0, Int_t k0, Int_t k1, I
  */
 float Glauber::Fitter::GetChi2 () const 
 {
-    float chi2 {0.0};
-    
-    const int lowchibin = fFitMinBin;
-    const int highchibin = fFitMaxBin<fNbins ? fFitMaxBin : fNbins;
-    
-    for (int i=lowchibin; i<=highchibin; ++i) 
-    {
-        if (fDataHisto.GetBinContent(i) < 1.0) continue;
-        const float error2 = TMath::Power(fDataHisto.GetBinError(i), 2) + TMath::Power(fGlauberFitHisto.GetBinError(i), 2);
-        const float diff2 = TMath::Power((fGlauberFitHisto.GetBinContent(i) - fDataHisto.GetBinContent(i)), 2) / error2;
-
-        chi2 += diff2;
-    }
-    
-    chi2 = chi2 / (highchibin - lowchibin + 1);
-    return chi2;
+  float chi2 {0.0};
+  
+  const int lowchibin = fFitMinBin;
+  const int highchibin = fFitMaxBin<fNbins ? fFitMaxBin : fNbins;
+  
+  for (int i=lowchibin; i<=highchibin; ++i) 
+  {
+    if (fDataHisto.GetBinContent(i) < 1.0) continue;
+    const float error2 = TMath::Power(fDataHisto.GetBinError(i), 2) + TMath::Power(fGlauberFitHisto.GetBinError(i), 2);
+    const float diff2 = TMath::Power((fGlauberFitHisto.GetBinContent(i) - fDataHisto.GetBinContent(i)), 2) / error2;
+    
+    chi2 += diff2;
+  }
+  
+  chi2 = chi2 / (highchibin - lowchibin + 1);
+  return chi2;
 }
 
 /**
@@ -295,18 +295,18 @@ float Glauber::Fitter::GetChi2 () const
  */
 void Glauber::Fitter::SetNBDhist(float mu, float k)
 {
-    // Interface for TH1F.
-    const int nBins = (mu+1.)*3 < 10 ? 10 : (mu+1.)*3;
-    
-    fNbdHisto = TH1F ("fNbdHisto", "", nBins, 0, nBins);
-    fNbdHisto.SetName(Form("nbd_%f_%f",mu,k));
-    
-    for (int i=0; i<nBins; ++i) 
-    {
-        const float val = NBD(i, mu, k);
-        if (val>1e-10) fNbdHisto.SetBinContent(i+1, val);
-//         std::cout << "val " << val << std::endl;    
-    }
+  // Interface for TH1F.
+  const int nBins = (mu+1.)*3 < 10 ? 10 : (mu+1.)*3;
+  
+  fNbdHisto = TH1F ("fNbdHisto", "", nBins, 0, nBins);
+  fNbdHisto.SetName(Form("nbd_%f_%f",mu,k));
+  
+  for (int i=0; i<nBins; ++i) 
+  {
+    const float val = NBD(i, mu, k);
+    if (val>1e-10) fNbdHisto.SetBinContent(i+1, val);
+    //         std::cout << "val " << val << std::endl;    
+  }
 }
 
 /**
@@ -318,27 +318,27 @@ void Glauber::Fitter::SetNBDhist(float mu, float k)
  */
 float Glauber::Fitter::NBD(float n, float mu, float k) const
 {
-    // Compute NBD.
-    float F;
-    float f;
-
-    if (n+k > 100.0) 
-    {
-        // log method for handling large numbers
-        F  = TMath::LnGamma(n + k)- TMath::LnGamma(n + 1.)- TMath::LnGamma(k);
-        f  = n * TMath::Log(mu/k) - (n + k) * TMath::Log(1.0 + mu/k);
-        F += f;
-        F = TMath::Exp(F);
-    } 
-    else 
-    {
-        F  = TMath::Gamma(n + k) / ( TMath::Gamma(n + 1.) * TMath::Gamma(k) );
-        f  = n * TMath::Log(mu/k) - (n + k) * TMath::Log(1.0 + mu/k);
-        f  = TMath::Exp(f);
-        F *= f;
-    }
-
-    return F;
+  // Compute NBD.
+  float F;
+  float f;
+  
+  if (n+k > 100.0) 
+  {
+    // log method for handling large numbers
+    F  = TMath::LnGamma(n + k)- TMath::LnGamma(n + 1.)- TMath::LnGamma(k);
+    f  = n * TMath::Log(mu/k) - (n + k) * TMath::Log(1.0 + mu/k);
+    F += f;
+    F = TMath::Exp(F);
+  } 
+  else 
+  {
+    F  = TMath::Gamma(n + k) / ( TMath::Gamma(n + 1.) * TMath::Gamma(k) );
+    f  = n * TMath::Log(mu/k) - (n + k) * TMath::Log(1.0 + mu/k);
+    f  = TMath::Exp(f);
+    F *= f;
+  }
+  
+  return F;
 }
 /**
  * Creates histo with a given model parameter distribution
@@ -350,37 +350,37 @@ float Glauber::Fitter::NBD(float n, float mu, float k) const
  */
 std::unique_ptr<TH1F> Glauber::Fitter::GetModelHisto (const float range[2], TString name, const float par[3], int nEvents)
 {    
-    const float f =  par[0];
-    const float mu = par[1];
-    const float k = par[2];
-    
-    float modelpar{-999.};
-    fSimTree->SetBranchAddress(name, &modelpar);
-        
-    SetNBDhist(mu, k);
+  const float f =  par[0];
+  const float mu = par[1];
+  const float k = par[2];
   
-//     TRandom random;  
-//     random.SetSeed(mu*k);
-
-    std::unique_ptr<TH1F> hModel(new TH1F ("hModel", "name", 100, fSimTree->GetMinimum(name),  fSimTree->GetMaximum(name)) );
-
-    for (int i=0; i<nEvents; i++)
-    {
-        fSimTree->GetEntry(i);
-        const int Na = int(Nancestors(f));
-        float nHits{0.};
-        for (int j=0; j<Na; ++j){
-            nHits += (int)fNbdHisto.GetRandom();
-        }
-        
-        if ( nHits > range[0] && nHits < range[1] ){
-            hModel->Fill(modelpar);
-        }
-            
+  float modelpar{-999.};
+  fSimTree->SetBranchAddress(name, &modelpar);
+  
+  SetNBDhist(mu, k);
+  
+  //     TRandom random;  
+  //     random.SetSeed(mu*k);
+  
+  std::unique_ptr<TH1F> hModel(new TH1F ("hModel", "name", 100, fSimTree->GetMinimum(name),  fSimTree->GetMaximum(name)) );
+  
+  #pragma omp parallel for
+  for (int i=0; i<nEvents; i++)
+  {
+    fSimTree->GetEntry(i);
+    const int Na = int(Nancestors(f));
+    float nHits{0.};
+    for (int j=0; j<Na; ++j){
+      nHits += (int)fNbdHisto.GetRandom();
     }
     
-    return std::move(hModel);
-    
+    if ( nHits > range[0] && nHits < range[1] ){
+      hModel->Fill(modelpar);
+    }
+  }
+  
+  return std::move(hModel);
+  
 }
 
 
diff --git a/glauber/Fitter.h b/glauber/Fitter.h
index 8c73ccb..b0a96ed 100644
--- a/glauber/Fitter.h
+++ b/glauber/Fitter.h
@@ -1,9 +1,9 @@
 /** @file   Fitter.h
-    @class  Glauber::Fitter
-    @author Viktor Klochkov (klochkov44@gmail.com)
-    @author Ilya Selyuzhenkov (ilya.selyuzhenkov@gmail.com)
-    @brief  Class to fit histo with Glauber based function
-*/
+ *    @class  Glauber::Fitter
+ *    @author Viktor Klochkov (klochkov44@gmail.com)
+ *    @author Ilya Selyuzhenkov (ilya.selyuzhenkov@gmail.com)
+ *    @brief  Class to fit histo with Glauber based function
+ */
 
 #ifndef GlauberFitter_H
 #define GlauberFitter_H 1
@@ -18,88 +18,88 @@
 
 namespace Glauber
 {
-    class Fitter
-    {
-        
-    public:
-        
-        /**   Default constructor   **/
-        Fitter() {};
-        Fitter(std::unique_ptr<TTree> tree) ;
-        /**   Destructor   **/
-        virtual ~Fitter(){};
-        
-        void Init(int nEntries);
-        void SetGlauberFitHisto (Float_t f, Float_t mu, Float_t k, Int_t n = 10000, Bool_t Norm2Data = true);
-        void NormalizeGlauberFit ();
-        void DrawHistos (Bool_t isSim = true, Bool_t isData = true, Bool_t isGlauber = false, Bool_t isNBD = false);
-        
-        float FitGlauber (float *par, Float_t f0, Int_t k0, Int_t k1, Int_t nEvents);
-        void FindMuGoldenSection (Float_t *mu, Float_t *chi2, Float_t mu_min, Float_t mu_max, Float_t f, Float_t k, Int_t nEvents = 10000, Int_t nIter = 5);
-        
-        Float_t GetChi2 (void) const;
-        
-        Float_t NBD(Float_t n, Float_t mu, Float_t k) const;
-        void SetNBDhist(Float_t mu, Float_t k);
-        float Nancestors(float f) const;
-        float NancestorsMax(float f) const;
-        
-        std::unique_ptr<TH1F> GetModelHisto (const Float_t range[2], TString name, const Float_t par[3], Int_t nEvents);
-        
-//         
-//         Setters
-//         
-        void SetInputHisto (const TH1F &h)   { fDataHisto = h; }
-        void SetFitMinBin  (Int_t min)      { fFitMinBin = min; }
-        void SetFitMaxBin  (Int_t min)      { fFitMaxBin = min; }
-        void SetNormMinBin  (Int_t min)     { fNormMinBin = min; }
-        void SetBinSize  (Int_t size)        { fBinSize = size; }
-        void SetOutDirName (TString name)    { fOutDirName = name; }
-        void SetMode (const TString mode) { fMode = mode; }
- 
-//         
-//         Getters
-//         
-        TH1F GetGlauberFitHisto () const { return fGlauberFitHisto; }
-        TH1F GetDataHisto ()       const { return fDataHisto;  }
-        TH1F GetNBDHisto ()        const { return fNbdHisto;   }
-        TH1F GetNpartHisto ()      const { return fNpartHisto; }
-        TH1F GetNcollHisto ()      const { return fNcollHisto;  }
-        TH1F GetBestFiHisto ()     const { return fBestFitHisto;  }
-
-        
-    private:
-        
-        /**   Data members  **/
-        TH1F fNpartHisto; 
-        TH1F fNcollHisto; 
-        TH1F fDataHisto; 
-        TH1F fNbdHisto; 
-        TH1F fGlauberFitHisto; 
-        TH1F fBestFitHisto;
-        
-        /* MC data */
-        std::unique_ptr<TTree> fSimTree{nullptr};
-        
-        Float_t fNpart{-1.};
-        Float_t fNcoll{-1.};
-
-        Float_t fMaxValue{-1.};
-        
-        Int_t fNbins{-1};
-        Int_t fBinSize{-1};
-        
-        Int_t fFitMinBin{-1};
-        Int_t fFitMaxBin{-1};
-
-        Int_t fNormMinBin{-1};
-        
-        TString fMode{"Default"};
-        
-        TString fOutDirName{""};
-        ClassDef(Fitter, 2);
-        
-    };
+  class Fitter
+  {
+    
+  public:
+    
+    /**   Default constructor   **/
+    Fitter() {};
+    Fitter(std::unique_ptr<TTree> tree) ;
+    /**   Destructor   **/
+    virtual ~Fitter(){};
+    
+    void Init(int nEntries);
+    void SetGlauberFitHisto (Float_t f, Float_t mu, Float_t k, Int_t n = 10000, Bool_t Norm2Data = true);
+    void NormalizeGlauberFit ();
+    void DrawHistos (Bool_t isSim = true, Bool_t isData = true, Bool_t isGlauber = false, Bool_t isNBD = false);
+    
+    float FitGlauber (float *par, Float_t f0, Int_t k0, Int_t k1, Int_t nEvents);
+    void FindMuGoldenSection (Float_t *mu, Float_t *chi2, Float_t mu_min, Float_t mu_max, Float_t f, Float_t k, Int_t nEvents = 10000, Int_t nIter = 5);
+    
+    Float_t GetChi2 (void) const;
+    
+    Float_t NBD(Float_t n, Float_t mu, Float_t k) const;
+    void SetNBDhist(Float_t mu, Float_t k);
+    float Nancestors(float f) const;
+    float NancestorsMax(float f) const;
+    
+    std::unique_ptr<TH1F> GetModelHisto (const Float_t range[2], TString name, const Float_t par[3], Int_t nEvents);
+    
+    //         
+    //         Setters
+    //         
+    void SetInputHisto (const TH1F &h)   { fDataHisto = h; }
+    void SetFitMinBin  (Int_t min)      { fFitMinBin = min; }
+    void SetFitMaxBin  (Int_t min)      { fFitMaxBin = min; }
+    void SetNormMinBin  (Int_t min)     { fNormMinBin = min; }
+    void SetBinSize  (Int_t size)        { fBinSize = size; }
+    void SetOutDirName (TString name)    { fOutDirName = name; }
+    void SetMode (const TString mode) { fMode = mode; }
+    
+    //         
+    //         Getters
+    //         
+    TH1F GetGlauberFitHisto () const { return fGlauberFitHisto; }
+    TH1F GetDataHisto ()       const { return fDataHisto;  }
+    TH1F GetNBDHisto ()        const { return fNbdHisto;   }
+    TH1F GetNpartHisto ()      const { return fNpartHisto; }
+    TH1F GetNcollHisto ()      const { return fNcollHisto;  }
+    TH1F GetBestFiHisto ()     const { return fBestFitHisto;  }
+    
+    
+  private:
+    
+    /**   Data members  **/
+    TH1F fNpartHisto; 
+    TH1F fNcollHisto; 
+    TH1F fDataHisto; 
+    TH1F fNbdHisto; 
+    TH1F fGlauberFitHisto; 
+    TH1F fBestFitHisto;
+    
+    /* MC data */
+    std::unique_ptr<TTree> fSimTree{nullptr};
+    
+    Float_t fNpart{-1.};
+    Float_t fNcoll{-1.};
+    
+    Float_t fMaxValue{-1.};
+    
+    Int_t fNbins{-1};
+    Int_t fBinSize{-1};
+    
+    Int_t fFitMinBin{-1};
+    Int_t fFitMaxBin{-1};
+    
+    Int_t fNormMinBin{-1};
+    
+    TString fMode{"Default"};
+    
+    TString fOutDirName{""};
+    ClassDef(Fitter, 2);
+    
+  };
 }
 
 #endif
diff --git a/glauber/FitterHelper.h b/glauber/FitterHelper.h
index daa705c..4c6c4ad 100644
--- a/glauber/FitterHelper.h
+++ b/glauber/FitterHelper.h
@@ -1,8 +1,8 @@
 /** @file   FitterHelper.h
-    @author Viktor Klochkov (klochkov44@gmail.com)
-    @author Ilya Selyuzhenkov (ilya.selyuzhenkov@gmail.com)
-    @brief  Methods for fit QA
-*/
+ *    @author Viktor Klochkov (klochkov44@gmail.com)
+ *    @author Ilya Selyuzhenkov (ilya.selyuzhenkov@gmail.com)
+ *    @brief  Methods for fit QA
+ */
 
 #ifndef GlauberFitterHelper_H
 #define GlauberFitterHelper_H 1
@@ -18,79 +18,79 @@
 
 namespace Glauber
 {
-    inline void DrawHistos (const Fitter& fit, Bool_t isSim, Bool_t isData, Bool_t isGlauber, Bool_t isNBD )
-    {
-        std::unique_ptr <TCanvas> c1 {new TCanvas("c1", "canvas", 1500, 900)};
-
-        c1->Divide(2,2);
-        
-        std::unique_ptr <TPad> c1_1 {(TPad*) c1->GetListOfPrimitives()->FindObject("c1_1")};
-        std::unique_ptr <TPad> c1_2 {(TPad*) c1->GetListOfPrimitives()->FindObject("c1_2")};
-        std::unique_ptr <TPad> c1_4 {(TPad*) c1->GetListOfPrimitives()->FindObject("c1_4")};
-
-        c1_1->SetLogy(1);
-        c1_2->SetLogy(1);
-        c1_4->SetLogy(1);
-        
-        /*const*/ TH1F hGlaub = fit.GetGlauberFitHisto();
-        /*const*/ TH1F hData = fit.GetDataHisto();
-        /*const*/ TH1F hNBD = fit.GetNBDHisto();
-        /*const*/ TH1F hNcoll = fit.GetNcollHisto();
-        /*const*/ TH1F hNpart = fit.GetNpartHisto();
-        /*const*/ TH1F hBestFit = fit.GetBestFiHisto();
-
-        std::unique_ptr <TFile> fOut{TFile::Open("glauber_qa.root", "recreate")}; 
-
-        if (isSim){
-            c1->cd(1);
-            hNcoll.SetLineColor(2);
-            
-            hNcoll.Draw();
-            hNpart.Draw("same");
-            
-            std::unique_ptr <TLegend> legSim { new TLegend(0.6,0.75,0.75,0.83) }; 
-            legSim->AddEntry(&hNpart ,"Npart", "l");    
-            legSim->AddEntry(&hNcoll ,"hNcoll", "l");    
-            legSim->Draw("same");
-            
-            hNcoll.Write();
-            hNpart.Write();
-        }
-        
-        if (isData){
-            c1->cd(2);
-            hData.Draw();
-            hData.Write();
-            if (isGlauber){
-                hBestFit.SetLineColor (kRed);
-                hBestFit.Draw("same");
-                
-                std::unique_ptr <TLegend>  legData { new TLegend(0.6,0.75,0.75,0.83) };
-                legData->AddEntry(&hBestFit ,"Fit", "l");    
-                legData->AddEntry(&hData ,"Data", "l");    
-                legData->Draw("same");   
-                hBestFit.Write();
-            }
-        }
-        
-        if (isNBD){
-            c1->cd(3);
-            hNBD.Draw();
-            hNBD.Write();
-
-        }
+  inline void DrawHistos (const Fitter& fit, Bool_t isSim, Bool_t isData, Bool_t isGlauber, Bool_t isNBD )
+  {
+    std::unique_ptr <TCanvas> c1 {new TCanvas("c1", "canvas", 1500, 900)};
+    
+    c1->Divide(2,2);
+    
+    std::unique_ptr <TPad> c1_1 {(TPad*) c1->GetListOfPrimitives()->FindObject("c1_1")};
+    std::unique_ptr <TPad> c1_2 {(TPad*) c1->GetListOfPrimitives()->FindObject("c1_2")};
+    std::unique_ptr <TPad> c1_4 {(TPad*) c1->GetListOfPrimitives()->FindObject("c1_4")};
+    
+    c1_1->SetLogy(1);
+    c1_2->SetLogy(1);
+    c1_4->SetLogy(1);
+    
+    /*const*/ TH1F hGlaub = fit.GetGlauberFitHisto();
+    /*const*/ TH1F hData = fit.GetDataHisto();
+    /*const*/ TH1F hNBD = fit.GetNBDHisto();
+    /*const*/ TH1F hNcoll = fit.GetNcollHisto();
+    /*const*/ TH1F hNpart = fit.GetNpartHisto();
+    /*const*/ TH1F hBestFit = fit.GetBestFiHisto();
+    
+    std::unique_ptr <TFile> fOut{TFile::Open("glauber_qa.root", "recreate")}; 
+    
+    if (isSim){
+      c1->cd(1);
+      hNcoll.SetLineColor(2);
+      
+      hNcoll.Draw();
+      hNpart.Draw("same");
+      
+      std::unique_ptr <TLegend> legSim { new TLegend(0.6,0.75,0.75,0.83) }; 
+      legSim->AddEntry(&hNpart ,"Npart", "l");    
+      legSim->AddEntry(&hNcoll ,"hNcoll", "l");    
+      legSim->Draw("same");
+      
+      hNcoll.Write();
+      hNpart.Write();
+    }
+    
+    if (isData){
+      c1->cd(2);
+      hData.Draw();
+      hData.Write();
+      if (isGlauber){
+        hBestFit.SetLineColor (kRed);
+        hBestFit.Draw("same");
         
-        if (isGlauber){
-            c1->cd(4);
-            hBestFit.Draw();
-        }
-
-        c1->Write();
-        c1->SaveAs("glauber.pdf");
-        fOut->Close();
+        std::unique_ptr <TLegend>  legData { new TLegend(0.6,0.75,0.75,0.83) };
+        legData->AddEntry(&hBestFit ,"Fit", "l");    
+        legData->AddEntry(&hData ,"Data", "l");    
+        legData->Draw("same");   
+        hBestFit.Write();
+      }
     }
     
+    if (isNBD){
+      c1->cd(3);
+      hNBD.Draw();
+      hNBD.Write();
+      
+    }
+    
+    if (isGlauber){
+      c1->cd(4);
+      hBestFit.Draw();
+    }
     
+    c1->Write();
+    c1->SaveAs("glauber.pdf");
+    fOut->Close();
+  }
+  
+  
 }
 
 
diff --git a/glauber/main.cpp b/glauber/main.cpp
index 7a57337..7f6477f 100644
--- a/glauber/main.cpp
+++ b/glauber/main.cpp
@@ -1,4 +1,5 @@
 #include <iostream>
+#include <chrono>
 
 #include "Fitter.h"
 #include "FitterHelper.h"
@@ -13,69 +14,77 @@ using namespace Glauber;
 
 int main(int argc, char *argv[])
 {
-    if (argc < 2)
-    {
-        std::cout << "Wrong number of parameters! Executable usage:" << std::endl;
-        std::cout << "   ./glauber f0 k0" << std::endl;
-        return -1;
-    }
-    const Float_t f0 = atof( argv[1]);
-    const Int_t k0 = atoi( argv[2] );
-    const Int_t k1 = atoi( argv[2] );
-    
-    // *****************************************
-    // Modify this part according to your needs
-    // *****************************************
 
-    ///  |   mode    |   function for Na     |
-    ///  |   Default |  Npart + (1-f)*Ncoll  |
-    ///  |   PSD     |     f - Npart         |
-    ///  |   Npart   |     Npart^f           |
-    ///  |   Ncoll   |     Ncoll^f           |
-    const TString mode = "Default";
-    
-    const TString glauber_filename = "../input/glauber_auau_sigma_30_100k.root";   // input files
-    const TString glauber_treename = "nt_Au_Au";
-    const TString in_filename = "../input/test_input.root";
-    const TString histoname = "hMreco";
+  if (argc < 2)
+  {
+    std::cout << "Wrong number of parameters! Executable usage:" << std::endl;
+    std::cout << "   ./glauber f0 k0" << std::endl;
+    return -1;
+  }
+  const Float_t f0 = atof( argv[1]);
+  const Int_t k0 = atoi( argv[2] );
+  const Int_t k1 = atoi( argv[2] );
+  
+  // *****************************************
+  // Modify this part according to your needs
+  // *****************************************
 
-    const Int_t min_bin = 50;      // not fitting low multiplicity region due to trigger bias, etc
-    const Int_t max_bin = 10000;   // very large number to fit the whole histo
-    const Int_t nevents = 100000;
+  ///  |   mode    |   function for Na     |
+  ///  |   Default |  Npart + (1-f)*Ncoll  |
+  ///  |   PSD     |     f - Npart         |
+  ///  |   Npart   |     Npart^f           |
+  ///  |   Ncoll   |     Ncoll^f           |
+  const TString mode = "Default";
+  
+  const TString glauber_filename = "../input/glauber_auau_sigma_30_100k.root";   // input files
+  const TString glauber_treename = "nt_Au_Au";
+  const TString in_filename = "../input/test_input.root";
+  const TString histoname = "hMreco";
 
-    const TString outdir = ".";
-    // *****************************************
-    // *****************************************
+  const Int_t min_bin = 50;      // not fitting low multiplicity region due to trigger bias, etc
+  const Int_t max_bin = 10000;   // very large number to fit the whole histo
+  const Int_t nevents = 100000;
 
-    std::unique_ptr<TFile> glauber_file{ TFile::Open(glauber_filename, "read") };
-    std::unique_ptr<TTree> glauber_tree{ (TTree*) glauber_file->Get(glauber_treename) };
+  const TString outdir = ".";
+  // *****************************************
+  // *****************************************
 
-    std::unique_ptr<TFile> f{TFile::Open(in_filename)};    
-    TH1F *hdata = (TH1F*)f->Get(histoname);
-    
-    Fitter fitter ( std::move(glauber_tree) );
+  std::unique_ptr<TFile> glauber_file{ TFile::Open(glauber_filename, "read") };
+  std::unique_ptr<TTree> glauber_tree{ (TTree*) glauber_file->Get(glauber_treename) };
 
-    fitter.SetMode(mode);
-    fitter.SetInputHisto(*hdata);
-    fitter.SetBinSize(1);
-    fitter.Init(nevents);
-    
-    fitter.SetFitMinBin(min_bin);
-    fitter.SetFitMaxBin(max_bin);
-    fitter.SetOutDirName(outdir);
+  std::unique_ptr<TFile> f{TFile::Open(in_filename)};    
+  TH1F *hdata = (TH1F*)f->Get(histoname);
+  
+  Fitter fitter ( std::move(glauber_tree) );
 
-    float par[3];
-    const float chi2 = fitter.FitGlauber(par, f0, k0, k1, nevents);
+  fitter.SetMode(mode);
+  fitter.SetInputHisto(*hdata);
+  fitter.SetBinSize(1);
+  fitter.Init(nevents);
+  
+  fitter.SetFitMinBin(min_bin);
+  fitter.SetFitMaxBin(max_bin);
+  fitter.SetOutDirName(outdir);
 
-    std::cout << "f = " << par[0] << "    mu = " << par[1] << "    k = " << par[2] << "    chi2 = " << chi2 << std::endl; 
-    
-    Glauber::DrawHistos(fitter, true, true, true, true);
+  float par[3];
+  
+  auto start = std::chrono::system_clock::now();
+  
+  const float chi2 = fitter.FitGlauber(par, f0, k0, k1, nevents);
+  
+  auto end = std::chrono::system_clock::now();
+  std::chrono::duration<double> elapsed_seconds = end - start;
+  std::cout << "elapsed time: " << elapsed_seconds.count() << " s\n";
 
-    const float range[2] = {300, 350.};
-    std::unique_ptr<TH1F> hB(fitter.GetModelHisto (range, "B", par, 100000));
-    hB->SaveAs( "b_test.root" );
-    
-    std::cout << "END!" << std::endl;
+  std::cout << "f = " << par[0] << "    mu = " << par[1] << "    k = " << par[2] << "    chi2 = " << chi2 << std::endl; 
+  
+  Glauber::DrawHistos(fitter, true, true, true, true);
 
-    return 0;
+  const float range[2] = {300, 350.};
+  std::unique_ptr<TH1F> hB(fitter.GetModelHisto (range, "B", par, 100000));
+  hB->SaveAs( "b_test.root" );
+  
+  std::cout << "END!" << std::endl;
+
+  return 0;
 }
-- 
GitLab