#include "TROOT.h"
#include "Riostream.h"
#include "TF1.h"
#include "TH1.h"
#include "TMath.h"
#include "TFile.h"
#include "TNtuple.h"
#include "TGraph.h"
#include "TCanvas.h"


void CalPulseAnalizer(TString inputfile="CPScan.dat", TString outputfile="CPscan.root", const Int_t nlines=0, Int_t vfatnumber=0)
{

        // Preparing evironment and new rootfile
	gROOT->Reset();
	TFile *f = new TFile(outputfile,"RECREATE");

	// Reading the input data file
	ifstream in;
	in.open(inputfile);
	
	// Creating ntuple...
	Double_t VCal[nlines],VFAT0Counts[nlines],VFAT1Counts[nlines],VFAT2Counts[nlines],VFAT3Counts[nlines],VFAT4Counts[nlines],VFAT5Counts[nlines],VFAT6Counts[nlines],VFAT7Counts[nlines];
	TNtuple *CalPulse = new TNtuple("CalPulse","data from ascii file","VCal:VFAT0Counts:VFAT1Counts:VFAT2Counts:VFAT3Counts:VFAT4Counts:VFAT5Counts:VFAT6Counts:VFAT7Counts");
	
	// Initializing ranges
	Double_t MaxRangeVFAT0 = 255;
	Double_t MaxRangeVFAT1 = 255;
	Double_t MaxRangeVFAT2 = 255;
	Double_t MaxRangeVFAT3 = 255;
	Double_t MaxRangeVFAT4 = 255;
	Double_t MaxRangeVFAT5 = 255;
	Double_t MaxRangeVFAT6 = 255;
	Double_t MaxRangeVFAT7 = 255;

	Double_t MinRangeVFAT0 = 0;
	Double_t MinRangeVFAT1 = 0;
	Double_t MinRangeVFAT2 = 0;
	Double_t MinRangeVFAT3 = 0;
	Double_t MinRangeVFAT4 = 0;
	Double_t MinRangeVFAT5 = 0;
	Double_t MinRangeVFAT6 = 0;
	Double_t MinRangeVFAT7 = 0;

	// Setting flags
	Bool_t	MaxRange0=0;
	Bool_t	MaxRange1=0;
	Bool_t	MaxRange2=0;
	Bool_t	MaxRange3=0;
	Bool_t	MaxRange4=0;
	Bool_t	MaxRange5=0;
	Bool_t	MaxRange6=0;
	Bool_t	MaxRange7=0;

	Bool_t	MinRange0=0;
	Bool_t	MinRange1=0;
	Bool_t	MinRange2=0;
	Bool_t	MinRange3=0;
	Bool_t	MinRange4=0;
	Bool_t	MinRange5=0;
	Bool_t	MinRange6=0;
	Bool_t	MinRange7=0;

	Double_t MinPercent=0.15;

	Int_t Steps=0;
	
	for (Int_t i = 0; i < nlines; i++)
	{
		in >> VCal[i] >> VFAT0Counts[i] >> VFAT1Counts[i] >> VFAT2Counts[i] >> VFAT3Counts[i] >> VFAT4Counts[i] >> VFAT5Counts[i] >> VFAT6Counts[i] >> VFAT7Counts[i];
		
		// Setting the range for the fit around the mean value
		if (!MinRange0 && VFAT0Counts[i]>=MinPercent)
		{
			MinRangeVFAT0 = VCal[i];
			MinRange0 = 1;
		}
		if (!MinRange1 && VFAT1Counts[i]>=MinPercent)
		{
			MinRangeVFAT1 = VCal[i];
			MinRange1 = 1;
		}
		if (!MinRange2 && VFAT2Counts[i]>=MinPercent)
		{
			MinRangeVFAT2 = VCal[i];
			MinRange2 = 1;
		}
		if (!MinRange3 && VFAT3Counts[i]>=MinPercent)
		{
			MinRangeVFAT3 = VCal[i];
			MinRange3 = 1;
		}
		if (!MinRange4 && VFAT4Counts[i]>=MinPercent)
		{
			MinRangeVFAT4 = VCal[i];
			MinRange4 = 1;
		}
		if (!MinRange5 && VFAT5Counts[i]>=MinPercent)
		{
			MinRangeVFAT5 = VCal[i];
			MinRange5 = 1;
		}
		if (!MinRange6 && VFAT6Counts[i]>=MinPercent)
		{
			MinRangeVFAT6 = VCal[i];
			MinRange6 = 1;
		}
		if (!MinRange7 && VFAT7Counts[i]>=MinPercent)
		{
			MinRangeVFAT7 = VCal[i];
			MinRange7 = 1;
		}

	
		if (!MaxRange0 && VFAT0Counts[i]>=0.95)
		{
			MaxRangeVFAT0 = VCal[i];
			MaxRange0 = 1;
		}
		if (!MaxRange1 && VFAT1Counts[i]>=0.95)
		{
			MaxRangeVFAT1 = VCal[i];
			MaxRange1 = 1;
		}
		if (!MaxRange2 && VFAT2Counts[i]>=0.95)
		{
			MaxRangeVFAT2 = VCal[i];
			MaxRange2 = 1;
		}
		if (!MaxRange3 && VFAT3Counts[i]>=0.95)
		{
			MaxRangeVFAT3 = VCal[i];
			MaxRange3 = 1;
		}
		if (!MaxRange4 && VFAT4Counts[i]>=0.95)
		{
			MaxRangeVFAT4 = VCal[i];
			MaxRange4 = 1;
		}
		if (!MaxRange5 && VFAT5Counts[i]>=0.95)
		{
			MaxRangeVFAT5 = VCal[i];
			MaxRange5 = 1;
		}
		if (!MaxRange6 && VFAT6Counts[i]>=0.95)
		{
			MaxRangeVFAT6 = VCal[i];
			MaxRange6 = 1;
		}
		if (!MaxRange7 && VFAT7Counts[i]>=0.95)
		{
			MaxRangeVFAT7 = VCal[i];
			MaxRange7 = 1;
		}

		
		if (!in.good()) break;
		
		// Filling ntuple
		CalPulse->Fill(VCal[i],VFAT0Counts[i],VFAT1Counts[i],VFAT2Counts[i],VFAT3Counts[i],VFAT4Counts[i],VFAT5Counts[i],VFAT6Counts[i],VFAT7Counts[i]);
		Steps = i;
	}

	// Uncomment to print number of VCal steps found
	//	printf(" found %d points\n",Steps);
	in.close();


	TCanvas *c1 = new TCanvas ("c1","S-Curve Fit");
	
	// Plotting VFAT0 counts VS VCal steps
	TGraph *gr0 = new TGraph(Steps,VCal,VFAT0Counts);
	gr0->SetTitle("VFAT0 S-Curve");
	gr0->GetXaxis()->SetTitle("VCal [VFAT2 DAC step Bin]");
	gr0->GetYaxis()->SetTitle("Counts");

	// Plotting VFAT1 counts VS VCal steps
	TGraph *gr1 = new TGraph(Steps,VCal,VFAT1Counts);
	gr1->SetTitle("VFAT1 S-Curve");
	gr1->GetXaxis()->SetTitle("VCal [VFAT2 DAC step Bin]");
	gr1->GetYaxis()->SetTitle("Counts");

	// Plotting VFAT2 counts VS VCal steps
	TGraph *gr2 = new TGraph(Steps,VCal,VFAT2Counts);
	gr2->SetTitle("VFAT2 S-Curve");
	gr2->GetXaxis()->SetTitle("VCal [VFAT2 DAC step Bin]");
	gr2->GetYaxis()->SetTitle("Counts");
	
	// Plotting VFAT3 counts VS VCal steps
	TGraph *gr3 = new TGraph(Steps,VCal,VFAT3Counts);
	gr3->SetTitle("VFAT3 S-Curve");
	gr3->GetXaxis()->SetTitle("VCal [VFAT2 DAC step Bin]");
	gr3->GetYaxis()->SetTitle("Counts");

	// Plotting VFAT4 counts VS VCal steps
	TGraph *gr4 = new TGraph(Steps,VCal,VFAT4Counts);
	gr4->SetTitle("VFAT4 S-Curve");
	gr4->GetXaxis()->SetTitle("VCal [VFAT2 DAC step Bin]");
	gr4->GetYaxis()->SetTitle("Counts");

	// Plotting VFAT5 counts VS VCal steps
	TGraph *gr5 = new TGraph(Steps,VCal,VFAT5Counts);
	gr5->SetTitle("VFAT5 S-Curve");
	gr5->GetXaxis()->SetTitle("VCal [VFAT2 DAC step Bin]");
	gr5->GetYaxis()->SetTitle("Counts");

	// Plotting VFAT6 counts VS VCal steps
	TGraph *gr6 = new TGraph(Steps,VCal,VFAT6Counts);
	gr6->SetTitle("VFAT6 S-Curve");
	gr6->GetXaxis()->SetTitle("VCal [VFAT2 DAC step Bin]");
	gr6->GetYaxis()->SetTitle("Counts");

	// Plotting VFAT7 counts VS VCal steps
	TGraph *gr7 = new TGraph(Steps,VCal,VFAT7Counts);
	gr7->SetTitle("VFAT7 S-Curve");
	gr7->GetXaxis()->SetTitle("VCal [VFAT2 DAC step Bin]");
	gr7->GetYaxis()->SetTitle("Counts");

	// Defining fit function (= error function)
	TF1 *sigmoid = new TF1("sigmoid", "[0] * (1 + TMath::Erf( (x - [1])/[2]/1.41421356 )) / 2");
	sigmoid->SetParNames("Amplitude", "Mean", "Sigma");

	// Normalizing the sigmoid
	sigmoid->FixParameter(0, 1);

	// Setting fit parameters' ranges and initial values
	sigmoid->SetParameter(1, 100);
	sigmoid->SetParError(1, 0.1);
	sigmoid->SetParameter(2, 5);
	sigmoid->SetParError(2, 0.01);
	sigmoid->SetParLimits(2, 2, 20);
	
	// Fitting the specified S-Curve with the sigmoid in a specified range
	switch (vfatnumber)
	  {
	  case (0):
	    // Uncomment a Draw command to check the specified fit
	    //	    gr0->Draw("AP");
	    sigmoid->SetParLimits(1, MinRangeVFAT0, MaxRangeVFAT0);
	    gr0->Fit(sigmoid,"Q","",MinRangeVFAT0,150);
	    gr0->GetFunction("sigmoid")->Write();
	    gr0->Write();
	    break;
	  case (1):
	    //	    gr1->Draw("AP");
	    sigmoid->SetParLimits(1, MinRangeVFAT1, MaxRangeVFAT1);
	    gr1->Fit(sigmoid,"Q","",MinRangeVFAT1,150);
	    gr1->GetFunction("sigmoid")->Write();
	    gr1->Write();
	    break;
	  case (2):
	    //	    gr2->Draw("AP");
	    sigmoid->SetParLimits(1, MinRangeVFAT2, MaxRangeVFAT2);
	    gr2->Fit(sigmoid,"Q","",MinRangeVFAT2,150);
	    gr2->GetFunction("sigmoid")->Write();
	    gr2->Write();
	    break;
	  case (3):
	    //	    gr3->Draw("AP");
	    sigmoid->SetParLimits(1, MinRangeVFAT3, MaxRangeVFAT3);
	    gr3->Fit(sigmoid,"Q","",MinRangeVFAT3,150);
	    gr3->GetFunction("sigmoid")->Write();
	    gr3->Write();
	    break;
	  case (4):
	    //	    gr4->Draw("AP");
	    sigmoid->SetParLimits(1, MinRangeVFAT4, MaxRangeVFAT4);
	    gr4->Fit(sigmoid,"Q","",MinRangeVFAT4,150);
	    gr4->GetFunction("sigmoid")->Write();
	    gr4->Write();
	    break;
	  case (5):
	    //	    gr5->Draw("AP");
	    sigmoid->SetParLimits(1, MinRangeVFAT5, MaxRangeVFAT5);
	    gr5->Fit(sigmoid,"Q","",MinRangeVFAT5,150);
	    gr5->GetFunction("sigmoid")->Write();
	    gr5->Write();
	    break;
	  case (6):
	    //	    gr6->Draw("AP");
	    sigmoid->SetParLimits(1, MinRangeVFAT6, MaxRangeVFAT6);
	    gr6->Fit(sigmoid,"Q","",MinRangeVFAT6,150);
	    gr6->GetFunction("sigmoid")->Write();
	    gr6->Write();
	    break;
	  case (7):
	    //	    gr7->Draw("AP");
	    sigmoid->SetParLimits(1, MinRangeVFAT7, MaxRangeVFAT7);
	    gr7->Fit(sigmoid,"Q","",MinRangeVFAT7,150);
	    gr7->GetFunction("sigmoid")->Write();
	    gr7->Write();
	    break;
	  }
	
	// Uncomment to print fit parameters found
	//	printf("\n\n Amplitude=%f,\t Mean=%f,\t Sigma=%f\n\n",Amplitude,Mean,Sigma);
	
	// Saves the objects created in the current rootfile
	
	CalPulse->Write();
	
	f->Write();
	f->Close();

}
