class RhoCandList;
class RhoCandidate;
class PndAnaPidSelector;
class PndAnaPidCombiner;
class PndAnalysis;

void run_ana_complete_llbar(int nevts=0)
{ 
  gROOT->Reset();
  gStyle->SetOptStat("ne");
  gStyle->SetOptFit(1111);
  gStyle -> SetOptDate(0);
  gStyle -> SetOptFile(0);
  gStyle -> SetLabelFont(60,"x");
  gStyle -> SetLabelFont(60,"y");
  gStyle -> SetLabelSize(0.04,"x");
  gStyle -> SetLabelSize(0.04,"y");
  gStyle -> SetLabelOffset(0.01,"x");
  gStyle -> SetLabelOffset(0.01,"y");
  gStyle -> SetTitleXSize(0.04);
  gStyle -> SetTitleYSize(0.04);
  gStyle -> SetTitleXOffset(1.0);
  gStyle -> SetTitleYOffset(1.0);
  gStyle -> SetTitleFont(62,"x");
  gStyle -> SetTitleFont(62,"y");
  gStyle->SetHistLineWidth(1);
  gStyle->SetHistLineColor(kBlue);
  
  
  int i=0,j=0, k=0, l=0,c=0;
  
  //*******************Analysis input root files ************
  TString OutFile="output.root";
    
  TString inPidFile = "llbar_pid_complete.root";
  TString inParFile = "llbar_simparams.root";
  
  // *** initialization
  FairRunAna* fRun = new FairRunAna();
  FairRuntimeDb* rtdb = fRun->GetRuntimeDb();
  fRun->SetInputFile(inPidFile);
  
  FairParRootFileIo* parIO = new FairParRootFileIo();
  parIO->open(inParFile);
  
  rtdb->setFirstInput(parIO);
  rtdb->setOutput(parIO);  
  
  fRun->SetOutputFile(OutFile);
  fRun->Init(); 
  
  // *** Booking histograms *****************************	
  
  TH1F * IM_Lam = new TH1F("IM_Lam"," ; Invariant Mass[p#pi^{-}](GeV/c2);Counts",200,1.08,1.16);
  TH1F *IM_Lam_vf   = new TH1F("IM_Lam_vf", "; Invariant Mass[p#pi^{-}](GeV/c2);Counts", 200, 1.08, 1.16);
  TH1F *IM_Lam_prob_vf  = new TH1F("IM_Lam_prob_vf", "#Lambda: Prob vertex fit;Prob(#chi^{2});Counts",100,0,1);
  
  TH1F * IM_AntiLam = new TH1F("IM_AntiLam","; Invariant Mass [#bar{p}#pi^{+}](GeV/c2);Counts",200,1.08,1.16);
  TH1F * IM_AntiLam_vf   = new TH1F("IM_AntiLam_vf", "; Invariant Mass [#bar{p}#pi^{+}](GeV/c2);Counts", 200, 1.08, 1.16);
  TH1F * IM_AntiLam_prob_vf  = new TH1F("IM_AntiLam_prob_vf", "#bar{#Lambda}: Prob vertex fit;Prob(#chi^{2});Counts",100,0,1);
  
 
  // *** the data reader object ************************
  
  PndAnalysis* theAnalysis = new PndAnalysis();
  if (nevts==0) nevts= theAnalysis->GetEntries();
  
  // *** RhoCandLists for the analysis******************
  RhoCandList proton, antiproton, piplus, piminus, lambda, antilambda;
  
   
  while (theAnalysis->GetEvent() && i++<nevts)
    {
          
      // *** Select with no PID info ('All'); type and mass are set
      theAnalysis->FillList(proton,  "ProtonAllPlus");
      theAnalysis->FillList(piminus, "PionAllMinus");
      theAnalysis->FillList(antiproton, "ProtonAllMinus");
      theAnalysis->FillList(piplus, "PionAllPlus");
      
      
      // *** combinatoric
      
      lambda.Combine(proton, piminus);
      antilambda.Combine(antiproton, piplus);
      lambda.SetType(3122);
      antilambda.SetType(-3122);
     
      // Lambda Candidate

      for (j=0;j<lambda.GetLength();++j)
        {
	  IM_Lam->Fill(lambda[j]->M());
       	  PndKinVtxFitter vtxfitter(lambda[j]);	 // instantiate a vertex fitter
	  vtxfitter.Fit();
			
	  double chi2_vtx = vtxfitter.GetChi2();	// access chi2 of fit
	  double prob_vtx = vtxfitter.GetProb();	// access probability of fit
	  IM_Lam_prob_vf->Fill(prob_vtx);			
	  
	  //if ( prob_vtx > 0.01 )			   
          if ( prob_vtx > 0.1 )				// when good enough, fill some histos
	    {
	      RhoCandidate *lamfit = lambda[j]->GetFit();	// access the fitted cand
	      
	      IM_Lam_vf->Fill(lamfit->M());            
	      
	    }
	  
	} // end of Cand loop
      

      // AntiLambda Candidate
      
      for (k=0;k<antilambda.GetLength();++k)
        {
	  IM_AntiLam->Fill(antilambda[k]->M());
	  PndKinVtxFitter vtxfitter(antilambda[k]);	// instantiate a vertex fitter
	  vtxfitter.Fit();
	  
	  double chi2_vtx = vtxfitter.GetChi2();	// access chi2 of fit
	  double prob_vtx = vtxfitter.GetProb();	// access probability of fit
	  IM_AntiLam_prob_vf->Fill(prob_vtx);			
	  
	  //if ( prob_vtx > 0.01 )		       
	  if ( prob_vtx > 0.1 )				// when good enough, fill some histos
	    {
	      RhoCandidate *antilamfit = antilambda[k]->GetFit();	// access the fitted cand
	      IM_AntiLam_vf->Fill(antilamfit->M());       
	      
	    } 
	  
	  
    } // end of Cand loop
      
    } //end of event loop   

   
      
     TString outfilename = "all.root";
   //TString outfilename = "loose.root";
   //TString outfilename = "best.root";

      TFile *file = new TFile(outfilename,"RECREATE");
      IM_Lam->Write();
      IM_Lam_vf->Write();
      IM_Lam_prob_vf->SetLineWidth(2);
      IM_Lam_prob_vf->Write();
      
      IM_AntiLam->Write();
      IM_AntiLam_vf->Write();
      IM_AntiLam_prob_vf->SetLineWidth(2);
      IM_AntiLam_prob_vf->Write();
      
      file->Close();	
      
   }// end of main loop
