#include <string.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <utility>

#include <TFile.h>
#include <TTree.h>
#include <TSystemDirectory.h>
#include <string.h>
#include <TFile.h>
#include <TTree.h>
#include <TH1.h>
#include <TH2.h>
#include <TNtuple.h>
#include <iostream>
#include <fstream>
#include <TRandom.h>
#include <TROOT.h>
#include <algorithm> 
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TProfile.h>
#include <TVectorD.h>


#include <cstdlib>
#include <cmath>
#include <vector>

#include <TApplication.h>



using namespace std;


int main(int argc, char **argv)
{

  // Working directories
  const char *dirname = "/work/leverington/beamprofilemonitor/hitdata/HIT_26-11-2016/with_timestamp/";

  
  const char *listfile = NULL;
  int ion = atoi(argv[1]);
  if (ion==1) {listfile = "energylist_p";}
  else  if (ion==2) {listfile = "energylist_he";}
  else if (ion==3) {listfile = "energylist_c";}
  else if (ion==4) {listfile = "energylist_o";}
  else {cerr<< argv[1] << " not allowed" << endl;
    cerr << "specify (1, 2, 3, or 4) for p, He4, C12, or O16" << endl;
    return 1;
  }
   ifstream in;
   ofstream ic1energyfile,ic2energyfile, beamenergyfile,beamenergyfile_iccorr, noisefile, focusfile,focusHITfile,  skewfile, kurtfile,focusFitfile,chi2Fitfile;
   ofstream beamenergyfile_beta,  peakFitfile;
   TFile *f;
   TTree *tree;
   Int_t nfiles = 0;
   Int_t EList = 0;
   Double_t Energy = 0.;
   Double_t F1 = 0.;
   Double_t Intensity = 0.;
   Double_t SP = 0.;
   char Filename[50];
   Int_t id = 0;
   Double_t signalmean = 0.;
   Double_t signalmeanerror = 0.;
   Double_t signalmean_corr = 0.;
   Double_t signalmeanerror_corr = 0.;
   Double_t signalmean_offsetcorr = 0.;
   Double_t signalmeanerror_offsetcorr = 0.;
   
   Double_t ic1mean = 0.;
   Double_t ic1meanerror = 0.;
   Double_t ic2mean = 0.;
   Double_t ic2meanerror = 0.;

   Double_t sp_air = 0.;
   Double_t sp_ps = 0.;
   Double_t sp2_air = 0.;
   Double_t sp2_ps = 0.;

   Double_t ic_beam_ratio = 0.;
   Double_t ic_beam_ratioerror = 0.;

   Double_t totalcurrent = 0.;
   Double_t totaltime = 0.;
   Double_t intcorr = 0.;
   Double_t icbpmcorrelation = 0.;

   Double_t noisemean = 0.;
   Double_t noiseRMS = 0.;
   Double_t focusmean = 0.;
   Double_t focusRMS = 0.;
   Double_t skewmean = 0.;
   Double_t skewRMS = 0.;
   Double_t kurtmean = 0.;
   Double_t kurtRMS = 0.;
   Double_t focusFitmean = 0.;
   Double_t focusFitRMS = 0.;
   Double_t chi2Fitmean = 0.;
   Double_t chi2FitRMS = 0.;
   Double_t peakFitmean = 0.;
   Double_t peakFitRMS = 0.;
   Double_t beta = 0.;
   Double_t gamma = 0.;
   Double_t zsqr = 0.;
   cout << "Trying to open"<< Form(": %s%s",dirname, listfile)<<"... " << endl;

   in.open(Form("%s%s.prn",dirname, listfile));

   ic1energyfile.open(Form("%s_ic1.txt",listfile ));
   ic2energyfile.open(Form("%s_ic1ratio.txt",listfile ));

   beamenergyfile.open(Form("%s_bpm1.txt",listfile ));
   beamenergyfile_beta.open(Form("%s_bpmbeta1.txt",listfile ));

   beamenergyfile_iccorr.open(Form("%s_bpm1ratio.txt",listfile ));

   noisefile.open(Form("%s_noise.txt",listfile ));
   focusfile.open(Form("%s_focus1.txt",listfile ));
   focusHITfile.open(Form("%s_focusHIT.txt",listfile ));
   skewfile.open(Form("%s_skew1.txt",listfile ));
   kurtfile.open(Form("%s_kurt1.txt",listfile ));
   focusFitfile.open(Form("%s_focusfit.txt",listfile ));
   chi2Fitfile.open(Form("%s_chi2fit.txt",listfile ));
   peakFitfile.open(Form("%s_peakfit.txt",listfile ));


   TF1 * f_sp_air = new TF1("f_sp_air","[0]*pow(x,[1])+[2]", 50, 250); //stopping power of protons in Air [MeV cm2 /g]
   f_sp_air->SetParameters(303.746, -0.873697,1.01335); //protons between 50 and 300 MeV

   TF1 * f_sp_ps = new TF1("f_sp_ps","[0]*pow(x,[1])+[2]", 50, 250); //stopping power of protons in polystyrene [MeV cm2 /g]
   f_sp_ps->SetParameters(361.936, -0.892255, 1.19133);  //protons between 50 and 220 MeV

   TF1 * f_h2sp_air = new TF1("f_h2sp_air","[0]*pow(x,[1])+[2]", 50, 250); //stopping power of helium in air [MeV cm2 /g]
   f_h2sp_air->SetParameters(1236.51, -0.880225, 4.17041);  //helium between 50 and 300 MeV
   
   TF1 * f_h2sp_ps = new TF1("f_h2sp_ps","[0]*pow(x,[1])+[2]", 50, 250); //stopping power of helium in polystyrene [MeV cm2 /g]
   f_h2sp_ps->SetParameters(1387.08, -0.882686,4.60833);  //heelium between 50 and 300 MeV
   
   TF1 * f_c12sp_air = new TF1("f_c12sp_air","[0]*pow(x,[1])+[2]", 80, 480); //stopping power of carbon in air [MeV cm2 /g]
   f_c12sp_air->SetParameters(13291.2, -0.925464,45.3876);  //carbon between 80 and 480 MeV

   TF1 * f_c12sp_ps = new TF1("f_c12sp_ps","[0]*pow(x,[1])+[2]", 80, 480); //stopping power of carbon in polystyrene [MeV cm2 /g]
   f_c12sp_ps->SetParameters(14538.9, -0.922423,49.2859);  //carbon between 80 and 480 MeV

   TF1 * f_o16sp_air = new TF1("f_o16sp_air","[0]*pow(x,[1])+[2]", 80, 480); //stopping power of oxygen in air [MeV cm2 /g]
   f_o16sp_air->SetParameters(24624.9, -0.925425,80.6828);  //oxygen between 80 and 480 MeV

   TF1 * f_o16sp_ps = new TF1("f_o16sp_ps","[0]*pow(x,[1])+[2]", 80,480); //stopping power of oxygen in polystyrene [MeV cm2 /g]
   f_o16sp_ps->SetParameters(26465.6, -0.928309,88.6728);  //oxygen between 80 and 480 MeV

   /////       ic1/SP intensity correction factor = 19.8E6+/-0.1E6 particles/s per nA/(Mevcm2/g)

   if (!in) {
     cout << Form("%s%s",dirname, listfile) << " not found." << endl;
     return 0;}
   cout << Form("%s%s",dirname, listfile) << " opened." << endl;

   in >> EList >> Energy >> F1 >> Intensity >> SP >> Filename >> id;//prime the while loop
   while (!in.eof()) {
     TFile * file = TFile::Open(Form("%s%s",dirname,Filename));
     TFile * outfile = TFile::Open(Form("plots/%s_plots",Filename),"RECREATE");
     cout << Filename << endl;
     //     TH1D* signalDist = 0;
     //     file->GetObject("signalDist",signalDist);
     //     signalmean = signalDist->GetMean();
     //     signalmeanerror =  signalDist->GetMeanError();
     //  cout << signalmean << " " << signalmeanerror << endl;
     //     delete signalDist;

     //  TCanvas *c1 = new TCanvas("c1");
     TTree *data;
     file->GetObject("newdata", data);
     TH2D *h_beamSignal_channel = (TH2D*)file->Get("th2d_beamSignal_channel");
     TH2D *h_bkg_channel = (TH2D*)file->Get("th2d_bkg_channel");

     noisemean = h_bkg_channel->GetMean(2);
     noiseRMS = h_bkg_channel->GetRMS(2);

    
     TVectorD *v = (TVectorD*)file->Get("icinfo");
     //   v->Print();
     totalcurrent = (*v)[0];
     totaltime = (*v)[1];
     //  data->Print();
     TH1D* h_beamSignal_1 = new TH1D("h_beamSignal_1","h_beamSignal_1",510,-500,50000);
     TH1D* h_ic1_1 = new TH1D("h_ic1_1","h_ic1_1",510,-50,500);
     TH1D* h_ic2_1 = new TH1D("h_ic2_1","h_ic2_1",510,-50,500);
    

    
     TH1D* h_ic_beam_ratio = new TH1D("h_ic_beam_ratio","h_ic_beam_ratio",500,0,500.);
     TH2D* h_beamSignal_v_ic = new TH2D("h_beamSignal_v_ic","h_beamSignal_v_ic",510,-50,500,510,-500,50000);

     TH1D* h_beamFocusX_1 = new TH1D("h_beamFocusX_1","h_beamFocusX_1",200,0,50.);
     TH1D* h_beamSkewX_1 = new TH1D("h_beamSkewX_1","h_beamSkewX_1",200,-10,10.);
     TH1D* h_beamKurtX_1 = new TH1D("h_beamKurtX_1","h_beamKurtX_1",200,-10,10.);
     TH1D* h_beamFocusX_fit = new TH1D("h_beamFocusX_fit","h_beamFocusX_fit",200,0,50.);
     TH1D* h_beamChi2_fit = new TH1D("h_beamChi2_fit","h_beamChi2_fit",200,0,50.);
     TH1D* h_beamPeakX_fit = new TH1D("h_beamPeakX_fit","h_beamPeakX_fit",1000,0,8000.);




     if (id>=0&&id<=26){
       //protons
       sp_air = f_sp_air->Eval(Energy)*(Intensity/1.0E6);
       sp_ps = f_sp_ps->Eval(Energy)*(Intensity/1.0E6);
       sp2_air = f_sp_air->Eval(Energy);
       sp2_ps = f_sp_ps->Eval(Energy);
       gamma = Energy/938.272 +1.; // gamma = E_u/M_u +1
       beta = sqrt(1. - 1./(gamma*gamma));
       zsqr = 1.;
     }
     else if (id>=27&&id<=52){
       //helium
       sp_air = f_h2sp_air->Eval(Energy)*(Intensity/1.0E6);
       sp_ps = f_h2sp_ps->Eval(Energy)*(Intensity/1.0E6);
       sp2_air = f_h2sp_air->Eval(Energy);
       sp2_ps = f_h2sp_ps->Eval(Energy);
       gamma = Energy/932.1055 +1.;// gamma = E_u/M_u +1
       beta = sqrt(1. - 1./(gamma*gamma));
       zsqr = 4.;

     }
     else if (id>=53&&id<=78){
       //carbon
       sp_air = f_c12sp_air->Eval(Energy)*(Intensity/1.0E6);
       sp_ps = f_c12sp_ps->Eval(Energy)*(Intensity/1.0E6);
       sp2_air = f_c12sp_air->Eval(Energy);
       sp2_ps = f_c12sp_ps->Eval(Energy);
       gamma = Energy/932.3539 +1.;// gamma = E_u/M_u +1
       beta = sqrt(1. - 1./(gamma*gamma));
       zsqr = 36.;

     }
     else if (id>=79&&id<=99){
       //oxygen
       sp_air = f_o16sp_air->Eval(Energy)*(Intensity/1.0E6);
       sp_ps = f_o16sp_ps->Eval(Energy)*(Intensity/1.0E6);
       sp2_air = f_o16sp_air->Eval(Energy);
       sp2_ps = f_o16sp_ps->Eval(Energy);
       gamma = Energy/931.4418 +1.;// gamma = E_u/M_u +1
       beta = sqrt(1. - 1./(gamma*gamma));
       zsqr = 64.;
       
      }
     else {
       sp_air = -1.;
       sp_ps = -1.;
       sp2_air = -1.;
       sp2_ps = -1.;
       gamma = 0.;
       beta = 0.;
       zsqr = -1.;
       
     }


     //  cout << Form("beamPeakX_fit*sqrt(2)*%F/2.3548",F1)  << endl;
     //     data->Project("h_beamSignal_1","beamSignal_1","beamon==1&&beamSignal_1>50");
     //  data->Project("h_beamSignal_1", Form("beamPeakX_fit*sqrt(2)*%F/2.3548",F1) ,"beamon==1&&ic1_1>0.005&&beamChi2_fit<200&&beamPeakX_fit>20");
     data->Project("h_beamSignal_1", "beamPeakX_fit*sqrt(2)*beamFocusX_fit/2.3548" ,"beamon==1&&ic1_1>0.001&&beamChi2_fit<200&&beamPeakX_fit>20");

     data->Project("h_beamFocusX_1","beamFocusX_1","beamon==1&&ic1_1>0.005&&beamSignal_1>100");
     data->Project("h_beamSkewX_1","beamSkewX_1","beamon==1&&ic1_1>0.005&&beamSignal_1>100");
     data->Project("h_beamKurtX_1","beamKurtX_1","beamon==1&&ic1_1>0.005&&beamSignal_1>100");
     data->Project("h_beamFocusX_fit","beamFocusX_fit","beamon==1&&ic1_1>0.005&&beamChi2_fit<200&&beamPeakX_fit>20");
     data->Project("h_beamChi2_fit","beamChi2_fit","beamon==1&&ic1_1>0.005&&beamChi2_fit<200&&beamPeakX_fit>20");
     data->Project("h_beamPeakX_fit","beamPeakX_fit","beamon==1&&ic1_1>0.005&&beamChi2_fit<200&&beamPeakX_fit>20");

     focusmean = h_beamFocusX_1->GetMean();
     focusRMS = h_beamFocusX_1->GetRMS();
     skewmean = h_beamSkewX_1->GetMean();
     skewRMS = h_beamSkewX_1->GetMeanError();
     kurtmean = h_beamKurtX_1->GetMean();
     kurtRMS = h_beamKurtX_1->GetMeanError();
     focusFitmean = h_beamFocusX_fit->GetMean();
     focusFitRMS = h_beamFocusX_fit->GetRMS();
     chi2Fitmean = h_beamChi2_fit->GetMean();
     chi2FitRMS = h_beamChi2_fit->GetRMS();
     peakFitmean = h_beamPeakX_fit->GetMean();
     peakFitRMS = h_beamPeakX_fit->GetRMS();

     data->Project("h_ic1_1","ic1_1","ic1_1>0.01");
     data->Project("h_ic2_1","ic2_1","ic2_1>0.01");
     
    
     

     data->Project("h_beamSignal_v_ic","(beamPeakX_fit*sqrt(2)*beamFocusX_fit/2.3548):ic1_1","beamon==1&&ic1_1>0.005&&beamChi2_fit<200&&beamPeakX_fit>20");
     icbpmcorrelation = h_beamSignal_v_ic->GetCorrelationFactor();

     data->Project("h_ic_beam_ratio","(beamPeakX_fit*sqrt(2)*beamFocusX_fit/2.3548)/ic1_1","beamon==1&&ic1_1>0.005&&beamChi2_fit<200&&beamPeakX_fit>20"); 
   
     signalmean = h_beamSignal_1->GetMean();
     signalmeanerror =  h_beamSignal_1->GetMeanError();

     
     ic1mean = h_ic1_1->GetMean();
     ic1meanerror =  h_ic1_1->GetMeanError();
     ic2mean = h_ic2_1->GetMean();
     ic2meanerror =  h_ic2_1->GetMeanError();

     ic_beam_ratio=h_ic_beam_ratio->GetMean();
     ic_beam_ratioerror=h_ic_beam_ratio->GetRMS();
     //  intcorr = (Intensity /19.8E6) / (totalcurrent/sp2_air/totaltime);
     intcorr = (Intensity / 19.8E6) / (ic1mean/sp2_air)/ 3.11;



     cout << id << " " <<sp2_air << " " << ic1mean/sp2_air << " " << intcorr << endl;
     // cout << id <<" " << sp2_ps << " " <<signalmean/(Intensity/1.0E6)/(ic1mean/sp_air) << " " << signalmeanerror/(Intensity/1.0E6)/(ic1mean/sp_air) << endl;

     ic1energyfile << sp2_air << " " << ic1mean *intcorr/(Intensity/1.E6) << " " << (ic1meanerror/ic1mean + 0.01)*ic1mean*intcorr/(Intensity/1.E6) <<  " " << Filename << endl;
     //  ic2energyfile << sp2_air << " " << ic2mean / (Intensity/1.0E6) / (0.659869 + 1.50842 * sp2_air) << " " << ic2meanerror/sp_air <<  " " << Filename << endl;

     beamenergyfile << sp2_ps << " " <<  signalmean*intcorr/(Intensity/1.E6) << " " << (signalmeanerror/signalmean + 0.01)*signalmean*intcorr/(Intensity/1.E6)<<   endl;
     beamenergyfile_beta << beta << " " << signalmean*intcorr/(Intensity/1.E6)/sp2_ps << " " << (signalmeanerror/signalmean+0.01) * signalmean*intcorr/(Intensity/1.E6)/sp2_ps <<   endl;

     beamenergyfile_iccorr << sp2_ps << " " << (ic_beam_ratio*sp2_air/sp2_ps)/84.5 << " " << (ic_beam_ratioerror*sp2_air/sp2_ps)/84.5  <<   endl;

     ic2energyfile << sp2_air << " " << icbpmcorrelation << endl;
     noisefile << sp2_ps << " " << noisemean << " " << noiseRMS << endl;
     focusfile << sp2_ps << " " << focusmean*0.8 << " " << focusRMS*0.8 << endl;
     focusHITfile << sp2_ps << " " << F1 <<  endl;
     skewfile << sp2_ps << " " << skewmean << " " << skewRMS << endl;
     kurtfile << sp2_ps << " " << kurtmean << " " << kurtRMS << endl;
     focusFitfile << sp2_ps << " " << focusFitmean*0.8 << " " << focusFitRMS*0.8 << endl;
     chi2Fitfile << sp2_ps << " " << chi2Fitmean << " " << chi2FitRMS << endl;
     peakFitfile << sp2_ps << " " << peakFitmean << " " << peakFitRMS*0.8 << endl;






     //  h_beamSignal_1->Draw("");
     // c1->SaveAs(Form("figs/h_beamsignal_%i.pdf",nfiles));
     // c1->Destructor();
   
     // f->Close();
     outfile->Write();
     outfile->Close();
     file->Close();
     in >>  EList >> Energy >> F1 >> Intensity >> SP >> Filename >> id;
     //  cout <<  EList << Energy << F1 << Intensity << SP << Filename << id << endl;
     nfiles++;
     
   }
   ic1energyfile.close();
   ic2energyfile.close();

   beamenergyfile.close();
   beamenergyfile_iccorr.close();
   beamenergyfile_beta.close();
   noisefile.close();
   focusfile.close();
   focusHITfile.close();
   skewfile.close();
   kurtfile.close();
   in.close();
   focusFitfile.close();
   chi2Fitfile.close();
  return 0;
}
