//////////////////////////////////////////////////////////
// This class has been automatically generated on
// Tue Sep 12 15:40:57 2017 by ROOT version 5.34/32
// from TTree t/t
// found on file: ../../HIT_26-11-2016/with_timestamp/pin/PiN_run1.root
//////////////////////////////////////////////////////////

#ifndef analyse2_h
#define analyse2_h

#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
#include <TTree.h>
#include <stdio.h>
#include <TH2D.h>
#include <TH1D.h>
#include <TProfile.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TMath.h>
#include <vector>
#include <utility>
#include <TString.h>
#include <TDirectory.h>
#include <TString.h>
#include <TVectorD.h>
#include <TGraph.h>
#include <TGraphErrors.h>
#include <cmath>
#include <TPaveStats.h>
#include <TText.h>
#include <TStyle.h>
#include <TObjArray.h>
#include <TLegend.h>
#include <TFitResult.h>
#include <gsl/gsl_statistics.h>
#include <math.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_fft_complex.h>


using namespace std;

// Header file for the classes stored in the TTree if any.

// Fixed size dimensions of array or collections stored in the TTree if any.

class analyse2 {
 


public :
   TTree          *fChain;   //!pointer to the analyzed TTree or TChain
   Int_t           fCurrent; //!current Tree number in a TChain
   TTree *data;
   TTree *newdata;
   // Declaration of leaf types
   Double_t        time;
   Double_t        event_id;
   Double_t        sync_out;
   Double_t        sync_in;
   Double_t        data_ok;
   Double_t        led_voltage;
   Double_t        current;
   Double_t        ch00;
   Double_t        ch01;
   Double_t        ch02;
   Double_t        ch03;
   Double_t        ch04;
   Double_t        ch05;
   Double_t        ch06;
   Double_t        ch07;
   Double_t        ch08;
   Double_t        ch09;
   Double_t        ch10;
   Double_t        ch11;
   Double_t        ch12;
   Double_t        ch13;
   Double_t        ch14;
   Double_t        ch15;
   Double_t        ch16;
   Double_t        ch17;
   Double_t        ch18;
   Double_t        ch19;
   Double_t        ch20;
   Double_t        ch21;
   Double_t        ch22;
   Double_t        ch23;
   Double_t        ch24;
   Double_t        ch25;
   Double_t        ch26;
   Double_t        ch27;
   Double_t        ch28;
   Double_t        ch29;
   Double_t        ch30;
   Double_t        ch31;
   Double_t        ch32;
   Double_t        ch33;
   Double_t        ch34;
   Double_t        ch35;
   Double_t        ch36;
   Double_t        ch37;
   Double_t        ch38;
   Double_t        ch39;
   Double_t        ch40;
   Double_t        ch41;
   Double_t        ch42;
   Double_t        ch43;
   Double_t        ch44;
   Double_t        ch45;
   Double_t        ch46;
   Double_t        ch47;
   Double_t        ch48;
   Double_t        ch49;
   Double_t        ch50;
   Double_t        ch51;
   Double_t        ch52;
   Double_t        ch53;
   Double_t        ch54;
   Double_t        ch55;
   Double_t        ch56;
   Double_t        ch57;
   Double_t        ch58;
   Double_t        ch59;
   Double_t        ch60;
   Double_t        ch61;
   Double_t        ch62;
   Double_t        ch63;
   Double_t        ic1;
   Double_t        ic2;
   Double_t        mw1_focusx;
   Double_t        mw1_focusy;
   Double_t        mw2_focusx;
   Double_t        mw2_focusy;
   Double_t        mw1_posx;
   Double_t        mw1_posy;
   Double_t        mw2_posx;
   Double_t        mw2_posy;

   // List of branches
   TBranch        *b_time;   //!
   TBranch        *b_event_id;   //!
   TBranch        *b_sync_out;   //!
   TBranch        *b_sync_in;   //!
   TBranch        *b_data_ok;   //!
   TBranch        *b_led_voltage;   //!
   TBranch        *b_current;   //!
   TBranch        *b_ch00;   //!
   TBranch        *b_ch01;   //!
   TBranch        *b_ch02;   //!
   TBranch        *b_ch03;   //!
   TBranch        *b_ch04;   //!
   TBranch        *b_ch05;   //!
   TBranch        *b_ch06;   //!
   TBranch        *b_ch07;   //!
   TBranch        *b_ch08;   //!
   TBranch        *b_ch09;   //!
   TBranch        *b_ch10;   //!
   TBranch        *b_ch11;   //!
   TBranch        *b_ch12;   //!
   TBranch        *b_ch13;   //!
   TBranch        *b_ch14;   //!
   TBranch        *b_ch15;   //!
   TBranch        *b_ch16;   //!
   TBranch        *b_ch17;   //!
   TBranch        *b_ch18;   //!
   TBranch        *b_ch19;   //!
   TBranch        *b_ch20;   //!
   TBranch        *b_ch21;   //!
   TBranch        *b_ch22;   //!
   TBranch        *b_ch23;   //!
   TBranch        *b_ch24;   //!
   TBranch        *b_ch25;   //!
   TBranch        *b_ch26;   //!
   TBranch        *b_ch27;   //!
   TBranch        *b_ch28;   //!
   TBranch        *b_ch29;   //!
   TBranch        *b_ch30;   //!
   TBranch        *b_ch31;   //!
   TBranch        *b_ch32;   //!
   TBranch        *b_ch33;   //!
   TBranch        *b_ch34;   //!
   TBranch        *b_ch35;   //!
   TBranch        *b_ch36;   //!
   TBranch        *b_ch37;   //!
   TBranch        *b_ch38;   //!
   TBranch        *b_ch39;   //!
   TBranch        *b_ch40;   //!
   TBranch        *b_ch41;   //!
   TBranch        *b_ch42;   //!
   TBranch        *b_ch43;   //!
   TBranch        *b_ch44;   //!
   TBranch        *b_ch45;   //!
   TBranch        *b_ch46;   //!
   TBranch        *b_ch47;   //!
   TBranch        *b_ch48;   //!
   TBranch        *b_ch49;   //!
   TBranch        *b_ch50;   //!
   TBranch        *b_ch51;   //!
   TBranch        *b_ch52;   //!
   TBranch        *b_ch53;   //!
   TBranch        *b_ch54;   //!
   TBranch        *b_ch55;   //!
   TBranch        *b_ch56;   //!
   TBranch        *b_ch57;   //!
   TBranch        *b_ch58;   //!
   TBranch        *b_ch59;   //!
   TBranch        *b_ch60;   //!
   TBranch        *b_ch61;   //!
   TBranch        *b_ch62;   //!
   TBranch        *b_ch63;   //!
   TBranch        *b_ic1;   //!
   TBranch        *b_ic2;   //!
   TBranch        *b_mw1_focusx;   //!
   TBranch        *b_mw1_focusy;   //!
   TBranch        *b_mw2_focusx;   //!
   TBranch        *b_mw2_focusy;   //!
   TBranch        *b_mw1_posx;   //!
   TBranch        *b_mw1_posy;   //!
   TBranch        *b_mw2_posx;   //!
   TBranch        *b_mw2_posy;   //!

   char *file;
   TFile *fileIn;
   TFile *fileOut;
   TObjArray objectArray;
   TBranch        *b_channels[64];
   TBranch        *b_baseline[64];
   double channels[64];
   double channelamp_smooth[64];
   
   double baseline[64];
   double channellist[64];
   double errorx[64];
   double errory[64];

   TBranch *b_beamNumX_1;
   TBranch *b_beamPosX_1;
   TBranch *b_beamFocusX_1;
   TBranch *b_beamSignal_1;
   TBranch *b_beamSidebandNoise_1;

   TBranch *b_beamSkewX_1;
   TBranch *b_beamKurtX_1;
   TBranch *b_beamPosX_fit;
   TBranch *b_beamFocusX_fit;
   TBranch *b_beamChi2_fit;
   TBranch *b_beamPeakX_fit;
   TBranch *b_beamPosX_fit2;
   TBranch *b_beamFocusX_fit2;
   TBranch *b_beamFocus2X_fit2;
   TBranch *b_beamChi2_fit2;
   TBranch *b_beamPeakX_fit2;
   TBranch *b_beamPeak2X_fit2;

   TBranch        *b_ic1_1;   //!
   TBranch        *b_ic2_1;   //!
   TBranch        *b_mw1_focusx_1;   //!
   TBranch        *b_mw1_focusy_1;   //!
   TBranch        *b_mw2_focusx_1;   //!
   TBranch        *b_mw2_focusy_1;   //!
   TBranch        *b_mw1_posx_1;   //!
   TBranch        *b_mw1_posy_1;   //!
   TBranch        *b_mw2_posx_1;   //!
   TBranch        *b_mw2_posy_1;   //!
   TBranch        *b_baseline_integral;
   TBranch        *b_time_1;   //!
   TBranch        *b_eventid_1;   //!
   TBranch        *b_rollingavg;   //!
   TBranch        *b_beamon;   //!

   double time_1;
   double ic1_1;
   double ic2_1;
   double mw1_focusx_1;
   double mw2_focusx_1;
   double mw2_posx_1;
   double mw1_posx_1;
   double mw1_focusy_1;
   double mw2_focusy_1;
   double mw2_posy_1;
   double mw1_posy_1;

   double beamNumX_1;
   double beamPosX_1;
   double beamFocusX_1;
   double beamSignal_1;
   double beamSidebandNoise_1;

   double beamSkewX_1;
   double beamKurtX_1;
   double baseline_integral;
   double chargeintegral;
   double timeintegral;
   double eventid_1;
   double rollingavg;
   int beamon;

   double beamPosX_fit;
   double beamFocusX_fit;
   double beamChi2_fit;
   double beamPeakX_fit;
   double beamPosX_fit2;
   double beamFocusX_fit2;
   double beamFocus2X_fit2;
   double beamChi2_fit2;
   double beamPeakX_fit2;
   double beamPeak2X_fit2;

   analyse2(TTree *tree=0);
   virtual ~analyse2();
   virtual Int_t    Cut(Long64_t entry);
   virtual Int_t    GetEntry(Long64_t entry);
   virtual Long64_t LoadTree(Long64_t entry);
   virtual void     Init(TTree *tree);
   virtual void     Loop();
   virtual Bool_t   Notify();
   virtual void     Show(Long64_t entry = -1);

  double channelWidth;



  void Initialize(const char *dirname, const char *filename, int baselineEvents = 1000, int prelimEvents = 10000, double beamLevel = 0.1, bool firstFibermat = true, double readOutFrequency = 1000., int integrationTime = 100);
  void Baseline(bool useFirstEvents, int nBaselineEvents, int StartEvent, bool run50hz);
  void Save();
  void Close();
  double * FFTsmoothing(double arr[]);

  // double RollingAverage(const int length, double newdata);
 

  TH2D * th2d_mw1_beamPosX;
  TH2D * th2d_ic1_beamSignal;
  TH1D * th1d_beamSignal_ic1ratio;
  TH2D * th2d_beamSignal_channel;
  TH2D * th2d_bkg_channel;
  TH1D * th1d_baseline;
  TH1D * th1d_baselinesub;
  TH1D * th1d_chbaseline;
  TH1D * th1d_chbaselinesub;
  TH2D * th2d_fitdiff_channel;
  TH2D * th2d_fit2diff_channel;
  TH2D * th2d_AmpFFT_channel;
  TH2D * th2d_PhaseFFT_channel;

  TFitResultPtr bkgfitResult;
  Double_t bkgfitPar0[65];
  Double_t bkgfitPar1[65];
  Double_t bkgfitPar2[65];
  Double_t bkgfitPar3[65];
  Double_t bkgfitPar4[65];

};

#endif

#ifdef analyse2_cxx
analyse2::analyse2(TTree *tree) : fChain(0) 
{
// if parameter tree is not specified (or zero), connect the file
// used to generate this class and read the Tree.
   if (tree == 0) {
     cerr << "no TTree found." << endl;
   }
   Init(tree);
}

analyse2::~analyse2()
{
   if (!fChain) return;
   delete fChain->GetCurrentFile();
}

Int_t analyse2::GetEntry(Long64_t entry)
{
// Read contents of entry.
   if (!fChain) return 0;
   return fChain->GetEntry(entry);
}
Long64_t analyse2::LoadTree(Long64_t entry)
{
// Set the environment to read one entry
   if (!fChain) return -5;
   Long64_t centry = fChain->LoadTree(entry);
   if (centry < 0) return centry;
   if (fChain->GetTreeNumber() != fCurrent) {
      fCurrent = fChain->GetTreeNumber();
      Notify();
   }
   return centry;
}

void analyse2::Init(TTree *tree)
{
   // The Init() function is called when the selector needs to initialize
   // a new tree or chain. Typically here the branch addresses and branch
   // pointers of the tree will be set.
   // It is normally not necessary to make changes to the generated
   // code, but the routine can be extended by the user if needed.
   // Init() will be called many times when running on PROOF
   // (once per file to be processed).

   // Set branch addresses and branch pointers
   if (!tree) return;
   fChain = tree;
   fCurrent = -1;
   fChain->SetMakeClass(1);

   fChain->SetBranchAddress("time", &time, &b_time);
   fChain->SetBranchAddress("event_id", &event_id, &b_event_id);
   fChain->SetBranchAddress("sync_out", &sync_out, &b_sync_out);
   fChain->SetBranchAddress("sync_in", &sync_in, &b_sync_in);
   fChain->SetBranchAddress("data_ok", &data_ok, &b_data_ok);
   fChain->SetBranchAddress("led_voltage", &led_voltage, &b_led_voltage);
   fChain->SetBranchAddress("current", &current, &b_current);
   fChain->SetBranchAddress("ch00", &ch00, &b_ch00);
   fChain->SetBranchAddress("ch01", &ch01, &b_ch01);
   fChain->SetBranchAddress("ch02", &ch02, &b_ch02);
   fChain->SetBranchAddress("ch03", &ch03, &b_ch03);
   fChain->SetBranchAddress("ch04", &ch04, &b_ch04);
   fChain->SetBranchAddress("ch05", &ch05, &b_ch05);
   fChain->SetBranchAddress("ch06", &ch06, &b_ch06);
   fChain->SetBranchAddress("ch07", &ch07, &b_ch07);
   fChain->SetBranchAddress("ch08", &ch08, &b_ch08);
   fChain->SetBranchAddress("ch09", &ch09, &b_ch09);
   fChain->SetBranchAddress("ch10", &ch10, &b_ch10);
   fChain->SetBranchAddress("ch11", &ch11, &b_ch11);
   fChain->SetBranchAddress("ch12", &ch12, &b_ch12);
   fChain->SetBranchAddress("ch13", &ch13, &b_ch13);
   fChain->SetBranchAddress("ch14", &ch14, &b_ch14);
   fChain->SetBranchAddress("ch15", &ch15, &b_ch15);
   fChain->SetBranchAddress("ch16", &ch16, &b_ch16);
   fChain->SetBranchAddress("ch17", &ch17, &b_ch17);
   fChain->SetBranchAddress("ch18", &ch18, &b_ch18);
   fChain->SetBranchAddress("ch19", &ch19, &b_ch19);
   fChain->SetBranchAddress("ch20", &ch20, &b_ch20);
   fChain->SetBranchAddress("ch21", &ch21, &b_ch21);
   fChain->SetBranchAddress("ch22", &ch22, &b_ch22);
   fChain->SetBranchAddress("ch23", &ch23, &b_ch23);
   fChain->SetBranchAddress("ch24", &ch24, &b_ch24);
   fChain->SetBranchAddress("ch25", &ch25, &b_ch25);
   fChain->SetBranchAddress("ch26", &ch26, &b_ch26);
   fChain->SetBranchAddress("ch27", &ch27, &b_ch27);
   fChain->SetBranchAddress("ch28", &ch28, &b_ch28);
   fChain->SetBranchAddress("ch29", &ch29, &b_ch29);
   fChain->SetBranchAddress("ch30", &ch30, &b_ch30);
   fChain->SetBranchAddress("ch31", &ch31, &b_ch31);
   fChain->SetBranchAddress("ch32", &ch32, &b_ch32);
   fChain->SetBranchAddress("ch33", &ch33, &b_ch33);
   fChain->SetBranchAddress("ch34", &ch34, &b_ch34);
   fChain->SetBranchAddress("ch35", &ch35, &b_ch35);
   fChain->SetBranchAddress("ch36", &ch36, &b_ch36);
   fChain->SetBranchAddress("ch37", &ch37, &b_ch37);
   fChain->SetBranchAddress("ch38", &ch38, &b_ch38);
   fChain->SetBranchAddress("ch39", &ch39, &b_ch39);
   fChain->SetBranchAddress("ch40", &ch40, &b_ch40);
   fChain->SetBranchAddress("ch41", &ch41, &b_ch41);
   fChain->SetBranchAddress("ch42", &ch42, &b_ch42);
   fChain->SetBranchAddress("ch43", &ch43, &b_ch43);
   fChain->SetBranchAddress("ch44", &ch44, &b_ch44);
   fChain->SetBranchAddress("ch45", &ch45, &b_ch45);
   fChain->SetBranchAddress("ch46", &ch46, &b_ch46);
   fChain->SetBranchAddress("ch47", &ch47, &b_ch47);
   fChain->SetBranchAddress("ch48", &ch48, &b_ch48);
   fChain->SetBranchAddress("ch49", &ch49, &b_ch49);
   fChain->SetBranchAddress("ch50", &ch50, &b_ch50);
   fChain->SetBranchAddress("ch51", &ch51, &b_ch51);
   fChain->SetBranchAddress("ch52", &ch52, &b_ch52);
   fChain->SetBranchAddress("ch53", &ch53, &b_ch53);
   fChain->SetBranchAddress("ch54", &ch54, &b_ch54);
   fChain->SetBranchAddress("ch55", &ch55, &b_ch55);
   fChain->SetBranchAddress("ch56", &ch56, &b_ch56);
   fChain->SetBranchAddress("ch57", &ch57, &b_ch57);
   fChain->SetBranchAddress("ch58", &ch58, &b_ch58);
   fChain->SetBranchAddress("ch59", &ch59, &b_ch59);
   fChain->SetBranchAddress("ch60", &ch60, &b_ch60);
   fChain->SetBranchAddress("ch61", &ch61, &b_ch61);
   fChain->SetBranchAddress("ch62", &ch62, &b_ch62);
   fChain->SetBranchAddress("ch63", &ch63, &b_ch63);
   fChain->SetBranchAddress("ic1", &ic1, &b_ic1);
   fChain->SetBranchAddress("ic2", &ic2, &b_ic2);
   fChain->SetBranchAddress("mw1_focusx", &mw1_focusx, &b_mw1_focusx);
   fChain->SetBranchAddress("mw1_focusy", &mw1_focusy, &b_mw1_focusy);
   fChain->SetBranchAddress("mw2_focusx", &mw2_focusx, &b_mw2_focusx);
   fChain->SetBranchAddress("mw2_focusy", &mw2_focusy, &b_mw2_focusy);
   fChain->SetBranchAddress("mw1_posx", &mw1_posx, &b_mw1_posx);
   fChain->SetBranchAddress("mw1_posy", &mw1_posy, &b_mw1_posy);
   fChain->SetBranchAddress("mw2_posx", &mw2_posx, &b_mw2_posx);
   fChain->SetBranchAddress("mw2_posy", &mw2_posy, &b_mw2_posy);

   //   v->ResizeTo(10);

   Notify();
}

Bool_t analyse2::Notify()
{
   // The Notify() function is called when a new file is opened. This
   // can be either for a new TTree in a TChain or when when a new TTree
   // is started when using PROOF. It is normally not necessary to make changes
   // to the generated code, but the routine can be extended by the
   // user if needed. The return value is currently not used.

   return kTRUE;
}

void analyse2::Show(Long64_t entry)
{
// Print contents of entry.
// If entry is not specified, print current entry
   if (!fChain) return;
   fChain->Show(entry);

}
Int_t analyse2::Cut(Long64_t entry)
{
// This function may be called from Loop.
// returns  1 if entry is accepted.
// returns -1 otherwise.
   return 1;
}

void analyse2::Initialize(const char *dirname, const char *filename, int baselineEvents, int prelimEvents, double beamLevel, bool firstFibermat, double readOutFrequency, int integrationTime)
{

  TString fn = TString(filename);
  TString dn = TString(dirname);
  channelWidth = 0.8;
   
  TString inName = dn + "pin/" + fn;
  fileIn = new TFile(inName, "READ");
  fileIn->GetObject("t", fChain);
  fChain->Print();
  Init(fChain);
  TString outname = filename;
  outname.Insert(0, "SAVE_");
  outname.Insert(0, dirname);
  fileOut = new TFile(outname.Data(), "RECREATE");
  newdata = new TTree("newdata", "newdata");


  for (int n = 0; n < 64; n++)
  {
    baseline[n] = 0.;
    channellist[n] = double(n);
    errorx[n] = 0.0;
    errory[n] = 7.0;
    char bname[20];
   
      sprintf(bname, "ch%02d", n);
      b_channels[n] = fChain->GetBranch(bname);
      b_channels[n]->SetAddress(&channels[n]);
  }
  b_eventid_1 = newdata->Branch("eventid_1", &eventid_1);

  b_beamNumX_1 = newdata->Branch("beamNumX_1", &beamNumX_1);
  b_beamPosX_1 = newdata->Branch("beamPosX_1", &beamPosX_1);
  b_beamFocusX_1 = newdata->Branch("beamFocusX_1", &beamFocusX_1);
  b_beamSignal_1 = newdata->Branch("beamSignal_1", &beamSignal_1);
  b_beamSidebandNoise_1 = newdata->Branch("beamSidebandNoise_1", &beamSidebandNoise_1);

  b_beamSkewX_1 = newdata->Branch("beamSkewX_1", &beamSkewX_1);
  b_beamKurtX_1 = newdata->Branch("beamKurtX_1", &beamKurtX_1);
  b_beamPosX_fit = newdata->Branch("beamPosX_fit", &beamPosX_fit);
  b_beamFocusX_fit = newdata->Branch("beamFocusX_fit", &beamFocusX_fit);
  b_beamChi2_fit = newdata->Branch("beamChi2_fit", &beamChi2_fit);
  b_beamPeakX_fit = newdata->Branch("beamPeakX_fit", &beamPeakX_fit);
 
  b_beamPosX_fit2 = newdata->Branch("beamPosX_fit2", &beamPosX_fit2);
  b_beamFocusX_fit2 = newdata->Branch("beamFocusX_fit2", &beamFocusX_fit2);
  b_beamFocus2X_fit2 = newdata->Branch("beamFocus2X_fit2", &beamFocus2X_fit2);
  b_beamChi2_fit2 = newdata->Branch("beamChi2_fit2", &beamChi2_fit2);
  b_beamPeakX_fit2 = newdata->Branch("beamPeakX_fit2", &beamPeakX_fit2);
  b_beamPeak2X_fit2 = newdata->Branch("beamPeak2X_fit2", &beamPeak2X_fit2);

  b_ic1_1 = newdata->Branch("ic1_1", &ic1_1);
  b_ic2_1 = newdata->Branch("ic2_1", &ic2_1);
  b_mw1_focusx_1 = newdata->Branch("mw1_focusx_1", &mw1_focusx_1);
  b_mw1_posx_1 = newdata->Branch("mw1_posx_1", &mw1_posx_1);
  b_mw2_focusx_1 = newdata->Branch("mw2_focusx_1", &mw2_focusx_1);
  b_mw2_posx_1 = newdata->Branch("mw2_posx_1", &mw2_posx_1);


  b_mw1_focusy_1 = newdata->Branch("mw1_focusy_1", &mw1_focusy_1);
  b_mw1_posy_1 = newdata->Branch("mw1_posy_1", &mw1_posy_1);
  b_mw2_focusy_1 = newdata->Branch("mw2_focusy_1", &mw2_focusy_1);
  b_mw2_posy_1 = newdata->Branch("mw2_posy_1", &mw2_posy_1);
  b_rollingavg = newdata->Branch("rollingavg", &rollingavg);
  b_beamon = newdata->Branch("beamon", &beamon);


  b_time_1 = newdata->Branch("time_1", &time_1);
  //histograms;
  th2d_mw1_beamPosX = new TH2D("th2d_mw1_beamPosX","th2d_mw1_beamPosX",1000,0,64,1000,0,60);
  th2d_ic1_beamSignal = new TH2D("th2d_ic1_beamSignal","th2d_ic1_beamSignal",500,0,500,500,0,100000);
  th1d_beamSignal_ic1ratio = new TH1D("th1d_beamSignal_ic1ratio","th1d_beamSignal_ic1ratio",500,0,500.);
  th2d_beamSignal_channel = new TH2D("th2d_beamSignal_channel","th2d_beamSignal_channel",65,-0.5,64.5,5100,-1000,10000);
  th2d_fitdiff_channel = new TH2D("th2d_fitdiff_channel","th2d_fitdiff_channel",65,-0.5,64.5,5100,-10000,1000);
   th2d_fit2diff_channel = new TH2D("th2d_fit2diff_channel","th2d_fit2diff_channel",65,-0.5,64.5,5100,-10000,1000);

th2d_bkg_channel = new TH2D("th2d_bkg_channel","th2d_bkg_channel",65,-0.5,64.5,500,-500,500);

  th1d_baseline = new TH1D("th1d_baseline","th1d_baseline",500,-1500,1500.);
  th1d_baselinesub = new TH1D("th1d_baselinesub","th1d_baselinesub",500,-1500,1500.);
 th1d_chbaseline = new TH1D("th1d_chbaseline","th1d_chbaseline",2100,-100,1000.);
  th1d_chbaselinesub = new TH1D("th1d_chbaselinesub","th1d_chbaselinesub",200,-100,100.);
  th2d_AmpFFT_channel = new TH2D("th2d_AmpFFT_channel","th2d_AmpFFT_channel",65,-0.5,64.5,500,0,1000);
  th2d_PhaseFFT_channel = new TH2D("th2d_PhaseFFT_channel","th2d_PhaseFFT_channel",65,-0.5,64.5,100,-2,2);

}




void analyse2::Baseline(bool useFirstEvents,  const int nBaselineEvents, int startevent, bool run50hz)
{
  Long64_t nevents = fChain->GetEntriesFast();
  baseline_integral = 0.;
  // use the first/last nBaselineEvents events to calculate the average/baseline
  cout << "Start background subtraction event:" << startevent << endl;
  const int numbaseline =  3500;
  Double_t channelamp[numbaseline];
  Double_t basetime[numbaseline] = {0.};
  
  TGraph * g1;
  TF1 * fitfunc = new TF1("fitfunc","[0]+[1]*TMath::Cos(x*[2]*(2*3.14159)+[3])");
  fitfunc->SetParameters( 0.0, 10.0, 0.05, 0.0 );
  fitfunc->FixParameter(2,0.05);

 fChain->GetEvent(1);
  Double_t basetimeoffsetzero = time;

  fChain->GetEvent(startevent+numbaseline);
  Double_t basetimeoffset = time-basetimeoffsetzero;
  
  fChain->GetEvent(startevent);
  Double_t basetimeoffsetstart = time-basetimeoffsetzero;
  Int_t counter = 0;
  char bname[20];
  for (int ch = 0; ch < 64; ch++)
      {
	baseline[ch] =0.;
      }

  if (!useFirstEvents)
  { // last
    for (int i =  nevents- numbaseline; i <   nevents; i++)
    {
      fChain->GetEvent(i);
      for (int ch = 0; ch < 64; ch++)
      {
	if (channels[ch]>-100) baseline[ch] += channels[ch] / double(numbaseline);
	if (channels[ch]>-100)	baseline_integral +=baseline[ch];
	th1d_chbaseline->Fill(channels[ch]);
      }
      
    }
    //  cout << "baseline int: " << 	baseline_integral << endl;
  }
  else
  {
    for (int i = startevent ; i <=  startevent+  numbaseline; i++)
    {
      fChain->GetEvent(i);
      for (int ch = 0; ch < 64; ch++)
      {
       	if (channels[ch]>-100) baseline[ch] += channels[ch] / double(numbaseline);
	if (channels[ch]>-100)	baseline_integral +=baseline[ch];
	th1d_chbaseline->Fill(channels[ch]);
      }
      //    cout << "baseline int: " << 	baseline_integral << endl;
    }
  }
  
  if (run50hz){
     
   ///fit a 50Hz background noise to each channel
   for (int ch = 0; ch < 64; ch++)
    {
      counter = 0;
      for (int i = startevent ; i < startevent+numbaseline; i++)
	{
	  fChain->GetEvent(i);
	  //      for (int ch = 0; ch < 64; ch++)
	  //{
	  channelamp[counter]= channels[ch]- baseline[ch];
	  //}
	  basetime[counter] = time-basetimeoffsetzero;
	  counter++;
	}
      
      
      g1 = new TGraph(numbaseline,basetime,channelamp);
      ///////finished here. 1) need to fit the baseline to a Cosine function 2) return 3 parameters per channel. 50 Hz is fixed.
      bkgfitResult = g1->Fit(fitfunc,"QSR","",basetimeoffsetstart,basetimeoffset );

      
      bkgfitPar0[ch] =  bkgfitResult->Parameter(0);
      bkgfitPar1[ch] =  bkgfitResult->Parameter(1);
      bkgfitPar2[ch] =  bkgfitResult->Parameter(2);
      bkgfitPar3[ch] =  bkgfitResult->Parameter(3);

      sprintf(bname, "bkg_ch%02d_graph", ch);
      g1->SetTitle(bname);
      g1->SetName(bname);

      //fitResult->Print("V");
      // bkgfitResult->Write();  
      g1->Write();


    } //end for (int ch = ...
 for (int ch = 0; ch < 64; ch++)
    {
      counter = 0;
      fitfunc->SetParameters( bkgfitPar0[ch], bkgfitPar1[ch], bkgfitPar2[ch], bkgfitPar3[ch]);
      for (Long64_t i = startevent ; i <startevent+ numbaseline; i++)
	{
	  fChain->GetEvent(i);
	  channelamp[counter] = channels[ch]- baseline[ch]- fitfunc->Eval(time-basetimeoffsetzero);
	  th1d_chbaselinesub->Fill(channelamp[counter]);
	  counter++;
	  th2d_bkg_channel->Fill(ch,channelamp[counter]);
	}
    }
 
  Double_t channelampsum[numbaseline] = {0.};
  

  
  counter = 0;
      ///fit a 50Hz background noise to the sum of all channels

  for (Long64_t i = startevent ; i <startevent+ numbaseline; i++)
    {
      fChain->GetEvent(i);
      channelampsum[counter]=0.;     
      for (int ch = 0; ch < 64; ch++){
	if (channels[ch]>-100 && baseline[ch]>-100) channelampsum[counter] +=  channels[ch] - baseline[ch]; //integrate the signal
	
      }

      basetime[counter] = (time-basetimeoffsetzero);
      counter++;
    }
  
  TGraph * g2 =  new TGraph(counter,basetime,channelampsum);
  TF1 * fitfunc2 = new TF1("fitfunc2","[0]+[1]*TMath::Cos(x*[2]*(2*3.14159)+[3])");
  fitfunc2->SetParameters( 5120.0, 450.0, 0.05, 0.0 );
  // fitfunc2->SetParLimits(1,0.,1000.);
    fitfunc2->FixParameter(2,0.05);
  
  TFitResultPtr sumbkgfitResult = g2->Fit(fitfunc2,"QRS","", basetimeoffsetstart, basetimeoffset);
  g2->SetName("commonmodenoise"); g2->SetTitle("commonmodenoise");
  g2->Write();
  sumbkgfitResult->Write();
  fitfunc2->Write();
  bkgfitPar0[64] =  fitfunc2->GetParameter(0);
  bkgfitPar1[64] =  fitfunc2->GetParameter(1);
  bkgfitPar2[64] =  fitfunc2->GetParameter(2);
  bkgfitPar3[64] =   fitfunc2->GetParameter(3); 
  
  counter=0;
for (Long64_t i = startevent ; i <startevent+ numbaseline; i++)
    {
      fChain->GetEvent(i);
      channelampsum[counter] -= fitfunc2->Eval(time-basetimeoffsetzero);
      th1d_baselinesub->Fill(channelampsum[counter]);
      counter++;

    }
 th1d_baseline->Write();
 th1d_baselinesub->Write();
 th1d_chbaseline->Write();
 th1d_chbaselinesub->Write();
  TGraph * g3 =  new TGraph(counter,basetime,channelampsum);
  g3->SetName("commonmodenoisesub"); g2->SetTitle("commonmodenoisesub");
  g3->Write();
  }
}


void analyse2::Save()
{
  //fileIn->Close();
  //fileOut->cd();
  newdata->AutoSave();
 
}


void analyse2::Close()
{
  fileIn->Close();
  fileOut->Close();
  if(fChain) delete fChain->GetCurrentFile();
}



#define REAL(z,i) ((z)[2*(i)])
#define IMAG(z,i) ((z)[2*(i)+1])

double  * analyse2::FFTsmoothing(double arr[])
{
 
  int i; double data[2*64];
  double channel[64];
  double RealInput[64];
  double ImagInput[64];
  double RealFFT[64];
  double ImagFFT[64];
  double AmpFFT[64];
  double PhaseFFT[64];


  double RealOutput[64];
  double ImagOutput[64];
 
  double avgnoiseAmpFFT = 0.;

  for (i = 0; i < 64; i++)
    {
       REAL(data,i) = arr[i]; IMAG(data,i) = 0.0;
    }

  // REAL(data,0) = 1.0;

  // for (i = 1; i <= 10; i++)
  //  {
  //     REAL(data,i) 1.0;
  // }
  for (i = 0; i < 64; i++)
    {
      channel[i] = i;
      RealInput[i] = REAL(data,i);
      ImagInput[i] =  IMAG(data,i);
      //   printf ("%d %e %e\n", i, REAL(data,i), IMAG(data,i));
   }
  //  printf ("\n");
  // TGraph * g1_input_real = new TGraph(64,channel,RealInput);
  // TGraph * g1_input_imag = new TGraph(64,channel,ImagInput);
  // g1_input_real->SetName("input_real"); g1_input_real->Write();
  //g1_input_imag->SetName("input_imag"); g1_input_imag->Write();

  //apply Fourier transform
  gsl_fft_complex_radix2_forward (data, 1, 64);

  for (i = 0; i < 64; i++)
    {
      //   printf ("%d %e %e\n", i,  REAL(data,i)/sqrt(64),  IMAG(data,i)/sqrt(64));
      RealFFT[i] = REAL(data,i)/sqrt(64);
      ImagFFT[i] = IMAG(data,i)/sqrt(64);

      AmpFFT[i] = sqrt(RealFFT[i]*RealFFT[i] +  ImagFFT[i]*ImagFFT[i]);
      PhaseFFT[i] = atan(ImagFFT[i]/RealFFT[i]);
      if (beamon){
	th2d_AmpFFT_channel->Fill(i,AmpFFT[i]);
	th2d_PhaseFFT_channel->Fill(i,PhaseFFT[i]);
      }
    }
  // printf ("\n");

  //find the average noise frequency amplitude
  for (i = 22; i < 32; i++){
    avgnoiseAmpFFT +=AmpFFT[i]/10;
  }

  //find where the signal frequency amplitude falls below noise;
  int cutchannel = 31;
 for (i = 0; i < 32; i++)
    {
      if (AmpFFT[i]<avgnoiseAmpFFT) {
	cutchannel = i;
	break;
      }
    }

  // TGraph * g1_FFT_real = new TGraph(64,channel,RealFFT);
  // TGraph * g1_FFT_imag = new TGraph(64,channel,ImagFFT);
  //g1_FFT_real->SetName("FFT_real"); g1_FFT_real->Write();
  // g1_FFT_imag->SetName("FFT_imag");g1_FFT_imag->Write();

  // TGraph * g1_FFT_amp = new TGraph(64,channel,AmpFFT);
  // TGraph * g1_FFT_phase = new TGraph(64,channel,PhaseFFT);
  // g1_FFT_amp->SetName("FFT_amp"); g1_FFT_amp->Write();
  //  g1_FFT_phase->SetName("FFT_phase");g1_FFT_phase->Write();


 //suppress channels that are more likely noise; the signal has a lower frequency than noise;
 for (i = cutchannel+2; i < 32; i++)
   {
     REAL(data,i) = 0.; 
     IMAG(data,i) = 0.;
     REAL(data,64-i) = 0.; 
     IMAG(data,64-i) = 0.;
   }
 //apply inverse Fourier transform
  gsl_fft_complex_radix2_inverse (data, 1, 64);
  for (i = 0; i < 64; i++)
    {
      // printf ("%d %e %e\n", i, REAL(data,i),  IMAG(data,i));
      RealOutput[i] = REAL(data,i);
      ImagOutput[i] = IMAG(data,i);
      arr[i] = RealOutput[i];
    }
  //printf ("\n");

  // TGraph * g1_output_real = new TGraph(64,channel,RealOutput);
  // TGraph * g1_output_imag = new TGraph(64,channel,ImagOutput);
  // g1_output_real->SetName("output_real");g1_output_real->Write();
  // g1_output_imag->SetName("output_imag");g1_output_imag->Write();

  return arr;
}

#endif // #ifdef analyse2_cxx
