Beispiel #1
0
void A1::PlotChannel( unsigned aModule, unsigned aChannel ){
  if (fChain == 0) return;
  if( c1 ) delete c1;
  c1 = new TCanvas( 3 );
  stringstream stmp;
  stmp << "Module " << aModule + 1 << ", Channel #" << aChannel << ";Time [0.1 ns]; Counts";


  TH1I * hChannel = new TH1I( "hChannel", stmp.str().c_str(), 100000, 10000, 100000 );
  Long64_t nentries = fChain->GetEntriesFast();
  Long64_t nbytes = 0, nb = 0;
  
  for (Long64_t jentry=0; jentry<nentries;jentry++) {
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   
    nbytes += nb;
      // if (Cut(ientry) < 0) continue;
    vector<unsigned int> * HITS_PER_CHANNEL = HitsPerChannel[ aModule ];
    vector<unsigned int> * CH = _Data[ aModule ][ aChannel ];//Module2_LE_CH32;
      //std::cout << "HITS_PER_CHANNEL 32: " << HITS_PER_CHANNEL->at( 32 ) << std::endl;
    if( HITS_PER_CHANNEL->at( aChannel ) > 0 ){
      long trig = CH->at( 0 );
      hChannel->Fill( trig );
    } 
      
  }

  hChannel->Draw();

}
Beispiel #2
0
plotClasses(const char* canvas, const char* title,
	    int nClasses, const char classes[][200], 
	    const int* events, const double* weights)
{
  char evtitle[200], wttitle[200];
  strcpy(evtitle,title);
  strcpy(wttitle,title);
  strcat(evtitle,": Events");
  strcat(wttitle,": Weights");

  TCanvas *c 
    = new TCanvas(canvas,"SPR Input Classes",200,10,600,400);
  gStyle->SetPalette(1); 

  int maxEv = TMath::MaxElement(nClasses,events);
  double maxWt = TMath::MaxElement(nClasses,weights);

  TPad* pad1 = new TPad("events", evtitle,0,0,1.,0.5);
  TPad* pad2 = new TPad("weights",wttitle,0,0.5,1.,1.);
  pad1->Draw();
  pad2->Draw();

  // events
  pad1->cd();
  TH1I* hev = new TH1I("events",evtitle,nClasses,0,nClasses);
  for( int i=0;i<nClasses;i++ )
    hev->Fill(classes[i],events[i]);
  hev->LabelsDeflate("X");
  hev->SetLabelSize(0.06,"X");
  hev->SetLabelSize(0.1,"X");
  hev->SetLabelSize(0.1,"Y");
  hev->SetLineColor(4);
  hev->SetFillColor(4);
  hev->SetBarWidth(0.8);
  hev->SetBarOffset(0.1);
  TAxis* yaxis1 = hev->GetYaxis();
  yaxis1->SetRangeUser(0.,1.1*maxEv);
  hev->Draw("B");

  // weights
  pad2->cd();
  TH1D* hwt = new TH1D("weights",wttitle,nClasses,0,nClasses);
  for( int i=0;i<nClasses;i++ )
    hwt->Fill(classes[i],weights[i]);
  hwt->LabelsDeflate("X");
  hwt->SetLabelSize(0.06,"X");
  hwt->SetLabelSize(0.1,"X");
  hwt->SetLabelSize(0.1,"Y");
  hwt->SetLineColor(3);
  hwt->SetFillColor(3);
  hwt->SetBarWidth(0.8);
  hwt->SetBarOffset(0.1);
  TAxis* yaxis2 = hwt->GetYaxis();
  yaxis2->SetRangeUser(0.,1.1*maxWt);
  hwt->Draw("B");
}
Beispiel #3
0
void A1_Mod::PlotCoinc( unsigned aChannelFirst, unsigned aChannelSecond ){

  if (fChain == 0) return;
  if( c1 ) delete c1;
  c1 = new TCanvas( 3 );
  stringstream stmp;
  unsigned aModule = 0;
  unsigned ChannelCoinc = 30;
  stmp << "Coincidence - Channels " << aChannelFirst << " : " << aChannelSecond << ";Time [0.1 ns]; Counts";

  
  TH1I * hChannel = new TH1I( "hChannel", stmp.str().c_str(), 10000, 0, 10000 );
  Long64_t nentries = fChain->GetEntriesFast();
  Long64_t nbytes = 0, nb = 0;
  
  for (Long64_t jentry = 0; jentry<nentries;jentry++) {
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   
    nbytes += nb;
      // if (Cut(ientry) < 0) continue;
    vector<unsigned int> * HITS_PER_CHANNEL = HitsPerChannel[ aModule ];
    vector<unsigned int> * COINC = _Data[ aModule ][ ChannelCoinc ];
    vector<unsigned int> * TRIG = _Data[ aModule ][ 31 ];   
   //std::cout << "HITS_PER_CHANNEL 32: " << HITS_PER_CHANNEL->at( 32 ) << std::endl;
    if( (HITS_PER_CHANNEL->at( aChannelFirst ) > 0 ) && (HITS_PER_CHANNEL->at( aChannelSecond ) > 0 ) && (HITS_PER_CHANNEL->at( ChannelCoinc ) > 0 ) ){
      long ch = COINC->at( 0 );
      long trig = TRIG->at( 0 );
      std::cout << "Trig -  = " << trig - ch << std::endl;
      hChannel->Fill( trig - ch );
    } 
      
  }

  hChannel->Draw();



}
void NewCosmicstest(){
	//gROOT->Reset();	
	
	TStopwatch *clock0 = new TStopwatch();
	TFile *fout = new TFile("Cosmictest.root","RECREATE");
	bool high = 1;
	
	//Float_t z0 = 1400;
	Float_t z0 = 0;
	Float_t yTop = 600;
	Float_t xTop = 300;
	Float_t zTop = 3650;
	
	Float_t xdist = 3000;
	Float_t zdist = 9000;
	
	TH2D *StartXZ = new TH2D("xz","xz;x[cm];z[cm]",30,-(xdist/2),xdist/2,90,z0 - 4500,z0 + 4500);
	TH1D *StartTheta = new TH1D("#theta","#theta; #theta_Zenith",100,0,2);
	TH1D *StartPhi = new TH1D("#phi","#phi; #phi",50,0,7);
	TH1D *StartPHigh = new TH1D("PHigh","P; P[GeV]",100,-1,3);
	TH1D *StartP = new TH1D("P","P;P[GeV]",100,-1,3);
	TH1D *StartPLow = new TH1D("PLow","P;P[GeV]",100,-1,3);
	//TH1D *StartP = new TH1D("P","P;P[GeV]",100,0.1,1000);
	BinLogX(StartP);
	BinLogX(StartPHigh);
	BinLogX(StartPLow);
	
	TH2D *StartPTheta = new TH2D("P,Theta","P-Theta;P[GeV];#theta",150,-1,3,50,0,2);
	BinLogX(StartPTheta);
	
	TH2D *MCXZ = new TH2D("MCxz","xz;x[cm];z[cm]",30,-(xdist/2),xdist/2,90,z0 - 4500,z0 + 4500);
	TH1D *MCTheta = new TH1D("MC#theta","#theta; #theta",100,0,2);
	TH1D *MCPhi = new TH1D("MC#phi","#phi, #phi",50,0,7);
	
	TH1I *MCnTry = new TH1I("nTry","nTry",100,4.6,5);
	
	Double_t totalweightsum=0;
	Double_t px,py,pz,x,y,z,w, weighttest, weight;
	Int_t nTry,nInside,nEvent,nTest;	
	Co3Rng *fRandomEngine = new Co3Rng();
	
	int EVENTS = 400000;
	Int_t kmax = 40000;
	float weight1,weight1Low,weight1High;
	weight1Low = 123*xdist*zdist/EVENTS/10000; // expected #muons per spill/ #simulated events per spill 174*30*90/500000
	cout<<weight1Low<<endl;
	
	double I = fRandomEngine->fSpectrumH->Integral(100,1000);
	weight1High = 2*TMath::Pi()/3*I*xdist*zdist/EVENTS/10000;
		//weight2 = 900/I; // 1/(mean momentum weight), P_max-P_min/(3*0.3044/2pi)
	
	cout<< weight1High<<endl;
	Float_t weight3 = 4.833931503; // MC average of nTry/nEvents 4.833949997 +- 0.000010494			
	weight1 = 1;								
	weight = weight1 / weight3;
	
	nInside = 0; nEvent = 0; nTest = 0; weighttest = 0;
	y = 1900; //20m over beam axis

	w = weight/kmax;
	clock0->Start();
	for(Int_t k = 0;k<kmax;k++){
		cout<<k<<endl;
		nTry =0;
		for(Int_t i=0;i<EVENTS;i++){
		   Bool_t hit = 0;   
		   do{
				// shower characteristics
			   double phi = fRandomEngine->Uniform(0,2*TMath::Pi());
			   double theta = fRandomEngine->fTheta->GetRandom();
			  				  			    		 
	   	   //momentum components
				px = TMath::Sin(phi)*TMath::Sin(theta); 
				pz = TMath::Cos(phi)*TMath::Sin(theta);
				py = -TMath::Cos(theta);
				
				// start position, area 1120m^2
				x = fRandomEngine->Uniform(-xdist/2,xdist/2);
				z = fRandomEngine->Uniform(z0 - zdist/2, z0 + zdist/2);
				
				// claim for flight close to the actual detector
				if((abs(x-(y+yTop)*px/py) < xTop && abs(z-z0-(y+yTop)*pz/py) < zTop) || (abs(x-(y-yTop)*px/py) < xTop && abs(z-z0-(y-yTop)*pz/py) <  zTop)|| abs(y-(x+xTop)*py/px)<yTop && abs(z-z0-(x+xTop)*pz/px)<zTop || abs(y-(x-xTop)*py/px)<yTop && abs(z-z0-(x-xTop)*pz/px)<zTop){
					
					// muon momentum
					double P;
					//if (!high) {P = fRandomEngine->NEWstest(theta);}
					//else {P = fRandomEngine->fSpectrumH->GetRandom();}
					// high
					P = fRandomEngine->fSpectrumH->GetRandom();
					w = weight1High/weight3/kmax;
					StartP->Fill(P,w);
					StartPHigh->Fill(P,w);
					StartPTheta->Fill(P,theta,w);
					// low
					P = fRandomEngine->NEWstest(theta);
					w = weight1Low/weight3/kmax;
					StartP->Fill(P,w);
					StartPLow->Fill(P,w);
					StartPTheta->Fill(P,theta,w);
					
					
					px = px*P;
					py = py*P;
					pz = pz*P;
					
					//muon or anti-muon
					hit = 1; nInside++; 
					// StartP->Fill(P,w);
					
					w = weight1Low/weight3/kmax + weight1High/weight3/kmax;
					
					StartTheta->Fill(theta,w); // kein Weight!
					StartPhi->Fill(phi,w);	// kein Weight!	
					StartXZ->Fill(x,z,w); // kein Weight!	
					StartPTheta->Fill(P,theta,w);	
			   }
			   nTry++;
				weighttest += w;
				MCTheta->Fill(theta,w); // kein Weight!
				MCPhi->Fill(phi,w);
				MCXZ->Fill(x,z,w);
				nTest++;
			}while(!hit);
			nEvent++;
		}
		MCnTry->Fill(1.0*nTry/EVENTS);
	}
	clock0->Stop();
	
	delete fRandomEngine;
	cout<<nEvent<<" events have been generated."<<endl;
	cout<<"There is a total of "<<nInside<<"/"<<nTest<<" muons that passed close enough to the detector."<<endl;
	cout<<"Including the given weight this corresponds to ";
	cout<<kmax*weighttest/xdist/zdist*10000/123.3044<<" spills (1 spill = "<<xdist*zdist*123.3044/10000;
	cout<<" real cosmic muons = "<<EVENTS<<" simulated events)."<<endl;
   
   cout<<weighttest<<endl;
   clock0->Print();
   
   Double_t meanflux = 0;
   Int_t binsum = 0;
   for (Int_t ix = 2; ix<29;ix++){
	   for (Int_t iz = 2; iz<89;iz++){
		 	binsum++;
		   meanflux += MCXZ->GetBinContent(ix,iz);
		}
	}
	cout<< "meanflux: "<<meanflux/binsum<<"  "<< meanflux<<endl<<endl;
   printf("MCnTry: %.9f +- %.9f",MCnTry->GetMean(),MCnTry->GetMeanError());
   cout<<endl<<endl;
     
    TCanvas *c1 = new TCanvas("c1","c1",400,400);
	 c1->Divide(1,1);
	 c1->cd(1);
	 MCnTry->DrawCopy();
	
	 TCanvas *c4 = new TCanvas("c4","c4",400,400);
	 c4->Divide(1,1);
	 c4->cd(1);
	 StartPTheta->DrawCopy("SURF2");
	 gPad->SetLogx();
	
	 //TCanvas *c2 = new TCanvas("c2","c2",400,400);
	 //c2->Divide(1,1);
	 //c2->cd(1);
	 //gPad->SetLogy();
	 //wei->DrawCopy();
	
    TCanvas *c3 = new TCanvas("c3","c3",1600,800);
	 c3->Divide(4,2);
	 c3->cd(1);
	 StartXZ->DrawCopy("COLZ");
	 c3->cd(2);
	 //MCP->SetLineColor(kGreen);
	// MCP->DrawCopy();
	 //StartP->DrawCopy();
	 //TF1 *fs = new TF1("fs",NEWs,1,100,2);
	 //fs->FixParameter(0, 0);
	 //fs->FixParameter(1, 500);
	 //StartP->Add(fs,-1);
	 StartP->DrawCopy();
	 //StartP->Fit(fs,"I");
	 
	 
	// 
	 //fs->DrawCopy("SAME");
	 
	 //gPad->SetLogy();
	 gPad->SetLogx();
	 c3->cd(3);
	 MCTheta->SetLineColor(kGreen);
	 MCTheta->DrawCopy();
	 StartTheta->DrawCopy("SAME");
	 //TF1 *f1 = new TF1("f1","[0]*cos(x)*cos(x)",1.57,3.14);
	 //StartTheta->Fit(f1,"","",1.57,3.14);	
	 gPad->SetLogy(0);
	 gPad->SetLogx(0);
	 c3->cd(4);
	 MCPhi->SetLineColor(kGreen);
	 MCPhi->DrawCopy();
	 StartPhi->DrawCopy("SAME");
	//TF1 *f1 = new TF1("f1","[0]*cos(x)*cos(x)",1.57,3.14);
	//StartTheta->Fit(f1,"","",1.57,3.14);	
	 gPad->SetLogy(0);
	 gPad->SetLogx(0);
	 c3->cd(5);
	 MCXZ->DrawCopy("COLZ");
	 c3->cd(6);
	 //MCP->Divide(StartP);
	// MCP->DrawCopy();
	 gPad->SetLogy(0);
	 gPad->SetLogx(0);
	 c3->cd(7);
	 //MCTheta->Divide(StartTheta);
	 MCTheta->DrawCopy();
	 gPad->SetLogy();
	 gPad->SetLogx(0);
	 c3->cd(8);
	 //MCPhi->Divide(StartPhi);
	 MCPhi->DrawCopy();
	 gPad->SetLogy(0);
	 gPad->SetLogx(0);
	 c3->Update();
	 c3->SaveAs("Start.png");
	 
	 
	 
	 
	 StartXZ->Write();
	 StartTheta->Write();
	 StartPhi->Write();
	 StartP->Write();
	 StartPLow->Write();
	 StartPHigh->Write();
	
    StartPTheta->Write();
		
	 MCXZ->Write();
	 MCTheta->Write();
	 MCPhi->Write();
	
	 MCnTry->Write();
	 fout ->Close();
	 
	 
  
}
Beispiel #5
0
int main(int argc, char* argv[])
{
  TFile* file = new TFile("neutrons.root", "recreate");

  TChain* chain = createChain(argc, argv);
  // Assign addresses
  double target_charge, veto_charge, target_cb, veto_cb;
  unsigned long long time;
  chain->SetBranchAddress("target_total", &target_charge);
  chain->SetBranchAddress("veto_total", &veto_charge);
  chain->SetBranchAddress("target_cb", &target_cb);
  chain->SetBranchAddress("veto_cb", &veto_cb);
  chain->SetBranchAddress("time", &time);

  const int chainEntries = chain->GetEntries();
  const double adc2us = 4/1000.0;
  const int maxCharge = 30000;
  TH1F* histogram = new TH1F("timing", "timing", 2000, 0, 2000);
  TH1F* neutrons = new TH1F("nspec", "neutron spectrum", 200, 0, maxCharge);
  TH1F* hydrogen = new TH1F("nhspec", "capture on hydrogen", 200, 0, maxCharge);
  TH1F* externals = new TH1F("externspec", "externals", 200, 0, maxCharge);
  TH1F* tsa_neutrons = new TH1F("tsa_spec", "neutron spectrum from tsa plot", 200, 0, maxCharge);
  TH1I* multiplicity = new TH1I("mult", "Event multiplicity", 20, 0, 20);

  unsigned long long t1=0;
  unsigned long long t2=0;
  unsigned long long t3=0;

  // cuts
  const double max_target_cb = 0.5;
  const double max_veto_charge = 500;
  const double min_target_charge = 0;
  const double tale_min = 800;
  const double tale_max = 2000;
  const double neutrons_min = 0;
  const double neutrons_time = 50;
  const double hydro_min = 100;
  const double hydro_max = 150;

  double previous_charge = 0;

  // TSA Plots
  const int nbins = 100;
  double logmin = -0.3;
  double logmax = 4.5;
  double binwidth = (logmax-logmin)/double(nbins);
  double bin_array[nbins+1];
  bin_array[0]=std::pow(10, logmin);
  for(int i=1; i<=nbins; i++)
    bin_array[i]=bin_array[0]+std::pow(10,logmin + i*binwidth);
  TH2F* tsa = new TH2F("tsa", "time series analysis", nbins, bin_array, nbins, bin_array);

  // Keep track of timing in order to get multiplicity
  std::vector<unsigned long long> time_vec;
  time_vec.resize(1, 0);

  for(int evt=0; evt<chainEntries; ++evt)
  {
    // Print out progress
    if(!(evt%1000))
      std::cout << std::floor(double(evt)/chainEntries*100) << "%\r";
    previous_charge = target_charge;
    chain->GetEvent(evt);    

    if(veto_charge<max_veto_charge &&
       target_charge>min_target_charge &&
       target_cb < max_target_cb )
    {
      
      t3=t2;
      t2=t1;
      t1=time;
      double d12 = (t1-t2)*adc2us;
      double d23 = (t2-t3)*adc2us;
      tsa->Fill(d23, d12);
      if((time-time_vec[0])*adc2us < 50)
	time_vec.push_back(time);
      else
      {
	multiplicity->Fill(time_vec.size());
	time_vec.clear();
	time_vec.push_back(time);
      }

      histogram->Fill(d12);
      if(d12 < neutrons_time && d12 > neutrons_min)
	neutrons->Fill(target_charge);
      if(d12 < tale_max && d12 > tale_min)
	externals->Fill(target_charge);
      if(d12 < hydro_max && d12 > hydro_min)
	hydrogen->Fill(target_charge);
      if(d12 < neutrons_time && d23 < neutrons_time)
	tsa_neutrons->Fill(previous_charge);
    }
  }
  std::cout << std::endl;
  // Events in tale:
  TF1* fitter_extern = new TF1("fitter_extern", "[0]*TMath::Exp([1]*x)",
			       0, 2000);
  fitter_extern->SetParameters(1000, -4e-4);
  histogram->Fit(fitter_extern, "QO", "", tale_min, tale_max);
  TF1* fitter_h = new TF1("fitter_h", "[0]*TMath::Exp([1]*x)",
			  0, 2000);
  fitter_h->SetParameters(1000, -4e-3);
  histogram->Fit(fitter_h, "QO+", "", hydro_min, hydro_max);

  

  int tale_events = fitter_extern->Integral(tale_min, tale_max);
  int bkg_events = fitter_extern->Integral(neutrons_min, neutrons_time);

  int h_long_events = fitter_h->Integral(hydro_min, hydro_max);
  int h_short_events = fitter_h->Integral(neutrons_min, neutrons_time);

  double talebkgratio = bkg_events / double(tale_events);
  externals->Scale(talebkgratio);
  double h_ratio = h_short_events / h_long_events;
  hydrogen->Scale(h_ratio);

  TH1F* pureNeutrons = new TH1F("pureNeutrons", "pureNeutrons", 200, 0, maxCharge);
  for(int i=0; i<neutrons->GetNbinsX(); i++)
    pureNeutrons->SetBinContent(i, neutrons->GetBinContent(i) - externals->GetBinContent(i) 
				- hydrogen->GetBinContent(i));

  file->Write();
  std::cout << "Wrote histograms to neutrons.root" << std::endl;

  // TRint* app = new TRint("EVIL", &argc, argv);
  // TCanvas* c1 = new TCanvas();
  //c1->Divide(1,2);
  //c1->cd(1);
  //histogram->Draw();
  //fitter_h->Draw("same");
  //fitter_extern->Draw("same");
  //c1->cd(2);
  // externals->SetLineColor(kBlack);
  // neutrons->SetLineColor(kGreen);
  // pureNeutrons->SetLineColor(kRed);
  // hydrogen->SetLineColor(kBlue);
  // neutrons->Draw();
  // externals->Draw("same");
  // hydrogen->Draw("same");
  // pureNeutrons->Draw("same");
  //app->Run();

  delete histogram;
  delete externals;
  delete neutrons;
  delete pureNeutrons;
  //delete c1;
  delete chain;
  delete file;
  return 0;
}
void processWaveforms(TTree* treeToSort, vector<Plots>& targetPlots, TFile* outFile, string mode)
{
    TH1D* fittedTimeHisto = new TH1D("raw fitted times", "raw fitted times", TOF_BINS,TOF_LOWER_BOUND,TOF_RANGE);

    TH2D* deltaTVsPulseHeight = new TH2D("delta T vs. pulse height","delta T vs. pulse height", 200, -10, 10, 1580, 0, 15800);

    TH2D* deltaTVsPulseIntegral0 = new TH2D("delta T vs. pulse integral, target 0","delta T vs. pulse integral, target 0",100, -10, 10, pow(2,15), 0, pow(2,15));
    TH2D* deltaTVsPulseIntegral1 = new TH2D("delta T vs. pulse integral, target 1","delta T vs. pulse integral, target 1",100, -10, 10, pow(2,15), 0, pow(2,15));
    TH2D* deltaTVsPulseIntegral2 = new TH2D("delta T vs. pulse integral, target 2","delta T vs. pulse integral, target 2",100, -10, 10, pow(2,15), 0, pow(2,15));
    TH2D* deltaTVsPulseIntegral3 = new TH2D("delta T vs. pulse integral, target 3","delta T vs. pulse integral, target 3",100, -10, 10, pow(2,15), 0, pow(2,15));
    TH2D* deltaTVsPulseIntegral4 = new TH2D("delta T vs. pulse integral, target 4","delta T vs. pulse integral, target 4",100, -10, 10, pow(2,15), 0, pow(2,15));
    TH2D* deltaTVsPulseIntegral5 = new TH2D("delta T vs. pulse integral, target 5","delta T vs. pulse integral, target 5",100, -10, 10, pow(2,15), 0, pow(2,15));

    TH1D* triggerAmplitudeHisto = new TH1D("triggerAmplitudeHisto","triggerAmplitudeHisto",pow(2,14),0,pow(2,14));
    TH1D* relativeTriggerTimeHisto = new TH1D("relativeTriggerTimeHisto","relative trigger time, from start of fitted wavelet",200,-5,5);
    TH2D* relativeTriggerTimeVsAmplitude = new TH2D("relativeTriggerTimeVSAmplitude","relative trigger time vs amplitude", 200, -5, 5, pow(2,14), 0, pow(2,14));

    TH1D* gammaToGammaTimeH = new TH1D("gammaToGammaTimeH","time between consecutive gammas", 1000, -5, 5);

    if(mode=="DPP")
    {
        setBranchesHistos(treeToSort);

        int totalEntries = treeToSort->GetEntries();
        cout << "Total waveforms = " << totalEntries << endl;

        vector<double> triggerList;

        waveformWrap = new TMultiGraph("DPP waveforms", "DPP waveforms");
        vector<TGraph*> waveletGraphs;
        vector<TGraph*> triggerGraphs;

        int gammaGate[2] = {80,90};

        double prevGammaTime = 0;

        for(int j=1; j<totalEntries; j++)
        {
            if(j%1000==0)
            {
                cout << "Processing triggers on waveform " << j << "\r";
                fflush(stdout);
            }

            /*if(j>500)
            {
                break;
            }*/

            triggerList.clear();
            triggerValues.clear();

            // pull individual waveform event
            treeToSort->GetEntry(j);

            // calculate the baseline for this waveform
            BASELINE = calculateBaseline(*procEvent.waveform);

            // Loop through all points in the waveform and fit peaks
            for(int k=DPP_PEAKFIT_START; (size_t)k<procEvent.waveform->size(); k++)
            {
                // Check to see if this point creates a new trigger
                if(isTrigger(k, *procEvent.waveform))
                {
                    // trigger found - plot/fit/extract time

                    double timeDiff = procEvent.completeTime-procEvent.macroTime;
                    double microTime = fmod(timeDiff,MICRO_LENGTH);

                    if(microTime > gammaGate[0] && microTime < gammaGate[1])
                    {
                        processTrigger(j, k, triggerList, *procEvent.waveform);

                        double fullTime = procEvent.completeTime-procEvent.macroTime+data.trigger1Time+DPP_PEAKFIT_OFFSET;
                        gammaToGammaTimeH->Fill(fmod(fullTime,MICRO_LENGTH)-prevGammaTime);
                        prevGammaTime=fmod(fullTime,MICRO_LENGTH);

                        fillTriggerHistos(fullTime, targetPlots);
                        fittedTimeHisto->Fill(data.trigger1Time);
                    }

                    //processTrigger(j, k, triggerList, *procEvent.waveform);

                    break;
                }
            }

            //produceTriggerOverlay(j, triggerList, *procEvent.waveform);

            TH2D* deltaTVsPulseIntegralHisto;

            switch(procEvent.targetPos-1)
            {
                case 0:
                    deltaTVsPulseIntegralHisto = deltaTVsPulseIntegral0;
                    break;

                case 1:
                    deltaTVsPulseIntegralHisto = deltaTVsPulseIntegral1;
                    break;

                case 2:
                    deltaTVsPulseIntegralHisto = deltaTVsPulseIntegral2;
                    break;

                case 3:
                    deltaTVsPulseIntegralHisto = deltaTVsPulseIntegral3;
                    break;

                case 4:
                    deltaTVsPulseIntegralHisto = deltaTVsPulseIntegral4;
                    break;

                case 5:
                    deltaTVsPulseIntegralHisto = deltaTVsPulseIntegral5;
                    break;
            }

            triggerAmplitudeHisto->Fill(data.peak1Amplitude);
            relativeTriggerTimeHisto->Fill(data.trigger1Time+DPP_PEAKFIT_OFFSET);
            relativeTriggerTimeVsAmplitude->Fill(data.trigger1Time+DPP_PEAKFIT_OFFSET,data.peak1Amplitude);

            deltaTVsPulseIntegralHisto->Fill(data.trigger1Time+DPP_PEAKFIT_OFFSET, procEvent.lgQ);
            deltaTVsPulseHeight->Fill(data.trigger1Time+DPP_PEAKFIT_OFFSET, data.peak1Amplitude);

            // Create a new graph for each wavelet
            //waveletGraphs.push_back(new TGraph());

            // Fill each micropulse graph with waveform samples
            /*for (int l=0; l<procEvent.waveform->size(); l++)
              {
              waveletGraphs.back()->SetPoint(l,l*SAMPLE_PERIOD,procEvent.waveform->at(l));
              }*/

            // Create a new graph for each wavelet
            //triggerGraphs.push_back(new TGraph());

            // Fill each micropulse graph with waveform samples
            //triggerGraphs.back()->SetPoint(0,triggerList[0],triggerValues[0]);

            fill(procEvent.waveform->begin(),procEvent.waveform->end(),BASELINE);
        }

        TGraph* exponentialFit = new TGraph();
        exponentialFit->SetPoint(0,-0.78,140);
        exponentialFit->SetPoint(1,0.16,206);
        exponentialFit->SetPoint(2,1.79,305);
        exponentialFit->SetPoint(3,2.82,417);
        exponentialFit->SetPoint(4,3.59,566);
        exponentialFit->SetPoint(5,4.4,929);
        exponentialFit->SetPoint(6,5.2,1482);
        exponentialFit->SetPoint(7,5.7,2149);
        exponentialFit->SetPoint(8,6.9,5319);
        exponentialFit->SetPoint(9,7.3,7808);
        exponentialFit->SetPoint(10,7.7,11395);
        exponentialFit->SetPoint(11,8.0,16200);
        exponentialFit->Write();

        // Add each wavelet graph to the MultiGraph
        for (int m=0; m<waveletGraphs.size(); m++)
        {
            //cout << "adding graph " << m << " to multigraph" << endl;
            waveletGraphs[m]->Draw();
            waveformWrap->Add(waveletGraphs[m],"l");
        }

        // Add each trigger graph to the MultiGraph
        for (int m=0; m<triggerGraphs.size(); m++)
        {
            //cout << "adding graph " << m << " to multigraph" << endl;
            triggerGraphs[m]->SetMarkerSize(2);
            triggerGraphs[m]->SetMarkerColor(2);
            triggerGraphs[m]->Draw();
            waveformWrap->Add(triggerGraphs[m],"*");
        }

        waveformWrap->Write();

        for(Plots p : targetPlots)
        {
            p.getTOFHisto()->Write();
            p.getEnergyHisto()->Write();
        }

        fittedTimeHisto->Write();

        deltaTVsPulseIntegral0->Write();
        deltaTVsPulseIntegral1->Write();
        deltaTVsPulseIntegral2->Write();
        deltaTVsPulseIntegral3->Write();
        deltaTVsPulseIntegral4->Write();
        deltaTVsPulseIntegral5->Write();

        deltaTVsPulseHeight->Write();

        relativeTriggerTimeHisto->Write();
        triggerAmplitudeHisto->Write();
        relativeTriggerTimeVsAmplitude->Write();

        gammaToGammaTimeH->Write();
    }

    else if(mode=="waveform")
    {
        setBranchesHistosW(treeToSort);

        triggerWalk = new TH2I("triggerWalk","trigger time vs. waveform chunk #",200,0,200,1000,0,1000);

        TH1I* monitorHisto = new TH1I("targetPosH", "targetPos", 7, 0, 7);
        monitorHisto->GetXaxis()->SetTitle("target position of each waveform");

        long triggersWithGamma = 0;
        vector<int> fullWaveform(MACRO_LENGTH/2, BASELINE);
        vector<double> triggerList;

        int prevTargetPos = 0;
        double firstTimetagInSeries = 0;

        int totalEntries = treeToSort->GetEntries();
        cout << "Total waveforms = " << totalEntries << endl;

        /*TCanvas *mycan = (TCanvas*)gROOT->FindObject("mycan");

          if(!mycan)
          {
          mycan = new TCanvas("mycan","mycan");
          }*/

        // EVENT LOOP for sorting through channel-specific waveforms
        for(int j=1; j<totalEntries; j++)
        {
            cout << "Processing triggers on waveform " << j << "\r";
            fflush(stdout);

            if(j>30)
            {
                break;
            }

            triggerList.clear();
            triggerValues.clear();

            prevTargetPos = procEvent.targetPos;

            // pull individual waveform event
            treeToSort->GetEntry(j);

            if(procEvent.evtNo==1)
            {
                // new macropulse; process the previous macropulse's waveform

                // calculate the baseline for this waveform
                BASELINE = calculateBaseline(fullWaveform);

                // Loop through all points in the waveform and fit peaks
                for(int k=PEAKFIT_WINDOW; (size_t)k<fullWaveform.size(); k++)
                {
                    // Check to see if this point creates a new trigger
                    if(isTrigger(k, fullWaveform))
                    {
                        // trigger found - plot/fit/extract time
                        processTrigger(j, k, triggerList, fullWaveform);

                        // shift waveform index past the end of this fitting window
                        // so that we don't refit the same data
                        k += PEAKFIT_WINDOW;
                    }
                    /*if(triggerList.size()>10)
                      {
                      for(int m=0; m<triggerList.size(); m++)
                      {
                      cout << "triggerList[" << m << "] = " << triggerList[m] << endl;
                      }
                      break;
                      }*/
                }

                // Use the gamma peaks to find the time offset for this waveform, and
                // adjust the microTime with this offset

                double gammaOffset = calculateGammaOffset(triggerList);

                /*for(int m=0; (size_t)m<triggerList.size(); m++)
                  {
                  fillTriggerHistos(triggerList[m]-gammaOffset, targetPlots);
                  }*/

                if(gammaOffset!=0)
                {
                    for(int m=0; (size_t)m<triggerList.size(); m++)
                    {
                        //fillTriggerHistos(triggerList[m]-gammaOffset+WAVEFORM_OFFSET, targetPlots);
                    }

                    triggersWithGamma++;
                }

                /*if(j<30)
                  {
                  produceTriggerOverlay(j, triggerList, fullWaveform);
                  }*/

                /*temp.str("");
                  temp << "waveformWrap" << j;

                  waveformWrap = new TMultiGraph(temp.str().c_str(), temp.str().c_str());

                  vector<TGraph*> microGraphs;

                // Create a new graph for each micropulse period to be plotted
                for (int m = 0; m<floor(2*procEvent.waveform->size()/MICRO_LENGTH); m++)
                {
                microGraphs.push_back(new TGraph());
                }

                // Fill each micropulse graph with waveform samples
                for (int l = 0; l<procEvent.waveform->size(); l++)
                {
                microGraphs[(int)floor(l/(double)MICRO_LENGTH)]->SetPoint(microGraphs[(int)floor(l/(double)MICRO_LENGTH)]->GetN(),fmod(2*l+WAVEFORM_OFFSET,MICRO_LENGTH),procEvent.waveform->at(l));
                //cout << "Adding value " << procEvent.waveform->at(l) << " to position " << fmod(l,MICRO_LENGTH) << " in microGraph " << floor(l/(double)MICRO_LENGTH) << endl;
                }

                // Add each graph to the MultiGraph
                for (int m = 0; m<microGraphs.size(); m++)
                {
                //cout << "adding graph " << m << " to multigraph" << endl;
                microGraphs[m]->Draw();
                waveformWrap->Add(microGraphs[m],"l");
                }

                waveformWrap->Write();
                */

                //gPad->Modified();
                //mycan->Update();

                // Fill trigger histogram
                /*for (int l = 0; l<triggerList.size(); l++)
                  {
                  cout << "trigger " << l << " = " << triggerList[l] << ", " << triggerValues[l] << endl;
                  }*/

                //triggerH->Write();
                //cout << "Finished processing waveform " << j << endl << endl;

                /*if(j==10)
                  {
                  break;
                  }*/

                monitorHisto->Fill(prevTargetPos);

                fill(fullWaveform.begin(),fullWaveform.end(),BASELINE);

                firstTimetagInSeries = procEvent.completeTime;
            }

            if (procEvent.targetPos == 0)
            {
                continue;
            }

            double timeOffset = procEvent.completeTime-firstTimetagInSeries;

            if(timeOffset<MACRO_LENGTH-2*procEvent.waveform->size())
            {
                for(int k=0; k<procEvent.waveform->size(); k++)
                {
                    fullWaveform[timeOffset/SAMPLE_PERIOD+k] = procEvent.waveform->at(k);
                }
            }
        }

        cout << "Triggers with gamma in wavelet: " << triggersWithGamma << endl;

        monitorHisto->Write();

        for(Plots p : targetPlots)
        {
            p.getTOFHisto()->Write();
            p.getEnergyHisto()->Write();
        }

        cout << "Number of good fits: " << numberGoodFits << endl;
        cout << "onePeak = " << numberOnePeakFits << endl; 
        cout << "onePeakExpBack = " << numberOnePeakExpBackFits << endl; 
        cout << "twoPeaks = " << numberTwoPeakFits << endl << endl; 
        cout << "Number of bad fits: " << numberBadFits << endl;
    }

    else
    {
        cerr << "Error: digitizer mode was " << mode << "; only possible options are 'DPP' or 'waveform'. Exiting..." << endl;
        exit(1);
    }
}
void ExtractTrackBasedTiming(TString fileName = "hd_root.root", int runNumber = 10390, TString variation = "default", bool verbose = false,TString prefix = ""){

   // set "prefix" in case you want to ship the txt files elsewhere...
   cout << "Performing Track Matched timing fits for File: " << fileName.Data() << " Run: " << runNumber << " Variation: " << variation.Data() << endl;

   ExtractTrackBasedTimingNS::thisFile = TFile::Open( fileName , "UPDATE");
   if (ExtractTrackBasedTimingNS::thisFile == 0) {
      cout << "Unable to open file " << fileName.Data() << "...Exiting" << endl;
      return;
   }

   //We need the existing constants, The best we can do here is just read them from the file.
   vector<double> sc_tdc_time_offsets;
   vector<double> sc_fadc_time_offsets;
   vector<double> tof_tdc_time_offsets;
   vector<double> tof_fadc_time_offsets;
   vector<double> tagm_tdc_time_offsets;
   vector<double> tagm_fadc_time_offsets;
   vector<double> tagh_tdc_time_offsets;
   vector<double> tagh_fadc_time_offsets;
   vector<double> tagh_counter_quality;

   double sc_t_base_fadc, sc_t_base_tdc;
   double tof_t_base_fadc, tof_t_base_tdc;
   double bcal_t_base_fadc, bcal_t_base_tdc;
   double tagm_t_base_fadc, tagm_t_base_tdc;
   double tagh_t_base_fadc, tagh_t_base_tdc;
   double fdc_t_base_fadc, fdc_t_base_tdc;
   double fcal_t_base;
   double cdc_t_base;
   double RF_Period;

   cout << "Grabbing CCDB constants..." << endl;
   // Base times
   GetCCDBConstants1("/CDC/base_time_offset" ,runNumber, variation, cdc_t_base);
   GetCCDBConstants1("/FCAL/base_time_offset",runNumber, variation, fcal_t_base);
   GetCCDBConstants1("/PHOTON_BEAM/RF/beam_period",runNumber, variation, RF_Period);
   GetCCDBConstants2("/FDC/base_time_offset" ,runNumber, variation, fdc_t_base_fadc, fdc_t_base_tdc);
   GetCCDBConstants2("/BCAL/base_time_offset" ,runNumber, variation, bcal_t_base_fadc, bcal_t_base_tdc);
   GetCCDBConstants2("/PHOTON_BEAM/microscope/base_time_offset" ,runNumber, variation, tagm_t_base_fadc, tagm_t_base_tdc);
   GetCCDBConstants2("/PHOTON_BEAM/hodoscope/base_time_offset" ,runNumber, variation, tagh_t_base_fadc, tagh_t_base_tdc);
   GetCCDBConstants2("/START_COUNTER/base_time_offset" ,runNumber, variation, sc_t_base_fadc, sc_t_base_tdc);
   GetCCDBConstants2("/TOF/base_time_offset" ,runNumber, variation, tof_t_base_fadc, tof_t_base_tdc);
   // Per channel
   //GetCCDBConstants("/BCAL/TDC_offsets"    ,runNumber, variation, bcal_tdc_offsets);
   //GetCCDBConstants("/FCAL/timing_offsets" ,runNumber, variation, fcal_adc_offsets);
   GetCCDBConstants("/START_COUNTER/adc_timing_offsets" ,runNumber, variation, sc_fadc_time_offsets);
   GetCCDBConstants("/START_COUNTER/tdc_timing_offsets" ,runNumber, variation, sc_tdc_time_offsets);
   GetCCDBConstants("/PHOTON_BEAM/microscope/fadc_time_offsets" ,runNumber, variation, tagm_fadc_time_offsets,3);// Interested in 3rd column
   GetCCDBConstants("/PHOTON_BEAM/microscope/tdc_time_offsets"  ,runNumber, variation, tagm_tdc_time_offsets,3);
   GetCCDBConstants("/PHOTON_BEAM/hodoscope/fadc_time_offsets"  ,runNumber, variation, tagh_fadc_time_offsets,2);// Interested in 2nd column
   GetCCDBConstants("/PHOTON_BEAM/hodoscope/tdc_time_offsets"   ,runNumber, variation, tagh_tdc_time_offsets,2);
   GetCCDBConstants("/PHOTON_BEAM/hodoscope/counter_quality"    ,runNumber, variation, tagh_counter_quality,2);
   GetCCDBConstants("/TOF/adc_timing_offsets",runNumber, variation, tof_fadc_time_offsets);
   GetCCDBConstants("/TOF/timing_offsets",runNumber, variation, tof_tdc_time_offsets);

   cout << "CDC base times = " << cdc_t_base << endl;
   cout << "FCAL base times = " << fcal_t_base << endl;
   cout << "FDC base times = " << fdc_t_base_fadc << ", " << fdc_t_base_tdc << endl;
   cout << "BCAL base times = " << bcal_t_base_fadc << ", " << bcal_t_base_tdc << endl;
   cout << "SC base times = " << sc_t_base_fadc << ", " << sc_t_base_tdc << endl;
   cout << "TOF base times = " << tof_t_base_fadc << ", " << tof_t_base_tdc << endl;
   cout << "TAGH base times = " << tagh_t_base_fadc << ", " << tagh_t_base_tdc << endl;
   cout << "TAGM base times = " << tagm_t_base_fadc << ", " << tagm_t_base_tdc << endl;

   cout << endl;
   cout << "RF_Period = " << RF_Period << endl;
   cout << endl;

   cout << "Done grabbing CCDB constants...Entering fits..." << endl;

   // Do our final step in the timing alignment with tracking

   //When the RF is present we can try to simply pick out the correct beam bucket for each of the runs
   //First just a simple check to see if we have the appropriate data
   bool useRF = false;
   TH1I *testHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "TAGH_TDC_RF_Compare","Counter ID 001");
   if (testHist != NULL){ // Not great since we rely on channel 1 working, but can be craftier later.
      cout << "Using RF Times for Calibration" << endl;
      useRF = true;
   }
   ofstream outFile;
   TH2I *thisHist; 
   thisHist = ExtractTrackBasedTimingNS::Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGM - SC Target Time");
   if (useRF) thisHist = ExtractTrackBasedTimingNS::Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGM - RFBunch Time");
   if (thisHist != NULL){
      //Statistics on these histograms are really quite low we will have to rebin and do some interpolation
      outFile.open(prefix + "tagm_tdc_timing_offsets.txt", ios::out | ios::trunc);
      outFile.close(); // clear file
      outFile.open(prefix + "tagm_adc_timing_offsets.txt", ios::out | ios::trunc);
      outFile.close(); // clear file
      int nBinsX = thisHist->GetNbinsX();
      int nBinsY = thisHist->GetNbinsY();
      TH1D * selectedTAGMOffset = new TH1D("selectedTAGMOffset", "Selected TAGM Offset; Column; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5);
      TH1I * TAGMOffsetDistribution = new TH1I("TAGMOffsetDistribution", "TAGM Offset; TAGM Offset [ns]; Entries", 500, -250, 250);
      for (int i = 1 ; i <= nBinsX; i++){ 
         TH1D *projY = thisHist->ProjectionY("temp", i, i);
         // Scan over the histogram
         //chose the correct number of bins based on the histogram
         float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
         float timeWindow = 3; //ns (Full Width)
         int binWindow = int(timeWindow / nsPerBin);
         double maxEntries = 0;
         double maxMean = 0;
         for (int j = 1 ; j <= projY->GetNbinsX();j++){
            int minBin = j;
            int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX();
            double sum = 0, nEntries = 0;
            for (int bin = minBin; bin <= maxBin; bin++){
               sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
               nEntries += projY->GetBinContent(bin);
               if (bin == maxBin){
                  if (nEntries > maxEntries) {
                     maxMean = sum / nEntries;
                     maxEntries = nEntries;
                  }
               } 
            }
         }
         //In the case there is RF, our job is to pick just the number of the correct beam bunch, so that's really all we need.
         if(useRF) {
            int beamBucket = int((maxMean / RF_Period) + 0.5); // +0.5 to handle rounding correctly
            selectedTAGMOffset->SetBinContent(i, beamBucket);
            TAGMOffsetDistribution->Fill(beamBucket);
         }
         else{
            selectedTAGMOffset->SetBinContent(i, maxMean);
            TAGMOffsetDistribution->Fill(maxMean);
         }
      }
      double meanOffset = TAGMOffsetDistribution->GetMean();
      // This might be in units of beam bunches, so we need to convert
      if (useRF) meanOffset *= RF_Period;
      if (verbose) {
         cout << "Dumping TAGM results...\n=======================================" << endl;
         cout << "TAGM mean Offset = " << meanOffset << endl;
         cout << "fADC Offsets" << endl;
      }

      outFile.open(prefix + "tagm_adc_timing_offsets.txt", ios::out);
      //for (int i = 1 ; i <= nBinsX; i++){
      // Loop over rows
      if (verbose) cout << "Column\tRow\tvalueToUse\toldValue\tmeanOffset\tTotal" << endl;
      for (unsigned int column = 1; column <= 102; column++){
         int index = GetCCDBIndexTAGM(column, 0);
         double valueToUse = selectedTAGMOffset->GetBinContent(index);
         if (useRF) valueToUse *= RF_Period;

         //if (valueToUse == 0) valueToUse = meanOffset;
         outFile << "0 " << column << " " << valueToUse + tagm_fadc_time_offsets[index-1] - meanOffset<< endl;
         if (verbose) printf("0\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", column, valueToUse, tagm_fadc_time_offsets[index-1], meanOffset, 
               valueToUse + tagm_fadc_time_offsets[index-1] - meanOffset);
         if (column == 9 || column == 27 || column == 81 || column == 99){
            for (unsigned int row = 1; row <= 5; row++){
               index = GetCCDBIndexTAGM(column, row);
               valueToUse = selectedTAGMOffset->GetBinContent(index);
               if (useRF) valueToUse *= RF_Period;
               //if (valueToUse == 0) valueToUse = meanOffset;
               outFile << row << " " << column << " " << valueToUse + tagm_fadc_time_offsets[index-1] - meanOffset<< endl;
               if (verbose) printf("%i\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", row, column, valueToUse, tagm_fadc_time_offsets[index-1], meanOffset,
                     valueToUse + tagm_fadc_time_offsets[index-1] - meanOffset);
            }
         }
      }
      outFile.close();

      if (verbose) {
         cout << "TDC Offsets" << endl;
         cout << "Column\tRow\tvalueToUse\toldValue\tmeanOffset\tTotal" << endl;
      }
      outFile.open(prefix + "tagm_tdc_timing_offsets.txt", ios::out);
      //for (int i = 1 ; i <= nBinsX; i++){
      // Loop over rows
      for (unsigned int column = 1; column <= 102; column++){
         int index = GetCCDBIndexTAGM(column, 0);
         double valueToUse = selectedTAGMOffset->GetBinContent(index);
         if (useRF) valueToUse *= RF_Period;
         //if (valueToUse == 0) valueToUse = meanOffset;
         outFile << "0 " << column << " " << valueToUse + tagm_tdc_time_offsets[index-1] - meanOffset << endl;
         if (verbose) printf("0\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", column, valueToUse, tagm_tdc_time_offsets[index-1], meanOffset,
               valueToUse + tagm_tdc_time_offsets[index-1] - meanOffset);
         if (column == 9 || column == 27 || column == 81 || column == 99){
            for (unsigned int row = 1; row <= 5; row++){
               index = GetCCDBIndexTAGM(column, row);
               valueToUse = selectedTAGMOffset->GetBinContent(index);
               if (useRF) valueToUse *= RF_Period;
               //if (valueToUse == 0) valueToUse = meanOffset;
               outFile << row << " " << column << " " << valueToUse + tagm_tdc_time_offsets[index-1] - meanOffset << endl;
               if (verbose) printf("%i\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", row, column, valueToUse, tagm_tdc_time_offsets[index-1], meanOffset,
                     valueToUse + tagm_tdc_time_offsets[index-1] - meanOffset);
            }
         }
      }
      outFile.close();
      outFile.open(prefix + "tagm_base_time.txt", ios::out);
      if (verbose) {
         printf("TAGM ADC Base = %f - (%f) = %f\n", tagm_t_base_fadc, meanOffset, tagm_t_base_fadc - meanOffset);
         printf("TAGM TDC Base = %f - (%f) = %f\n", tagm_t_base_tdc, meanOffset, tagm_t_base_tdc - meanOffset);
      }
      outFile << tagm_t_base_fadc - meanOffset << " " << tagm_t_base_tdc - meanOffset << endl;
      outFile.close();

   }

   thisHist = ExtractTrackBasedTimingNS::Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGH - SC Target Time");
   if (useRF) thisHist = ExtractTrackBasedTimingNS::Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGH - RFBunch Time");
   if (thisHist != NULL) {
      outFile.open(prefix + "tagh_tdc_timing_offsets.txt", ios::out | ios::trunc);
      outFile.close(); // clear file
      outFile.open(prefix + "tagh_adc_timing_offsets.txt", ios::out | ios::trunc);
      outFile.close(); // clear file

      // Setup histogram for determining the most probable change in offset for each F1TDC slot
      // This is needed to account for the occasional uniform shift in offsets of the 32 counters in a slot
      const int NtdcSlots = 8;
      TH1I * tdcDist[NtdcSlots];
      for (int i = 1; i <= NtdcSlots; i++) {
         stringstream ss; ss << i;
         TString s = ss.str();
         double range = 500.0; double width = 0.1;
         int Nbins = range/width;
         double low = -0.5*range - 0.5*width;
         double high = 0.5*range - 0.5*width;
         tdcDist[i-1] = new TH1I("TAGHOffsetDistribution_"+s, "TAGH Offset (slot "+s+"); TAGH Offset [ns]; Entries", Nbins, low, high);
      }

      int nBinsX = thisHist->GetNbinsX();
      TH1D * selectedTAGHOffset = new TH1D("selectedTAGHOffset", "Selected TAGH Offset; ID; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5);
      for (int i = 1 ; i <= nBinsX; i++) {
         TH1D *projY = thisHist->ProjectionY("temp", i, i);
         // Scan over histogram to find mean offset in timeWindow with largest integral
         // Choose the correct number of bins based on the histogram
         double nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
         double timeWindow = 2.0; // ns (Full Width)
         int binWindow = int(timeWindow / nsPerBin);

         double maxEntries = 0;
         double maxMean = 0;
         for (int j = 1; j <= projY->GetNbinsX(); j++) {
            int minBin = j;
            int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX();
            double sum = 0; 
            double nEntries = 0;
            for (int bin = minBin; bin <= maxBin; bin++) {
               sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
               nEntries += projY->GetBinContent(bin);
               if (bin == maxBin) {
                  if (nEntries > maxEntries) {
                     maxMean = sum / nEntries;
                     maxEntries = nEntries;
                  }
               }
            }
         }

         if (tagh_counter_quality[i-1] == 0.0) {
            selectedTAGHOffset->SetBinContent(i, 0);
            continue;
         }
         int tdc_slot = GetF1TDCslotTAGH(i);
         if (useRF) {
            int beamBucket;
            if (maxMean >= 0) beamBucket = int((maxMean / RF_Period) + 0.5); // +0.5 to handle rounding correctly
            else beamBucket = int((maxMean / RF_Period) - 0.5);
            selectedTAGHOffset->SetBinContent(i, beamBucket);
            if (maxEntries != 0.0) tdcDist[tdc_slot - 1]->Fill(beamBucket);
         } else {
            selectedTAGHOffset->SetBinContent(i, maxMean);
            if (maxEntries != 0.0) tdcDist[tdc_slot - 1]->Fill(maxMean);
         }
      }
      // Most probable change in offset or beam bucket per F1TDC slot
      double mpDelta[NtdcSlots];
      for (int i = 1; i <= NtdcSlots; i++) {
         int mpBin = tdcDist[i-1]->GetMaximumBin();
         mpDelta[i-1] = (mpBin > 0) ? tdcDist[i-1]->GetBinCenter(mpBin) : 0.0;
         if (useRF) mpDelta[i-1] *= RF_Period;
         if (verbose) {
            cout << "TAGH most probable Offset = " << i << ", " << mpDelta[i-1] << endl;
         }
      }

      if (verbose) {
         cout << "Dumping TAGH results...\n=======================================" << endl;
         cout << "Type\tChannel\tvalueToUse\toldValue\tmpDelta\tTotal" << endl;
      }

      double limit = 2.5; // ns
      double ccdb_sum = 0.0;
      for (int i = 1; i <= nBinsX; i++) ccdb_sum += tagh_tdc_time_offsets[i-1];
      double c1_tdcOffset = 0.0;
      outFile.open(prefix + "tagh_tdc_timing_offsets.txt");
      for (int i = 1; i <= nBinsX; i++) {
         if (tagh_counter_quality[i-1] == 0.0) {
            outFile << i << " " << 0 << endl;
            continue;
         }
         int tdc_slot = GetF1TDCslotTAGH(i);
         double delta = selectedTAGHOffset->GetBinContent(i);
         if (useRF) delta *= RF_Period;
         if (ccdb_sum > 0.0 && fabs(delta - mpDelta[tdc_slot-1]) > limit) {
            delta = mpDelta[tdc_slot-1];
         }
         double ccdb = tagh_tdc_time_offsets[i-1];
         double offset = ccdb + delta;
         if (i == 1) c1_tdcOffset = offset;
         offset -= c1_tdcOffset;
         outFile << i << " " << offset << endl;
         if (verbose) printf("TDC\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", i, delta, ccdb, mpDelta[tdc_slot-1], offset);
      }
      outFile.close();

      ccdb_sum = 0.0;
      for (int i = 1; i <= nBinsX; i++) ccdb_sum += tagh_fadc_time_offsets[i-1];
      double c1_adcOffset = 0.0;
      outFile.open(prefix + "tagh_adc_timing_offsets.txt");
      for (int i = 1; i <= nBinsX; i++) {
         if (tagh_counter_quality[i-1] == 0.0) {
            outFile << i << " " << 0 << endl;
            continue;
         }
         int tdc_slot = GetF1TDCslotTAGH(i);
         double delta = selectedTAGHOffset->GetBinContent(i);
         if (useRF) delta *= RF_Period;
         if (ccdb_sum > 0.0 && fabs(delta - mpDelta[tdc_slot-1]) > limit) {
            delta = mpDelta[tdc_slot-1];
         }
         double ccdb = tagh_fadc_time_offsets[i-1];
         double offset = ccdb + delta;
         if (i == 1) c1_adcOffset = offset;
         offset -= c1_adcOffset;
         outFile << i << " " << offset << endl;
         if (verbose) printf("ADC\t%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n", i, delta, ccdb, mpDelta[tdc_slot-1], offset);
      }
      outFile.close();

      outFile.open(prefix + "tagh_base_time.txt");
      outFile << tagh_t_base_fadc - c1_adcOffset << " " << tagh_t_base_tdc - c1_tdcOffset << endl;
      if (verbose) {
         printf("TAGH ADC Base = %f - (%f) = %f\n", tagh_t_base_fadc, c1_adcOffset, tagh_t_base_fadc - c1_adcOffset);
         printf("TAGH TDC Base = %f - (%f) = %f\n", tagh_t_base_tdc, c1_tdcOffset, tagh_t_base_tdc - c1_tdcOffset);
      }
      outFile.close();
   }

   // We can use the RF time to calibrate the SC time (Experimental for now)
   double meanSCOffset = 0.0; // In case we change the time of the SC, we need this in this scope
   if(useRF){
      TH1F * selectedSCSectorOffset = new TH1F("selectedSCSectorOffset", "Selected TDC-RF offset;Sector; Time", 30, 0.5, 30.5);
      TH1F * selectedSCSectorOffsetDistribution = new TH1F("selectedSCSectorOffsetDistribution", "Selected TDC-RF offset;Time;Entries", 100, -3.0, 3.0);
      TF1* f = new TF1("f","pol0(0)+gaus(1)", -3.0, 3.0);
      for (int sector = 1; sector <= 30; sector++){
         TH1I *scRFHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "SC_Target_RF_Compare", Form("Sector %.2i", sector));
         if (scRFHist == NULL) continue;
         //Do the fit
         TFitResultPtr fr = scRFHist->Fit("pol0", "SQ", "", -2, 2);
         double p0 = fr->Parameter(0);

         f->FixParameter(0,p0);
         f->SetParLimits(2, -2, 2);
         f->SetParLimits(3, 0, 2);
         f->SetParameter(1, 10);
         f->SetParameter(2, scRFHist->GetBinCenter(scRFHist->GetMaximumBin()));
         f->SetParameter(3, 0);

         fr = scRFHist->Fit(f, "SQ", "", -2, 2);
         double SCOffset = fr->Parameter(2);
         selectedSCSectorOffset->SetBinContent(sector, SCOffset);
         selectedSCSectorOffsetDistribution->Fill(SCOffset);
      }
      // Now write out the offsets
      meanSCOffset = selectedSCSectorOffsetDistribution->GetMean();
      if (verbose){
         cout << "Dumping SC results...\n=======================================" << endl;
         cout << "SC mean Offset = " << meanSCOffset << endl;
         cout << "TDC Offsets" << endl;
         cout << "Sector\toldValue\tValueToUse\tmeanOffset\tTotal" << endl;
      }
      outFile.open(prefix + "sc_tdc_timing_offsets.txt");
      for (int sector = 1; sector <= 30; sector++){
         outFile << sc_tdc_time_offsets[sector-1] + selectedSCSectorOffset->GetBinContent(sector) - meanSCOffset << endl;
         if (verbose) printf("%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n",sector, sc_tdc_time_offsets[sector-1], selectedSCSectorOffset->GetBinContent(sector), meanSCOffset,
               sc_tdc_time_offsets[sector-1] + selectedSCSectorOffset->GetBinContent(sector) - meanSCOffset);
      }
      outFile.close();
      if (verbose){
         cout << "ADC Offsets" << endl;
         cout << "Sector\tvalueToUse\toldValue\tmeanOffset\tTotal" << endl;
      }
      outFile.open(prefix + "sc_adc_timing_offsets.txt");
      for (int sector = 1; sector <= 30; sector++){
         outFile << sc_fadc_time_offsets[sector-1] + selectedSCSectorOffset->GetBinContent(sector) - meanSCOffset << endl;
         if (verbose) printf("%i\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\n",sector,sc_fadc_time_offsets[sector-1], selectedSCSectorOffset->GetBinContent(sector), meanSCOffset,
               sc_fadc_time_offsets[sector-1] + selectedSCSectorOffset->GetBinContent(sector) - meanSCOffset);
      }
      outFile.close();

      outFile.open(prefix + "sc_base_time.txt");
      outFile << sc_t_base_fadc - meanSCOffset << " " << sc_t_base_tdc - meanSCOffset << endl;
      if (verbose) {
         printf("SC ADC Base = %f - (%f) = %f\n", sc_t_base_fadc, meanSCOffset, sc_t_base_fadc - meanSCOffset);
         printf("SC TDC Base = %f - (%f) = %f\n", sc_t_base_tdc, meanSCOffset, sc_t_base_tdc - meanSCOffset);
      }
      outFile.close();
   }

   TH1I *this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "TRACKING", "TOF - RF Time");
   if(this1DHist != NULL){
      //Gaussian
      Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
      TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 1.5, maximum + 1.5);
      float mean = fr->Parameter(1);
      outFile.open(prefix + "tof_base_time.txt");
      if (verbose) {
         printf("TOF ADC Base = %f - (%f) - (%f) = %f\n", tof_t_base_fadc, mean, meanSCOffset, tof_t_base_fadc - mean - meanSCOffset);
         printf("TOF TDC Base = %f - (%f) - (%f) = %f\n", tof_t_base_tdc, mean, meanSCOffset, tof_t_base_tdc - mean - meanSCOffset);
      }
      outFile << tof_t_base_fadc - mean - meanSCOffset<< " " << tof_t_base_tdc - mean - meanSCOffset<< endl;
      outFile.close();
   }

   this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "TRACKING", "BCAL - RF Time");
   if(this1DHist != NULL){
      //Gaussian
      Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
      TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 5, maximum + 5);
      float mean = fr->Parameter(1);
      outFile.open(prefix + "bcal_base_time.txt");
      if (verbose) {
         printf("BCAL ADC Base = %f - (%f) - (%f) = %f\n", bcal_t_base_fadc, mean, meanSCOffset, bcal_t_base_fadc - mean - meanSCOffset);
         printf("BCAL TDC Base = %f - (%f) - (%f) = %f\n", bcal_t_base_tdc, mean, meanSCOffset, bcal_t_base_tdc - mean - meanSCOffset);
      }
      outFile << bcal_t_base_fadc - mean - meanSCOffset << " " << bcal_t_base_tdc - mean - meanSCOffset << endl; // TDC info not used
      outFile.close();
   }

   this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "TRACKING", "FCAL - RF Time");
   if(this1DHist != NULL){
      //Gaussian
      Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
      TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 5, maximum + 5);
      float mean = fr->Parameter(1);
      outFile.open(prefix + "fcal_base_time.txt");
      if (verbose) {
         printf("FCAL ADC Base = %f - (%f) - (%f) = %f\n",fcal_t_base, mean, meanSCOffset, fcal_t_base - mean - meanSCOffset);
      }
      outFile << fcal_t_base - mean - meanSCOffset<< endl; 
      outFile.close();
   }

   this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "TRACKING", "Earliest CDC Time Minus Matched SC Time");
   if(this1DHist != NULL){
      //Gaussian
      Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
      TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 15, maximum + 10);
      float mean = fr->Parameter(1);
      outFile.open(prefix + "cdc_base_time.txt");
      if (verbose) {
         printf("CDC ADC Base = %f - (%f) - (%f) = %f\n",cdc_t_base, mean, meanSCOffset, cdc_t_base - mean - meanSCOffset);
      }
      outFile << cdc_t_base - mean - meanSCOffset << endl;
      outFile.close();
   }

   // We want to account for any residual difference between the cathode and anode times.
   double FDC_ADC_Offset = 0.0, FDC_TDC_Offset = 0.0; 
   this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "FDC", "FDCHit Cathode time;1");
    if(this1DHist != NULL){
        Int_t firstBin = this1DHist->FindFirstBinAbove( 1 , 1); // Find first bin with content above 1 in the histogram
        for (int i = 0; i <= 16; i++){
            if ((firstBin + i) > 0) this1DHist->SetBinContent((firstBin + i), 0);
        }
        //Fit a gaussian to the left of the main peak
        Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
        TF1 *f = new TF1("f", "gaus");
        f->SetParameters(100, maximum, 20);
        //this1DHist->Rebin(2);
        TFitResultPtr fr = this1DHist->Fit(f, "S", "", maximum - 10, maximum + 7); // Cant fix value at end of range
        double mean = fr->Parameter(1);
        float sigma = fr->Parameter(2);
        FDC_ADC_Offset = mean;
        delete f;
    }

    this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "FDC", "FDCHit Wire time;1");
    if(this1DHist != NULL){
        Int_t firstBin = this1DHist->FindLastBinAbove( 1 , 1); // Find first bin with content above 1 in the histogram
        for (int i = 0; i <= 25; i++){
            if ((firstBin + i) > 0) this1DHist->SetBinContent((firstBin + i), 0);
        }
        //Fit a gaussian to the left of the main peak
        Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
        TF1 *f = new TF1("f", "gaus");
        f->SetParameters(100, maximum, 20);
        TFitResultPtr fr = this1DHist->Fit(f, "S", "", maximum - 10, maximum + 5); // Cant fix value at end of range
        double mean = fr->Parameter(1);
        float sigma = fr->Parameter(2);
        FDC_TDC_Offset = mean;
        delete f;
    }
    double FDC_ADC_TDC_Offset = FDC_ADC_Offset - FDC_TDC_Offset;

   this1DHist = ExtractTrackBasedTimingNS::Get1DHistogram("HLDetectorTiming", "TRACKING", "Earliest Flight-time Corrected FDC Time");
   if(this1DHist != NULL){
      //Landau
      Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
      TFitResultPtr fr = this1DHist->Fit("landau", "S", "", maximum - 2.5, maximum + 4);
      float MPV = fr->Parameter(1);
      outFile.open(prefix + "fdc_base_time.txt");
      if (verbose) {
         printf("FDC ADC Base = %f - (%f) - (%f) - (%f) = %f\n",fdc_t_base_fadc, MPV, meanSCOffset, FDC_ADC_TDC_Offset, fdc_t_base_fadc - MPV - meanSCOffset - FDC_ADC_TDC_Offset);
         printf("FDC TDC Base = %f - (%f) - (%f) = %f\n",fdc_t_base_tdc, MPV, meanSCOffset, fdc_t_base_tdc - MPV - meanSCOffset);
      }
      outFile << fdc_t_base_fadc - MPV - meanSCOffset - FDC_ADC_TDC_Offset << " " << fdc_t_base_tdc - MPV - meanSCOffset << endl;
      outFile.close();
   }

   ExtractTrackBasedTimingNS::thisFile->Write();
   return;
}
Beispiel #8
0
void runcorr(int condor_iter, int trackqual, string flist = "", string tag = "", int nmin = 220, int nmax = 1000, float pttrigmin = 1, float pttrigmax = 2, float ptassmin = 1, float ptassmax = 1)
{

  const int nptbins = 1;
  const int ncentbins = 1;
  const int najbins = 1;
  
  string buffer;
  vector<string> listoffiles;
  int nlines = 0;
  // ifstream infile("sortedforests.txt");
  // ifstream infile("doeproposalforests.txt");
  // ifstream infile("PA2013_PromptReco_Json_FullTrack12_v84_prod2.txt");
  // ifstream infile("PA2013_PromptReco_Json_FullTrack12_v84_prod2_MIT.txt");
  // ifstream infile("HIMinBiasUPC_PbPbUPC_pptracking_452p1_forest_v2.txt");
  ifstream infile(flist.data());
  if (!infile.is_open()) {
    cout << "Error opening file. Exiting." << endl;
    return;
  } else {
    while (!infile.eof()) {
      infile >> buffer;
      listoffiles.push_back(buffer);
      nlines++;
    }
  }
  bool dostdhists = (condor_iter%(nptbins * ncentbins * najbins) == 0);
  int ptbin = condor_iter % nptbins;
  int centbin = (condor_iter / nptbins) % ncentbins;
  int ajbin = (condor_iter / (nptbins * ncentbins)) % najbins;
  int filenum = (condor_iter / (nptbins * ncentbins * najbins));
  cout << "ipt: " << ptbin << " icent: " << centbin << " iaj: " << ajbin << " filenum: " << filenum << " dostdhists: " << dostdhists << endl;
 
  // int nmin = 220 , nmax = 1000, one = 1;
  //! for first iteration of forest production
  /*
  if(filenum==0) { nmin = 110 ; nmax = 1000; }
  if(filenum==1) { nmin = 90  ; nmax = 110 ; }
  if(filenum>1 ) { nmin = 0   ; nmax = 35  ; }
  if(filenum>9 ) { nmin = 35  ; nmax = 90  ; }
  */
  //! for second iteration of forest production
  // /*
  // if(filenum<24 ) { nmin = 90  ; nmax = 110 ; }
  // if(filenum<22 ) { nmin = 35  ; nmax = 90  ; }
  // if(filenum<12 ) { nmin = 110 ; nmax = 1000; }
  // if(filenum<10 ) { nmin = 0   ; nmax = 35  ; }
  // */
  //! for second iteration of forest production
  /*
  if(filenum<26 ) { nmin = 90  ; nmax = 110 ; }
  if(filenum<23 ) { nmin = 35  ; nmax = 90  ; }
  if(filenum<13)  { nmin = 110 ; nmax = 1000; }
  if(filenum<10)  { nmin = 0   ; nmax = 35  ; }
  */
  corrana(listoffiles[filenum].data(),trackqual);
  
  
  // double pttriglow[] =  {1   ,14 ,16 ,20, 1};
  // double pttrighigh[] = {2   ,16 ,20 ,24, 3};
  // double ptasslow[] =   {1   ,1  ,1  ,1 , 1};
  // double ptasshigh[] =  {2   ,2  ,2  ,2 , 3};
  
  
  int centmin[] = {0,4,8,12,16,20,24,28,32};
  int centmax[] = {41,8,12,16,20,24,28,32,36};
  // TFile * outf = new TFile(Form("%s_trkqaul%d_nmin%d_nmax%d_tptmin%d_tptmax%d_aptmin%d_aptmax%d_%d.root",tag.data(),trackqual,nmin,nmax,(int)pttrigmin/one,(int)pttrigmax/one,(int)ptassmin/one,(int)ptassmax/one,filenum),"recreate");
  cout<<Form("%s_trkqaul%d_nmin%d_nmax%d_tptmin%d_tptmax%d_aptmin%d_aptmax%d_%d.root",tag.data(),trackqual,nmin,nmax,(int)pttrigmin,(int)pttrigmax,(int)ptassmin,(int)ptassmax,filenum)<<endl;
  TFile * outf = new TFile(Form("%s_trkqaul%d_nmin%d_nmax%d_tptmin%d_tptmax%d_aptmin%d_aptmax%d_%d.root",tag.data(),trackqual,nmin,nmax,(int)pttrigmin,(int)pttrigmax,(int)ptassmin,(int)ptassmax,filenum),"recreate");
  
  // int i = 0;
  int cent = 0;

  cout<<"cent iteration "<<cent<<endl;
  TH2D * ttsig = TrackTrackSignal(pttrigmin,pttrigmax,ptassmin,ptassmax,centmin[cent],centmax[cent],nmin,nmax);
  TH2D * ttbak = TrackTrackBackground(pttrigmin,pttrigmax,ptassmin,ptassmax,centmin[cent],centmax[cent],nmin,nmax);

  TH1I * hntottrig = new TH1I(Form("nttottrig_trg%d_%d_ass%d_%d_cmin%d_cmax%d",(int)pttrigmin,(int)pttrigmax,(int)ptassmin,(int)ptassmax,centmin[cent],centmax[cent]),"",1,0.5,1.5);
  int myntottrig = GetNTotTrig();
  hntottrig->Fill(1,myntottrig);
  cout<<"ntottrig: "<<myntottrig<<endl;

  TH2D * ttcorr = (TH2D*)ttsig->Clone(Form("corr_trg%d_%d_ass%d_%d_cmin%d_cmax%d",(int)pttrigmin,(int)pttrigmax,(int)ptassmin,(int)ptassmax,centmin[cent],centmax[cent]));
  ttcorr->Divide(ttbak);
  ttcorr->Scale(ttbak->GetBinContent(ttbak->FindBin(0,0)));
  ttcorr->Scale(1/0.0594998609); //! bin width
  ttcorr->GetXaxis()->SetRange(ttcorr->GetXaxis()->FindBin(-4.0),ttcorr->GetXaxis()->FindBin(4.0));
  ttcorr->GetYaxis()->SetRange(ttcorr->GetYaxis()->FindBin(-3.1415926/2.0),ttcorr->GetYaxis()->FindBin(3*3.1415926/2.0));
  
  outf->Write();
  outf->Close();
}
void ExtractTrackBasedTiming(int runNumber){

    TString fileName = Form ("Run%i/TrackBasedTiming.root", runNumber);
    TString prefix = Form ("Run%i/constants/TrackBasedTiming/",runNumber);
    TString inputPrefix = Form ("Run%i/constants/TDCADCTiming/",runNumber);

    thisFile = TFile::Open( fileName , "UPDATE");
    if (thisFile == 0) {
        cout << "Unable to open file " << fileName.Data() << "...Exiting" << endl;
        return;
    }

    //We need the existing constants, The best we can do here is just read them from the file.
    vector<double> sc_tdc_time_offsets;
    vector<double> sc_fadc_time_offsets;
    vector<double> tof_tdc_time_offsets;
    vector<double> tof_fadc_time_offsets;
    vector<double> tagm_tdc_time_offsets;
    vector<double> tagm_fadc_time_offsets;
    vector<double> tagh_tdc_time_offsets;
    vector<double> tagh_fadc_time_offsets;

    double sc_t_base_fadc;
    double sc_t_base_tdc;
    double tof_t_base_fadc;
    double tof_t_base_tdc;
    double bcal_t_base_fadc;
    double bcal_t_base_tdc;
    double tagm_t_base_fadc;
    double tagm_t_base_tdc;
    double tagh_t_base_fadc;
    double tagh_t_base_tdc;
    double fcal_t_base;
    double cdc_t_base;

    ifstream inFile;
    inFile.open(inputPrefix + "sc_tdc_timing_offsets.txt");
    string line;
    if (inFile.is_open()){
        while (getline (inFile, line)){
            sc_tdc_time_offsets.push_back(atof(line.data()));
        }
    }
    inFile.close();

    ifstream inFile;
    inFile.open(inputPrefix + "sc_adc_timing_offsets.txt");
    string line;
    if (inFile.is_open()){
        while (getline (inFile, line)){
            sc_fadc_time_offsets.push_back(atof(line.data()));
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "tof_tdc_timing_offsets.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            tof_tdc_time_offsets.push_back(atof(line.data()));
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "tof_adc_timing_offsets.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            tof_fadc_time_offsets.push_back(atof(line.data()));
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "tagm_tdc_timing_offsets.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            double r, c, offset;
            while (iss>>r>>c>>offset){
                //if (row != 0) continue;
                tagm_tdc_time_offsets.push_back(offset);
            }
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "tagm_adc_timing_offsets.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            double r, c, offset;
            while (iss>>r>>c>>offset){
                //if (row != 0) continue;
                tagm_fadc_time_offsets.push_back(offset);
            }
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "tagh_tdc_timing_offsets.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            double counter, offset;
            while (iss>>counter>>offset){
                tagh_tdc_time_offsets.push_back(offset);
            }
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "tagh_adc_timing_offsets.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            double counter, offset;
            while (iss>>counter>>offset){
                tagh_fadc_time_offsets.push_back(offset);
            }
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "tof_base_time.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            iss>>tof_t_base_fadc>>tof_t_base_tdc;
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "sc_base_time.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            iss>>sc_t_base_fadc>>sc_t_base_tdc;
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "bcal_base_time.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            double adc_offset, tdc_offset;
            iss>>adc_offset>>tdc_offset; // TDC not used currently
            bcal_t_base_fadc = adc_offset;
            bcal_t_base_tdc = tdc_offset;
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "tagm_base_time.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            double adc_offset, tdc_offset;
            iss>>adc_offset>>tdc_offset; // TDC not used currently
            tagm_t_base_fadc = adc_offset;
            tagm_t_base_tdc = tdc_offset;
        }
    }

    inFile.close();
    inFile.open(inputPrefix + "tagh_base_time.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            double adc_offset, tdc_offset;
            iss>>adc_offset>>tdc_offset; // TDC not used currently
            tagh_t_base_fadc = adc_offset;
            tagh_t_base_tdc = tdc_offset;
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "fcal_base_time.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            iss>>fcal_t_base; 
        }
    }
    inFile.close();

    inFile.open(inputPrefix + "cdc_base_time.txt");
    if (inFile.is_open()){
        while (getline (inFile, line)){
            istringstream iss(line);
            iss>>cdc_t_base; 
        }
    }
    inFile.close();


    // Do our final step in the timing alignment with tracking

    //When the RF is present we can try to simply pick out the correct beam bucket for each of the runs
    //First just a simple check to see if we have the appropriate data
    bool useRF = false;
    double RF_Period = 4.0080161;
    TH1I *testHist = Get1DHistogram("HLDetectorTiming", "TAGH_TDC_RF_Compare","Counter ID 001");
    if (testHist != NULL){ // Not great since we rely on channel 1 working, but can be craftier later.
        useRF = true;
    }
    ofstream outFile;
    TH2I *thisHist; 
    thisHist = Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGM - SC Target Time");
    if (useRF) thisHist = Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGM - RFBunch Time");
    if (thisHist != NULL){
        //Statistics on these histograms are really quite low we will have to rebin and do some interpolation
        outFile.open(prefix + "tagm_tdc_timing_offsets.txt", ios::out | ios::trunc);
        outFile.close(); // clear file
        outFile.open(prefix + "tagm_adc_timing_offsets.txt", ios::out | ios::trunc);
        outFile.close(); // clear file
        int nBinsX = thisHist->GetNbinsX();
        int nBinsY = thisHist->GetNbinsY();
        TH1D * selectedTAGMOffset = new TH1D("selectedTAGMOffset", "Selected TAGM Offset; Column; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5);
        TH1I * TAGMOffsetDistribution = new TH1I("TAGMOffsetDistribution", "TAGM Offset; TAGM Offset [ns]; Entries", 500, -250, 250);
        for (int i = 1 ; i <= nBinsX; i++){ 
            TH1D *projY = thisHist->ProjectionY("temp", i, i);
            // Scan over the histogram
            //chose the correct number of bins based on the histogram
            float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
            float timeWindow = 3; //ns (Full Width)
            int binWindow = int(timeWindow / nsPerBin);
            double maxEntries = 0;
            double maxMean = 0;
            for (int j = 1 ; j <= projY->GetNbinsX();j++){
                int minBin = j;
                int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX();
                double sum = 0, nEntries = 0;
                for (int bin = minBin; bin <= maxBin; bin++){
                    sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
                    nEntries += projY->GetBinContent(bin);
                    if (bin == maxBin){
                        if (nEntries > maxEntries) {
                            maxMean = sum / nEntries;
                            maxEntries = nEntries;
                        }
                    } 
                }
            }
            //In the case there is RF, our job is to pick just the number of the correct beam bunch, so that's really all we need.
            if(useRF) {
                int beamBucket = int((maxMean / RF_Period) + 0.5); // +0.5 to handle rounding correctly
                selectedTAGMOffset->SetBinContent(i, beamBucket);
                TAGMOffsetDistribution->Fill(beamBucket);
            }
            else{
                selectedTAGMOffset->SetBinContent(i, maxMean);
                TAGMOffsetDistribution->Fill(maxMean);
            }
        }
        /*
        if (!useRF){
            //TFitResultPtr fr1 = selectedTAGMOffset->Fit("pol1", "SQ", "", 0.5, nBinsX + 0.5);
            TFitResultPtr fr1 = selectedTAGMOffset->Fit("pol1", "SQ", "", 5, 50);

            for (int i = 1 ; i <= nBinsX; i++){
                double x0 = fr1->Parameter(0);
                double x1 = fr1->Parameter(1);
                //double x2 = fr1->Parameter(2);
                //double fitResult = x0 + i*x1 + i*i*x2;
                double fitResult = x0 + i*x1;

                double outlierCut = 20;
                double valueToUse = selectedTAGMOffset->GetBinContent(i);
                if (fabs(selectedTAGMOffset->GetBinContent(i) - fitResult) > outlierCut && valueToUse != 0.0){
                    valueToUse = fitResult;
                }

                selectedTAGMOffset->SetBinContent(i, valueToUse);
                if (valueToUse != 0 ) TAGMOffsetDistribution->Fill(valueToUse);
            }
        }
*/
        double meanOffset = TAGMOffsetDistribution->GetMean();
        // This might be in units of beam bunches, so we need to convert
        if (useRF) meanOffset *= RF_Period;
        /*
           for (int i = 1 ; i <= nBinsX; i++){
           double valueToUse = selectedTAGMOffset->GetBinContent(i);
           if (useRF) valueToUse *= RF_Period;
           if (valueToUse == 0) valueToUse = meanOffset;
           outFile.open(prefix + "tagm_tdc_timing_offsets.txt", ios::out | ios::app);
           outFile << "0 " << i << " " << valueToUse + tagm_tdc_time_offsets[i-1] - meanOffset<< endl;
           if (i == 7 || i == 25 || i == 79 || i == 97){
           for(int j = 1; j <= 5; j++){
           outFile << j << " " << i << " " << valueToUse + tagm_tdc_time_offsets[i-1] - meanOffset<< endl;
           }
           }
           outFile.close();
        // Apply the same shift to the adc offsets
        outFile.open(prefix + "tagm_adc_timing_offsets.txt", ios::out | ios::app);
        outFile << "0 " << i << " " << valueToUse + tagm_fadc_time_offsets[i-1] - meanOffset<< endl;
        if (i == 7 || i == 25 || i == 79 || i == 97){
        for(int j = 1; j <= 5; j++){
        outFile << j << " " << i << " " << valueToUse + tagm_fadc_time_offsets[i-1] - meanOffset<< endl;
        }
        }
        outFile.close();
        }
        */

        outFile.open(prefix + "tagm_adc_timing_offsets.txt", ios::out);
        //for (int i = 1 ; i <= nBinsX; i++){
        // Loop over rows
        for (unsigned int column = 1; column <= 102; column++){
            int index = GetCCDBIndexTAGM(column, 0);
            double valueToUse = selectedTAGMOffset->GetBinContent(index);
            if (useRF) valueToUse *= RF_Period;
            if (valueToUse == 0) valueToUse = meanOffset;
            outFile << "0 " << column << " " << valueToUse + tagm_fadc_time_offsets[index-1] - meanOffset<< endl;
            if (column == 9 || column == 27 || column == 81 || column == 99){
                for (unsigned int row = 1; row <= 5; row++){
                    index = GetCCDBIndexTAGM(column, row);
                    valueToUse = selectedTAGMOffset->GetBinContent(index);
                    if (useRF) valueToUse *= RF_Period;
                    if (valueToUse == 0) valueToUse = meanOffset;
                    outFile << row << " " << column << " " << valueToUse + tagm_fadc_time_offsets[index-1] - meanOffset<< endl;
                }
            }
        }
        outFile.close();

        outFile.open(prefix + "tagm_tdc_timing_offsets.txt", ios::out);
        //for (int i = 1 ; i <= nBinsX; i++){
        // Loop over rows
        for (unsigned int column = 1; column <= 102; column++){
            int index = GetCCDBIndexTAGM(column, 0);
            double valueToUse = selectedTAGMOffset->GetBinContent(index);
            if (useRF) valueToUse *= RF_Period;
            if (valueToUse == 0) valueToUse = meanOffset;
            outFile << "0 " << column << " " << valueToUse + tagm_tdc_time_offsets[index-1] - meanOffset << endl;
            if (column == 9 || column == 27 || column == 81 || column == 99){
                for (unsigned int row = 1; row <= 5; row++){
                    index = GetCCDBIndexTAGM(column, row);
                    valueToUse = selectedTAGMOffset->GetBinContent(index);
                    if (useRF) valueToUse *= RF_Period;
                    if (valueToUse == 0) valueToUse = meanOffset;
                    outFile << row << " " << column << " " << valueToUse + tagm_tdc_time_offsets[index-1] - meanOffset << endl;
                }
            }
        }
        outFile.close();
        outFile.open(prefix + "tagm_base_time.txt", ios::out);
        outFile << tagm_t_base_fadc - meanOffset << " " << tagm_t_base_tdc - meanOffset << endl;
        outFile.close();

    }

    thisHist = Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGH - SC Target Time");
    if (useRF) thisHist = Get2DHistogram("HLDetectorTiming", "TRACKING", "TAGH - RFBunch Time");
    if(thisHist != NULL){
        outFile.open(prefix + "tagh_tdc_timing_offsets.txt", ios::out | ios::trunc);
        outFile.close(); // clear file
        outFile.open(prefix + "tagh_adc_timing_offsets.txt", ios::out | ios::trunc);
        outFile.close(); // clear file

        int nBinsX = thisHist->GetNbinsX();
        int nBinsY = thisHist->GetNbinsY();
        TH1D * selectedTAGHOffset = new TH1D("selectedTAGHOffset", "Selected TAGH Offset; ID; Offset [ns]", nBinsX, 0.5, nBinsX + 0.5);
        TH1I * TAGHOffsetDistribution = new TH1I("TAGHOffsetDistribution", "TAGH Offset; TAGH Offset [ns]; Entries", 500, -250, 250);
        for (int i = 1 ; i <= nBinsX; i++){
            TH1D *projY = thisHist->ProjectionY("temp", i, i);
            // Scan over the histogram
            //chose the correct number of bins based on the histogram
            float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
            float timeWindow = 2; //ns (Full Width)
            int binWindow = int(timeWindow / nsPerBin);

            double maxEntries = 0;
            double maxMean = 0;
            for (int j = 1 ; j <= projY->GetNbinsX();j++){
                int minBin = j;
                int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX();
                double sum = 0; 
                double nEntries = 0;
                for (int bin = minBin; bin <= maxBin; bin++){
                    sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
                    nEntries += projY->GetBinContent(bin);
                    if (bin == maxBin){
                        if (nEntries > maxEntries){
                            maxMean = sum / nEntries;
                            maxEntries = nEntries;
                        }
                    }
                }
            }

            if(useRF) {
                int beamBucket = int((maxMean / RF_Period) + 0.5); // +0.5 to handle rounding correctly
                selectedTAGHOffset->SetBinContent(i, beamBucket);
                TAGHOffsetDistribution->Fill(beamBucket);
            }
            else{
                selectedTAGHOffset->SetBinContent(i, maxMean);
            }
            /*
               outFile.open("tagh_tdc_timing_offsets.txt", ios::out | ios::app);
               outFile << i << " " << maxMean + tagh_tdc_time_offsets[i] << endl;
               outFile.close();
               outFile.open("tagh_adc_timing_offsets.txt", ios::out | ios::app);
               outFile << i << " " << maxMean + tagh_fadc_time_offsets[i] << endl;
               outFile.close();
               */
        }

        // Fit 1D histogram. If value is far from the fit use the fitted value
        // Two behaviors above and below microscope
        // This isn't working well, so removing...
        /*
           TFitResultPtr fr1 = selectedTAGHOffset->Fit("pol2", "SQ", "", 0.5, 131.5);
           TFitResultPtr fr2 = selectedTAGHOffset->Fit("pol2", "SQ", "", 182.5, 274.5);        

           for (int i = 1 ; i <= nBinsX; i++){
           double fitResult = 0.0;
           if (i < 150){
           double x0 = fr1->Parameter(0);
           double x1 = fr1->Parameter(1);
           double x2 = fr1->Parameter(2);
           fitResult = x0 + i*x1 + i*i*x2;
           }
           else{
           double x0 = fr2->Parameter(0);
           double x1 = fr2->Parameter(1);
           double x2 = fr2->Parameter(2);
           fitResult = x0 + i*x1 + i*i*x2;
           }

           double outlierCut = 7;
           double valueToUse = selectedTAGHOffset->GetBinContent(i);
           if (fabs(selectedTAGHOffset->GetBinContent(i) - fitResult) > outlierCut && valueToUse != 0.0){
           valueToUse = fitResult;
           }

           selectedTAGHOffset->SetBinContent(i, valueToUse);
           if(valueToUse != 0) TAGHOffsetDistribution->Fill(valueToUse);
           }
           */
        double meanOffset = TAGHOffsetDistribution->GetMean();
        if (useRF) meanOffset *= RF_Period;
        for (int i = 1 ; i <= nBinsX; i++){
            valueToUse = selectedTAGHOffset->GetBinContent(i);
            if (useRF) valueToUse *= RF_Period;
            if (valueToUse == 0) valueToUse = meanOffset;
            outFile.open(prefix + "tagh_tdc_timing_offsets.txt", ios::out | ios::app);
            outFile << i << " " << valueToUse + tagh_tdc_time_offsets[i-1] - meanOffset << endl;
            outFile.close();
            outFile.open(prefix + "tagh_adc_timing_offsets.txt", ios::out | ios::app);
            outFile << i << " " << valueToUse + tagh_fadc_time_offsets[i-1] - meanOffset << endl;
            outFile.close();
        }

        outFile.open(prefix + "tagh_base_time.txt", ios::out);
        outFile << tagh_t_base_fadc - meanOffset << " " << tagh_t_base_tdc - meanOffset << endl;
        outFile.close();
    }

    // We can use the RF time to calibrate the SC time (Experimental for now)
    double meanSCOffset = 0.0; // In case we change the time of the SC, we need this in this scope
    if(useRF){
        TH1F * selectedSCSectorOffset = new TH1F("selectedSCSectorOffset", "Selected TDC-RF offset;Sector; Time", 30, 0.5, 30.5);
        TH1F * selectedSCSectorOffsetDistribution = new TH1F("selectedSCSectorOffsetDistribution", "Selected TDC-RF offset;Time;Entries", 100, -3.0, 3.0);
        TF1* f = new TF1("f","pol0(0)+gaus(1)", -3.0, 3.0);
        for (int sector = 1; sector <= 30; sector++){
            TH1I *scRFHist = Get1DHistogram("HLDetectorTiming", "SC_Target_RF_Compare", Form("Sector %.2i", sector));
            if (scRFHist == NULL) continue;
            //Do the fit
            TFitResultPtr fr = scRFHist->Fit("pol0", "SQ", "", -2, 2);
            double p0 = fr->Parameter(0);

            f->FixParameter(0,p0);
            f->SetParLimits(2, -2, 2);
            f->SetParLimits(3, 0, 2);
            f->SetParameter(1, 10);
            f->SetParameter(2, scRFHist->GetBinCenter(scRFHist->GetMaximumBin()));
            f->SetParameter(3, 0);

            fr = scRFHist->Fit(f, "SQ", "", -2, 2);
            double SCOffset = fr->Parameter(2);
            selectedSCSectorOffset->SetBinContent(sector, SCOffset);
            selectedSCSectorOffsetDistribution->Fill(SCOffset);
        }
        // Now write out the offsets
        meanSCOffset = selectedSCSectorOffsetDistribution->GetMean();
        outFile.open(prefix + "sc_tdc_timing_offsets.txt");
        for (int sector = 1; sector <= 30; sector++){
            outFile << sc_tdc_time_offsets[sector-1] + selectedSCSectorOffset->GetBinContent(sector) - meanSCOffset << endl;
        }
        outFile.close();
        outFile.open(prefix + "sc_adc_timing_offsets.txt");
        for (int sector = 1; sector <= 30; sector++){
            outFile << sc_fadc_time_offsets[sector-1] + selectedSCSectorOffset->GetBinContent(sector) - meanSCOffset << endl;
        }
        outFile.close();
        
        outFile.open(prefix + "sc_base_time.txt");
        outFile << sc_t_base_fadc - meanSCOffset << " " << sc_t_base_tdc - meanSCOffset << endl;
        outFile.close();
    }

    TH1I *this1DHist = Get1DHistogram("HLDetectorTiming", "TRACKING", "TOF - SC Target Time");
    if(this1DHist != NULL){
        //Gaussian
        Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
        TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 1.5, maximum + 1.5);
        float mean = fr->Parameter(1);
        outFile.open(prefix + "tof_base_time.txt");
        outFile << tof_t_base_fadc - mean - meanSCOffset<< " " << tof_t_base_tdc - mean - meanSCOffset<< endl;
        outFile.close();
    }

    this1DHist = Get1DHistogram("HLDetectorTiming", "TRACKING", "BCAL - SC Target Time");
    if(this1DHist != NULL){
        //Gaussian
        Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
        TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 5, maximum + 5);
        float mean = fr->Parameter(1);
        outFile.open(prefix + "bcal_base_time.txt");
        outFile << bcal_t_base_fadc - mean - meanSCOffset << " " << bcal_t_base_tdc - mean - meanSCOffset << endl; // TDC info not used
        outFile.close();
    }

    this1DHist = Get1DHistogram("HLDetectorTiming", "TRACKING", "FCAL - SC Target Time");
    if(this1DHist != NULL){
        //Gaussian
        Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
        TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 5, maximum + 5);
        float mean = fr->Parameter(1);
        outFile.open(prefix + "fcal_base_time.txt");
        outFile << fcal_t_base - mean - meanSCOffset<< endl; 
        outFile.close();
    }

    this1DHist = Get1DHistogram("HLDetectorTiming", "TRACKING", "Earliest CDC Time Minus Matched SC Time");
    if(this1DHist != NULL){
        //Gaussian
        Double_t maximum = this1DHist->GetBinCenter(this1DHist->GetMaximumBin());
        TFitResultPtr fr = this1DHist->Fit("gaus", "S", "", maximum - 15, maximum + 10);
        float mean = fr->Parameter(1);
        outFile.open(prefix + "cdc_base_time.txt");
        outFile << cdc_t_base - mean - meanSCOffset << endl;
        outFile.close();
    }
    thisFile->Write();
    return;
    }
// Do the extraction of the actual constants
void ExtractTimeOffsetsAndCEff(int run = 2931, TString filename = "hd_root.root") {

    // Open our input and output file
    thisFile = TFile::Open(filename);
    TFile *outputFile = TFile::Open("BCALTimeOffsetAndCEff_Results.root", "RECREATE");
    outputFile->mkdir("Fits");
    outputFile->mkdir("ResultOverview");

    // Check to make sure it is open
    if (thisFile == 0) {
        cout << "Unable to open file " << fileName.Data() << "...Exiting" << endl;
        return;
    }

    // We need to have the value of C_effective used for the position determination to get the time offsets
    double C_eff = 16.75; // cm/ns

    // Since we are updating existing constants we will need their current values. We can pipe them in from the CCDB...
    // We need a place to store them...
    double tdc_offsets[1152];
    double adc_offsets[1536];

    //Pipe the current constants into this macro
    //NOTE: This dumps the "LATEST" values. If you need something else, modify this script.
    char command[100];
    sprintf(command, "ccdb dump /BCAL/TDC_offsets:%i:default", run);
    FILE* locInputFile = gSystem->OpenPipe(command, "r");
    if(locInputFile == NULL)
        return 0;
    //get the first (comment) line
    char buff[1024];
    if(fgets(buff, sizeof(buff), locInputFile) == NULL)
        return 0;
    //get the remaining lines
    double time;
    int counter = 0;
    while(fgets(buff, sizeof(buff), locInputFile) != NULL) {
        istringstream locConstantsStream(buff);
        locConstantsStream >> time;
        cout << "TDC Time Offset = " << time << endl;
        tdc_offsets[counter] = time;
        counter++;
    }
    if (counter != 1152) cout << "Wrong number of TDC entries (" << counter << " != 1152)?" << endl;
    //Close the pipe
    gSystem->ClosePipe(locInputFile);

    sprintf(command, "ccdb dump /BCAL/ADC_timing_offsets:%i:default", run);
    locInputFile = gSystem->OpenPipe(command, "r");
    if(locInputFile == NULL)
        return 0;
    //get the first (comment) line
    char buff[1024];
    if(fgets(buff, sizeof(buff), locInputFile) == NULL)
        return 0;
    //get the remaining lines
    counter = 0;
    while(fgets(buff, sizeof(buff), locInputFile) != NULL) {
        istringstream locConstantsStream(buff);
        locConstantsStream >> time;
        cout << "ADC Time Offset = " << time << endl;
        adc_offsets[counter] = time;
        counter++;
    }
    if (counter != 1536) cout << "Wrong number of ADC entries (" << counter << " != 1536)?" << endl;
    //Close the pipe
    gSystem->ClosePipe(locInputFile);

    // This stream will be for outputting the results in a format suitable for the CCDB
    // Will wait to open until needed
    ofstream adcOffsetFile, tdcOffsetFile;
    adcOffsetFile.open("ADCOffsetsBCAL.txt");
    tdcOffsetFile.open("TDCOffsetsBCAL.txt");

    // Declaration of the fit funtion
    TF1 *f1 = new TF1("f1", "[0]+[1]*x", -200, 200);
    f1->SetParLimits(0, -20.0, 20.0);
    f1->SetParLimits(1, 0.85, 1.15);
    outputFile->cd("ResultOverview");
    // Make some histograms to get the distributions of the fit parameters
    TH1I *h1_c0 = new TH1I("h1_c0", "Distribution of parameter c_{0}", 100, -15, 15);
    TH1I *h1_c1 = new TH1I("h1_c1", "Distribution of parameter c_{1}", 100, 0.85, 1.15);
    TH1F *h1_c0_all = new TH1F ("h1_c0_all", "Value of c0; CCDB Index; c0 [cm]", 768, 0.5, 768.5);
    TH1F *h1_c1_all = new TH1F ("h1_c1_all", "Value of c1; CCDB Index; c1 [cm]", 768, 0.5, 768.5);
    TH2I *h2_c0_c1 = new TH2I("h2_c0_c1", "c_{1} Vs. c_{0}; c_{0}; c_{1}", 100, -15, 15, 100, 0.85, 1.15);

    // Fit the global offset histogram to get the per channel global offset
    double globalOffset[768];
    TH1D * selectedBCALOffset = new TH1D("selectedBCALOffset", "Selected Global BCAL Offset; CCDB Index; Offset [ns]", 768, 0.5, 768 + 0.5);
    TH1I * BCALOffsetDistribution = new TH1I("BCALOffsetDistribution", "Global BCAL Offset; Global Offset [ns]; Entries", 100, -10, 10);

    thisHist = Get2DHistogram("BCAL_Global_Offsets", "Target Time", "Target Time Minus RF Time Vs. Cell Number");
    if(thisHist != NULL) {
        int nBinsX = thisHist->GetNbinsX();
        int nBinsY = thisHist->GetNbinsY();
        for (int i = 1 ; i <= nBinsX; i++) {
            TH1D *projY = thisHist->ProjectionY("temp", i, i);
            // Scan over the histogram
            float nsPerBin = (projY->GetBinCenter(projY->GetNbinsX()) - projY->GetBinCenter(1)) / projY->GetNbinsX();
            float timeWindow = 0.5; //ns (Full Width)
            int binWindow = int(timeWindow / nsPerBin);
            double maxEntries = 0;
            double maxMean = 0;
            for (int j = 1 ; j <= projY->GetNbinsX(); j++) {
                int minBin = j;
                int maxBin = (j + binWindow) <= projY->GetNbinsX() ? (j + binWindow) : projY->GetNbinsX();
                double sum = 0, nEntries = 0;
                for (int bin = minBin; bin <= maxBin; bin++) {
                    sum += projY->GetBinContent(bin) * projY->GetBinCenter(bin);
                    nEntries += projY->GetBinContent(bin);
                    if (bin == maxBin) {
                        if (nEntries > maxEntries) {
                            maxMean = sum / nEntries;
                            maxEntries = nEntries;
                        }
                    }
                }
            }
            globalOffset[i-1] = maxMean;
            selectedBCALOffset->SetBinContent(i, maxMean);
            BCALOffsetDistribution->Fill(maxMean);
        }
    }

    outputFile->cd("Fits");
    // Now we want to loop through all available module/layer/sector and try to make a fit of each one
    for (unsigned int iModule = 1; iModule <=48; iModule++) {
        for (unsigned int iLayer = 1; iLayer <= 4; iLayer++) { // Only 3 layers with TDCs
            for (unsigned int iSector = 1; iSector <= 4; iSector++) {
                int the_cell = (iModule - 1) * 16 + (iLayer - 1) * 4 + iSector;
                int the_tdc_cell = (iModule - 1) * 12 + (iLayer - 1) * 4 + iSector; // One less layer of TDCs
                // Format the string to lookup the histogram by name
                char name[200];
                sprintf(name, "Module %.2i Layer %.2i Sector %.2i", iModule, iLayer, iSector);

                // These histograms are created on the fly in the plugin, so there is a chance that they do not exist, in which case the pointer will be NULL

                TH2I *h_offsets   = Get2DHistogram ("BCAL_TDC_Offsets", "Z Position", name);

                // Use FitSlicesY routine to extract the mean of each x bin
                TObjArray ySlices;

                if (h_offsets != NULL) {
                    h_offsets->RebinX(5);
                    TProfile *profile = h_offsets->ProfileX();
                    f1->SetParameters(0, 1); // Just out initial guess
                    TFitResultPtr fr = profile->Fit(f1, "SQR");
                    Int_t fitStatus = fr;
                    if (fitStatus == 0) {
                        double c0 = fr->Parameter(0);
                        double c0_err = fr->ParError(0);
                        double c1 = fr->Parameter(1);
                        double c1_err = fr->ParError(1);
                        if (c0 == 10.0 || c0 == -10.0 || c1 == 0.9 || c1 == 1.1) {
                            cout << "WARNING: Parameter hit limit " << name << endl;
                        }
                        h1_c0->Fill(c0);
                        h1_c1->Fill(c1);
                        h2_c0_c1->Fill(c0,c1);
                        h1_c0_all->SetBinContent(the_cell, c0);
                        h1_c0_all->SetBinError(the_cell, c0_err);
                        h1_c1_all->SetBinContent(the_cell, c1);
                        h1_c1_all->SetBinError(the_cell, c1_err);
                        adcOffsetFile << adc_offsets[(the_cell - 1) * 2] + 0.5 * c0 / C_eff + globalOffset[the_cell] << endl;
                        adcOffsetFile << adc_offsets[ the_cell*2 - 1] - 0.5 * c0 / C_eff + globalOffset[the_cell] << endl;
                        if (iLayer != 4) {
                            tdcOffsetFile << tdc_offsets[(the_tdc_cell - 1) * 2] + 0.5 * c0 / C_eff + globalOffset[the_cell] << endl;
                            tdcOffsetFile << tdc_offsets[the_tdc_cell*2 - 1] - 0.5 * c0 / C_eff + globalOffset[the_cell] << endl;
                        }
                    }
                    else {
                        cout << "WARNING: Fit Status "<< fitStatus << " for Upstream " << name << endl;
                        adcOffsetFile << adc_offsets[(the_cell - 1) * 2] + globalOffset[the_cell] << endl;
                        adcOffsetFile << adc_offsets[the_cell*2 - 1] + globalOffset[the_cell] << endl;
                        if (iLayer != 4) {
                            tdcOffsetFile << tdc_offsets[(the_tdc_cell - 1) * 2] + globalOffset[the_cell] << endl;
                            tdcOffsetFile << tdc_offsets[the_tdc_cell*2 - 1] + globalOffset[the_cell] << endl;
                        }
                    }
                }
                else {
                    adcOffsetFile << adc_offsets[ (the_cell-1) * 2] + globalOffset[the_cell] << endl;
                    adcOffsetFile << adc_offsets[  the_cell*2  - 1] + globalOffset[the_cell] << endl;
                    if (iLayer != 4) {
                        tdcOffsetFile << tdc_offsets[(the_tdc_cell -1) * 2] + globalOffset[the_cell] << endl;
                        tdcOffsetFile << tdc_offsets[ the_tdc_cell*2 - 1] + globalOffset[the_cell] << endl;
                    }
                }
            }
        }
    }
    adcOffsetFile.close();
    tdcOffsetFile.close();
    outputFile->Write();
    thisFile->Close();
    return;
}
Beispiel #11
0
void Zlumi::Loop()
{
//   In a ROOT session, you can do:
//      Root > .L Zlumi.C
//      Root > Zlumi t
//      Root > t.GetEntry(12); // Fill t data members with entry number 12
//      Root > t.Show();       // Show values of entry 12
//      Root > t.Show(16);     // Read and show values of entry 16
//      Root > t.Loop();       // Loop on all entries
//

//     This is the loop skeleton where:
//    jentry is the global entry number in the chain
//    ientry is the entry number in the current Tree
//  Note that the argument to GetEntry must be:
//    jentry for TChain::GetEntry
//    ientry for TTree::GetEntry and TBranch::GetEntry
//
//       To read only selected branches, Insert statements like:
// METHOD1:
//    fChain->SetBranchStatus("*",0);  // disable all branches
//    fChain->SetBranchStatus("branchname",1);  // activate branchname
// METHOD2: replace line
//    fChain->GetEntry(jentry);       //read all branches
//by  b_branchname->GetEntry(ientry); //read only this branch
 
 gROOT->ForceStyle();
        tdrStyle();

  if (fChain == 0) return;

int minRun=0;
int maxRun=0;
int maxLS=0;
bool forminRun=true;


//TH2I * LumiSRun = new TH2I("LumiSRun", "LS vs Run", 3000, 0., 3000., 20000, 160000., 180000.);
//TH1I * test2 = new TH1I("test2","test2", 3000,0, 3000);


Long64_t nentries = fChain->GetEntriesFast();

Long64_t nbytes = 0, nb = 0;
for (Long64_t jentry=0; jentry<nentries;jentry++) {
	Long64_t ientry = LoadTree(jentry);
	if (ientry < 0) break;
	nb = fChain->GetEntry(jentry);   nbytes += nb;


	if(forminRun && (Run!=0)){minRun=Run; forminRun=false;}
	if((Run!=0) && (Run>maxRun)){maxRun=Run;}
	if((LS!=0) && (LS>maxLS)){maxLS=LS;}
	//printf("run %i ls %i \n",Run,LS);
}
cout << nentries << " nentries \n";

TH2I *LumiSRun = new TH2I("LumiSRun", "LS vs Run", maxLS, 0, maxLS, maxRun-minRun+2, minRun-1, maxRun+1);
TH1I *Runs = new TH1I("Runs","Run", maxRun-minRun+2, minRun-1, maxRun+1);
 Runs->Sumw2();
nbytes = 0; nb = 0;
for (Long64_t jentry=0; jentry<nentries;jentry++) {
	Long64_t ientry = LoadTree(jentry);
	if (ientry < 0) break;
	nb = fChain->GetEntry(jentry);   nbytes += nb;

	LumiSRun->Fill(LS,Run);
	//printf("run %i ls %i \n",Run,LS);
	Runs->Fill(Run);
	//test2->Fill(LS);
}
	printf("minRun %i maxRun %i \n",minRun,maxRun);
LumiSRun->Draw();
 for (int h=0;h<Runs->GetNbinsX();h++){
   Runs->SetBinError(h+1,sqrt(Runs->GetBinContent(h+1)) );
 }
Runs->Draw();
//test->Draw();
//test2->Draw();

TH1F *FileRuns = new TH1F("FileRuns","Run from Lumicalc", maxRun-minRun+2, minRun-1, maxRun+1);
TH1D *XsecDistro = new TH1D("XsecDistro","X sec distribution", 60, 0., 0.6);
//-------------
   const Int_t mpt = maxRun-minRun;
   int fileRun[mpt];
   double Lumi[mpt];

   int npt = 0;
   // read data file
   ifstream file;
   //file.open("./2011-run-lumi.txt");
   file.open("./LumiAeB-dav.txt");
   while (1) {

	   file >> fileRun[npt] >> Lumi[npt];
	   if ( ! file.good() ) break;
	   cout << "x = " << fileRun[npt] << " y = " << Lumi[npt] << endl;
	   
	   FileRuns->SetBinContent((fileRun[npt]-minRun+2),0.2);
	   npt++;
   }

   file.close();
   printf("found %d Runs in file \n", npt);

bool flaggg=1;
TH1D *LumiRuns = new TH1D("LumiRuns","Zyield vs Run", maxRun-minRun+2, minRun-1, maxRun+1);
 LumiRuns->Sumw2();
for(int i=0; i<npt;i++){
	for(int j=0;j<maxRun;j++){
		if(fileRun[i]==(minRun+j)){
		  cout << fileRun[i]-minRun+1 <<" "<< ((float)Runs->GetBinContent(j+1))/Lumi[i] <<" "<< Lumi[i] << " matched run \n";
		if(Lumi[i]>0.&&Runs->GetBinContent(j+2)>0.){
			LumiRuns->SetBinContent(fileRun[i]-minRun+2,(((double)Runs->GetBinContent(j+2))/Lumi[i])*1000);
			LumiRuns->SetBinError(fileRun[i]-minRun+2,((TMath::Sqrt((double)Runs->GetBinContent(j+2)))/Lumi[i])*1000);
			XsecDistro->Fill((((double)Runs->GetBinContent(j+2))/Lumi[i])*1000);
		flaggg=false;
		}
		}
		else if(fileRun[i]==(minRun+j) && (Runs->GetBinContent(j+2+1)>0. || Runs->GetBinContent(j+2-1)>0.)) cout << "Son cazzi " << fileRun[i]<<"\n";
	}
	if(flaggg) {
	//cout << " ---------------- \n";
	cout << fileRun[i] << " Run not matched! \n";
	//cout << Runs->GetBinContent(i) <<" " << Runs->GetBinContent(i+1) <<" " << Runs->GetBinContent(i+2) <<" "<< Lumi[i] << " probably not empty \n";
	//if(Lumi[i]>1.e+06) cout << "ALERT THIS ONE IS GOOD \n";
	}
	flaggg=true;
}

TCanvas * Canv = (TCanvas*)gDirectory->GetList()->FindObject("Canv");
if (Canv) delete Canv;
Canv = new TCanvas("Canv","Canv",0,0,800,600);
Canv->cd();
LumiRuns->SetXTitle("Run");
LumiRuns->SetYTitle("#sigma (nb)");
LumiRuns->SetLineColor(kBlack);
LumiRuns->Draw("E1");
Runs->SetLineColor(kRed);
//Runs->Draw("SAMES");
FileRuns->SetLineColor(kBlue);
//FileRuns->Draw("SAMES");
//LumiRuns->Draw("E1 SAMES");
Canv->Print("ratio_zlumi.eps");

TCanvas * Another = (TCanvas*)gDirectory->GetList()->FindObject("Another");
if (Another) delete Another;
Another = new TCanvas("Another","Another",0,0,800,600);
Another->cd();
XsecDistro->SetXTitle("#sigma (nb)");
XsecDistro->SetLineColor(kBlack);
XsecDistro->Draw();
Another->Print("distrib_zsigma.eps");

/*
  //-------------
  // per il momento tengo le due sezioni separate... solo per debuggare meglio...
  //-------------
   const Int_t rpt = 120000;
   int lsRun[rpt];
   float LuSec[rpt];

   npt = 0;
   // read data file
   ifstream in;
   in.open("./2011-LS.txt");
   while (1) {

	   in >> lsRun[npt] >> LuSec[npt];
	   if ( ! in.good() ) break;
	   //cout << "x = " << fileRun[npt] << " y = " << Lumi[npt] << endl;
	   npt++;
   }

   in.close();
   printf("found %d LS\n", npt);
*/
}