ROOT logo
#if !defined(__CINT__) || defined(__MAKECINT__)
#include <iostream>

#include "AliPWGHistoTools.h"
#include "AliPWGFunc.h"
#include "AliLatexTable.h"
#include "TF1.h"
#include "TFile.h"
#include "TH1.h"
#include "TROOT.h"
#include "TDatabasePDG.h"
#include "TCanvas.h"
#include "TMath.h"
#include "TSystem.h"
#include "THashList.h"
#include "TMinuit.h"
#include "TLatex.h"

using namespace std;
#endif

enum {kFitExpPt, kFitLevi, fFitExpMt, kFitBoltzmann, kFitBlastWave, kFitBoseEinstein, kFitFermiDirac};
Bool_t skipMean = 0;

void FitParticle(TH1 * h, const char * partName, Float_t min = 0, Float_t max =3, Float_t scaleHisto = -1., Int_t fitFunc = kFitLevi, Int_t vartype = AliPWGFunc::kdNdpt, const char * fileOut = 0, Bool_t wait = 0, Float_t meanMin = 0., Float_t meanMax = 100) ;
void FitParticle(const char * file, const char * histo, const char * partName,  const char * listname=0, Float_t min = 0, Float_t max =3, Float_t scaleHisto = -1., Int_t fitFunc = kFitLevi, Int_t vartype = AliPWGFunc::kdNdpt, const char * fileOut = 0, Bool_t wait = 0);

void FitParticle(const char * file, const char * histo, const char * partName,  const char * listname, Float_t min, Float_t max, Float_t scaleHisto, Int_t fitFunc, Int_t vartype, const char * fileOut, Bool_t wait) {

  // Generic Macro to fit any particle using the PWG2/SPECTRA/Fit macros
  //
  // You have to provide:
  // - file: file name. If not set, uses gFile
  // - histo: histogram name name (assumend to be in the main folder of the file)
  // - listname: if different from 0, histo is looked in this tlist
  // - partName: it is used to get the mass of the particle from
  //   TDatabasePDG. If you are not sure, just use a part of the name: a
  //   list of names matching it is printed on screen
  // 
  // You can optionally provide:
  // - min, max: the fit range
  // - scaleHisto: a scaling factor for the histo. If negative, it is
  //   ignored. If the histo is scaled, the bin width is also
  //   divided).
  // - fitFunc: id of the function, levi is the default
  //   valide options: kFitExpPt, kFitLevi, fFitExpMt, kFitBoltzmann, kFitBlastWave
  // - varType: the variable used in the pt spectrum (see AliPWGFunc.h)

  // Author: Michele Floris, CERN

  // load stuff
  gSystem->Load("libTree.so");
  gSystem->Load("libVMC.so");
  gSystem->Load("libMinuit.so");
  gSystem->Load("libSTEERBase.so");
  gSystem->Load("libESD.so");
  gSystem->Load("libAOD.so");
  gSystem->Load("libANALYSIS.so");
  gSystem->Load("libANALYSISalice.so");
  gSystem->Load("libCORRFW.so");
  gSystem->Load("libPWG2spectra.so");


  // open file
  TFile * f = file ? new TFile(file) : gFile;  
  TH1 * h = 0;
  if(listname){
    TList * l = (TList*) gDirectory->Get(listname);
    h = (TH1*) l->FindObject(histo);
  }
  else{
    h = (TH1*) gDirectory->Get(histo); // 
  }

  FitParticle(h, partName, min, max, scaleHisto, fitFunc, vartype, fileOut, wait);
  


}

void FitParticle(TH1 * h, const char * partName, Float_t min , Float_t max, Float_t scaleHisto, Int_t fitFunc, Int_t vartype, const char * fileOut, Bool_t wait, Float_t meanMin, Float_t meanMax) { 


  // get histo and draw
  AliPWGFunc * fm = new AliPWGFunc;
  fm->SetVarType(AliPWGFunc::VarType_t(vartype));
  //  fm->SetVarType(AliPWGFunc::VarType_t(0));//FIXME
  //  cout << "Warning: hacked vartype" << endl;
  
  if (!TDatabasePDG::Instance()->GetParticle(partName)) {
    cout << "Wrong particle name " << partName << endl;

    const THashList * l = TDatabasePDG::Instance()->ParticleList();
    Int_t npart = l->GetSize();
    for(Int_t ipart = 0; ipart < npart; ipart++){
      TString name = l->At(ipart)->GetName();
      if(name.Contains(partName, TString::kIgnoreCase))
	cout << " - Did you mean [" << name.Data() << "] ?" << endl;		 
    }
    
    cout << "Try [ TDatabasePDG::Instance()->GetParticle(partName) ] by hand "<< endl;
    return;
    
  }
  Double_t mass = TDatabasePDG::Instance()->GetParticle(partName)->Mass();
  cout << "Fitting ["<<partName<<"], mass: " << mass << endl;
  

  AliLatexTable * table;

  TF1* func = 0;
  Int_t normPar = -1;
  Int_t slopePar=0;
  if (fitFunc == kFitLevi)   {
    func = fm->GetLevi (mass, 0.4, 750,3);
    func->SetParLimits(1,0.0001,20000);
    table = new AliLatexTable(10,"c|ccccccccc");
    table->InsertCustomRow("Part & Func & Yield & FD Slope & $\\Chi^2$/NDF & Min X & Fit Min & Fit Max & Frac Below  & Mean ");
    normPar = 0;
    slopePar = 2;
  }
  if (fitFunc == kFitExpPt)  {
    func = fm->GetPTExp(0.2, 20);
    table = new AliLatexTable(10,"c|ccccccccc");
    table->InsertCustomRow("Part & Func & Yield & pT Slope & $\\Chi^2$/NDF & Min X & Fit Min & Fit Max & Frac Below & Mean ");
    normPar = 0;
    slopePar = 1;
  }
  if (fitFunc == fFitExpMt)  {
    func = fm->GetMTExp(mass,0.2, 20);
    table = new AliLatexTable(10,"c|ccccccccc");
    table->InsertCustomRow("Part & Func & Yield & mT Slope & $\\Chi^2$/NDF & Min X & Fit Min & Fit Max & Frac Below & Mean  ");
    normPar = 0;
    slopePar = 1;
  }
  if (fitFunc == kFitBoltzmann)  {
    func = fm->GetBoltzmann(mass, 0.2, 20);
    table = new AliLatexTable(10,"c|ccccccccc");
    table->InsertCustomRow("Part & Func & Yield & Bz Slope & $\\Chi^2$/NDF & Min X & Fit Min & Fit Max & Frac Below & Mean  ");
    normPar = 0;
    slopePar = 1;

  }
  if (fitFunc == kFitBlastWave)  {
    func = fm->GetBGBW(mass,0.6,0.3, 1, 1e5);// beta, T, n, norm 
    table = new AliLatexTable(12,"cc|cccccccccccc");
    table->InsertCustomRow("Part & Func & Yield & T & beta & n & $\\Chi^2$/NDF & Min X & Fit Min & Fit Max & Frac Below  & Mean ");
    func->SetParLimits(1, 0.1, 0.99);
    func->SetParLimits(2, 0.01, 1);
    func->SetParLimits(3, 0.01, 2);
    normPar = 4;
    slopePar = 2;
  }
  if (fitFunc == kFitBoseEinstein)  {
    func = fm->GetBoseEinstein(mass,0.3,20);
    table = new AliLatexTable(10,"c|ccccccccc");
    table->InsertCustomRow("Part & Func & Yield & BE Slope & $\\Chi^2$/NDF & Min X & Fit Min & Fit Max & Frac Below & Mean ");
    normPar = 0;
    slopePar = 1;
  }
  if (fitFunc == kFitFermiDirac)  {
    func = fm->GetFermiDirac(mass,0.3,20);
    table = new AliLatexTable(10,"c|ccccccccc");
    table->InsertCustomRow("Part & Func & Yield & FD Slope & $\\Chi^2$/NDF & Min X & Fit Min & Fit Max & Frac Below  & Mean  ");
    normPar = 0;
    slopePar = 1;
  }

    h->Sumw2();
  if (scaleHisto > 0) h->Scale(scaleHisto, "width");
//   TH1 * h = AliPWGHistoTools::GetdNdPtFromOneOverPt((TH1*) gDirectory->Get(histo)); // FIXME
//   cout << "WARNING SCALING2PI" << endl;
//   h->Scale(2*TMath::Pi());//Fixme

   h->Fit(func); // FIXME
   h->Fit(func); // FIXME
   h->Fit(func); // FIXME
   h->Fit(func,"IME0","",min,max);      
   h->Fit(func,"IME0","",min,max);      

   //   gMinuit->Command("SET STRATEGY 2"); // FIXME

  // if (!AliPWGHistoTools::Fit(h,func,min,max)) {
  //   cout << "Fitting error!" << endl;
  //   //    return;    
  // } FIXME
  cout << "Drawing" << endl;

  TCanvas * c = new TCanvas();
  cout << "1" << endl;
  c->SetLogy();
  cout << "2" << endl;
  h->Draw();
  cout << "3" << endl;
  func->Draw("same");
  cout << "4" << endl;

  // Print results nicely
  // populate table

  Double_t yield=0,yieldE=0;
  cout << "Y" << endl;
  AliPWGHistoTools::GetYield(h,func,yield,yieldE);  
  cout << "YE" << endl;
  TLatex * l = new TLatex(2,(h->GetMaximum()+h->GetMinimum())/2,Form("%3.3f #pm %3.3f (%s)", yield,yieldE, func->GetName()));
  l->Draw();

//   Float_t yield  = func->Integral(0.45,1.05);
//   Float_t yieldE = func->IntegralError(0.45,1.05);
  cout << "Slope Par: "<< slopePar << endl;

  Double_t tslope   = func->GetParameter(slopePar);
  Double_t tslopeE = func->GetParError(slopePar);	

  table->SetNextCol(Form("%s (%s)", partName, h->GetName()));
  table->SetNextCol(func->GetName());
  table->SetNextCol(yield,yieldE,-4);
  table->SetNextCol(tslope,tslopeE,-4);
  if(fitFunc == kFitBlastWave) {
    table->SetNextCol(func->GetParameter(1),func->GetParError(1),-4);
    table->SetNextCol(func->GetParameter(3),func->GetParError(3),-4);
  }
  //  table->SetNextCol(func->GetParameter(1),func->GetParError(1),-4);
  table->SetNextCol(Form("%2.2f/%d",func->GetChisquare(),func->GetNDF()));
  Float_t lowestPoint = TMath::Max(AliPWGHistoTools::GetLowestNotEmptyBinEdge(h),min);
  //  Float_t yieldAbove  = func->Integral(lowestPoint,100);
  Float_t yieldBelow  = func->Integral(0,lowestPoint);
  table->SetNextCol(lowestPoint,-3);
  table->SetNextCol(min,-2);
  table->SetNextCol(max,-2);
  table->SetNextCol(yieldBelow/yield,-3);

  Double_t mean=0, meane=0;
  // Float_t mean2=0, mean2e=0;
  //  AliPWGHistoTools::GetMean      (func, mean,  meane , 0.,100., normPar);
  AliPWGHistoTools::GetMeanDataAndExtrapolation      (h, func, mean,  meane , meanMin, meanMax);
  //  AliPWGHistoTools::GetMeanDataAndExtrapolation      (h, func, mean,  meane , 0.,4.5);
  // AliPWGHistoTools::GetMeanSquare(func, mean2, mean2e, 0.,100., normPar);
  if(skipMean) table->SetNextCol("N/A");
  else table->SetNextCol(mean,  meane ,-4);
  // table->SetNextCol(mean2, mean2e,-4);
  //			 fMean2->IntegralError(0,100)/func->Integral(0,100),-7);
  table->InsertRow();
  table->PrintTable("ASCII");
  
  if(fileOut) {
    TFile * fout = new TFile(fileOut, "update");    
    c->SetName(Form("c_%s_%s_fit_%2.2f_%2.2f", h->GetName(), func->GetName(), min, max));
    c->Write();
    TH1F * hFit = new TH1F ("hFitResults", "hFitResults", 2,0,1);
    hFit->SetBinContent(1, yield); hFit->SetBinError(1, yieldE);
    hFit->SetBinContent(2, mean ); hFit->SetBinError(2, meane);
    hFit->GetXaxis()->SetBinLabel(1, "yield");
    hFit->GetXaxis()->SetBinLabel(2, "<pt>");
    hFit->Write(Form("hFit_%s_%s_fit_%2.2f_%2.2f", h->GetName(), func->GetName(), min, max));
    fout->Purge(); // remove old canvases
    fout->Close();
  }


  if(wait)  c->WaitPrimitive();


}

// Double_t MicheleFunction(Double_t *x, Double_t *p) {

//   Double_t xloc = x[0];
//   Double_t y = 0;
//   if(xloc < p[0]) {
//     y = xloc*TMath::Exp(-xloc/p[2]);
//   } else if (xloc > p[0] && xloc < p[1]) {
    
//   }


// }
 FitParticle.C:1
 FitParticle.C:2
 FitParticle.C:3
 FitParticle.C:4
 FitParticle.C:5
 FitParticle.C:6
 FitParticle.C:7
 FitParticle.C:8
 FitParticle.C:9
 FitParticle.C:10
 FitParticle.C:11
 FitParticle.C:12
 FitParticle.C:13
 FitParticle.C:14
 FitParticle.C:15
 FitParticle.C:16
 FitParticle.C:17
 FitParticle.C:18
 FitParticle.C:19
 FitParticle.C:20
 FitParticle.C:21
 FitParticle.C:22
 FitParticle.C:23
 FitParticle.C:24
 FitParticle.C:25
 FitParticle.C:26
 FitParticle.C:27
 FitParticle.C:28
 FitParticle.C:29
 FitParticle.C:30
 FitParticle.C:31
 FitParticle.C:32
 FitParticle.C:33
 FitParticle.C:34
 FitParticle.C:35
 FitParticle.C:36
 FitParticle.C:37
 FitParticle.C:38
 FitParticle.C:39
 FitParticle.C:40
 FitParticle.C:41
 FitParticle.C:42
 FitParticle.C:43
 FitParticle.C:44
 FitParticle.C:45
 FitParticle.C:46
 FitParticle.C:47
 FitParticle.C:48
 FitParticle.C:49
 FitParticle.C:50
 FitParticle.C:51
 FitParticle.C:52
 FitParticle.C:53
 FitParticle.C:54
 FitParticle.C:55
 FitParticle.C:56
 FitParticle.C:57
 FitParticle.C:58
 FitParticle.C:59
 FitParticle.C:60
 FitParticle.C:61
 FitParticle.C:62
 FitParticle.C:63
 FitParticle.C:64
 FitParticle.C:65
 FitParticle.C:66
 FitParticle.C:67
 FitParticle.C:68
 FitParticle.C:69
 FitParticle.C:70
 FitParticle.C:71
 FitParticle.C:72
 FitParticle.C:73
 FitParticle.C:74
 FitParticle.C:75
 FitParticle.C:76
 FitParticle.C:77
 FitParticle.C:78
 FitParticle.C:79
 FitParticle.C:80
 FitParticle.C:81
 FitParticle.C:82
 FitParticle.C:83
 FitParticle.C:84
 FitParticle.C:85
 FitParticle.C:86
 FitParticle.C:87
 FitParticle.C:88
 FitParticle.C:89
 FitParticle.C:90
 FitParticle.C:91
 FitParticle.C:92
 FitParticle.C:93
 FitParticle.C:94
 FitParticle.C:95
 FitParticle.C:96
 FitParticle.C:97
 FitParticle.C:98
 FitParticle.C:99
 FitParticle.C:100
 FitParticle.C:101
 FitParticle.C:102
 FitParticle.C:103
 FitParticle.C:104
 FitParticle.C:105
 FitParticle.C:106
 FitParticle.C:107
 FitParticle.C:108
 FitParticle.C:109
 FitParticle.C:110
 FitParticle.C:111
 FitParticle.C:112
 FitParticle.C:113
 FitParticle.C:114
 FitParticle.C:115
 FitParticle.C:116
 FitParticle.C:117
 FitParticle.C:118
 FitParticle.C:119
 FitParticle.C:120
 FitParticle.C:121
 FitParticle.C:122
 FitParticle.C:123
 FitParticle.C:124
 FitParticle.C:125
 FitParticle.C:126
 FitParticle.C:127
 FitParticle.C:128
 FitParticle.C:129
 FitParticle.C:130
 FitParticle.C:131
 FitParticle.C:132
 FitParticle.C:133
 FitParticle.C:134
 FitParticle.C:135
 FitParticle.C:136
 FitParticle.C:137
 FitParticle.C:138
 FitParticle.C:139
 FitParticle.C:140
 FitParticle.C:141
 FitParticle.C:142
 FitParticle.C:143
 FitParticle.C:144
 FitParticle.C:145
 FitParticle.C:146
 FitParticle.C:147
 FitParticle.C:148
 FitParticle.C:149
 FitParticle.C:150
 FitParticle.C:151
 FitParticle.C:152
 FitParticle.C:153
 FitParticle.C:154
 FitParticle.C:155
 FitParticle.C:156
 FitParticle.C:157
 FitParticle.C:158
 FitParticle.C:159
 FitParticle.C:160
 FitParticle.C:161
 FitParticle.C:162
 FitParticle.C:163
 FitParticle.C:164
 FitParticle.C:165
 FitParticle.C:166
 FitParticle.C:167
 FitParticle.C:168
 FitParticle.C:169
 FitParticle.C:170
 FitParticle.C:171
 FitParticle.C:172
 FitParticle.C:173
 FitParticle.C:174
 FitParticle.C:175
 FitParticle.C:176
 FitParticle.C:177
 FitParticle.C:178
 FitParticle.C:179
 FitParticle.C:180
 FitParticle.C:181
 FitParticle.C:182
 FitParticle.C:183
 FitParticle.C:184
 FitParticle.C:185
 FitParticle.C:186
 FitParticle.C:187
 FitParticle.C:188
 FitParticle.C:189
 FitParticle.C:190
 FitParticle.C:191
 FitParticle.C:192
 FitParticle.C:193
 FitParticle.C:194
 FitParticle.C:195
 FitParticle.C:196
 FitParticle.C:197
 FitParticle.C:198
 FitParticle.C:199
 FitParticle.C:200
 FitParticle.C:201
 FitParticle.C:202
 FitParticle.C:203
 FitParticle.C:204
 FitParticle.C:205
 FitParticle.C:206
 FitParticle.C:207
 FitParticle.C:208
 FitParticle.C:209
 FitParticle.C:210
 FitParticle.C:211
 FitParticle.C:212
 FitParticle.C:213
 FitParticle.C:214
 FitParticle.C:215
 FitParticle.C:216
 FitParticle.C:217
 FitParticle.C:218
 FitParticle.C:219
 FitParticle.C:220
 FitParticle.C:221
 FitParticle.C:222
 FitParticle.C:223
 FitParticle.C:224
 FitParticle.C:225
 FitParticle.C:226
 FitParticle.C:227
 FitParticle.C:228
 FitParticle.C:229
 FitParticle.C:230
 FitParticle.C:231
 FitParticle.C:232
 FitParticle.C:233
 FitParticle.C:234
 FitParticle.C:235
 FitParticle.C:236
 FitParticle.C:237
 FitParticle.C:238
 FitParticle.C:239
 FitParticle.C:240
 FitParticle.C:241
 FitParticle.C:242
 FitParticle.C:243
 FitParticle.C:244
 FitParticle.C:245
 FitParticle.C:246
 FitParticle.C:247
 FitParticle.C:248
 FitParticle.C:249
 FitParticle.C:250
 FitParticle.C:251
 FitParticle.C:252
 FitParticle.C:253
 FitParticle.C:254
 FitParticle.C:255
 FitParticle.C:256
 FitParticle.C:257
 FitParticle.C:258
 FitParticle.C:259
 FitParticle.C:260
 FitParticle.C:261
 FitParticle.C:262
 FitParticle.C:263
 FitParticle.C:264
 FitParticle.C:265
 FitParticle.C:266
 FitParticle.C:267
 FitParticle.C:268
 FitParticle.C:269
 FitParticle.C:270
 FitParticle.C:271
 FitParticle.C:272
 FitParticle.C:273
 FitParticle.C:274
 FitParticle.C:275
 FitParticle.C:276
 FitParticle.C:277
 FitParticle.C:278