void laserCalibration(
		char* filename = "frascatirun", //input file
		int filenum = 1081, 					//file number
		int channel = 3, 						//trace channel
		int flagChannel = 5, 					//laser flag channel
		Double_t entriesN = 10,					//number of entries for prcessing
		int sleep = 10,							//sleep time between 2 processed entries, helpful for viewing traces
		bool gui = true							//enable or disable trace visualization
		)
{
	caen_5742 caen;
	Int_t nbins = 1024;
	Double_t entries = entriesN;
	Int_t bin;

	TCanvas *c1 = new TCanvas("c1","frascatirun",900,700);
	c1->Divide(1,2);
	c1->cd(1);

	TGraph* g = new TGraph();
	TH1F* lmPeaks = new TH1F("lm","Peaks Ratio", 1000, 0, 5000);
    TH1F* d = new TH1F("d","",nbins,0,nbins);
    TH1F* back = new TH1F("Back","",nbins,0,nbins);

    // input file
    char fname[100]=0;
    sprintf(fname,"%s_0%i.root",filename,filenum);

    TFile* infile = new TFile(fname);
	TTree *t = (TTree*) infile->Get("t");
	t->SetBranchAddress("caen_5742", &caen.system_clock);
	t->Print();

	if(entriesN<=0)
		entries = t->GetEntries();

	//out file
    char foutname[100]=0;
    int lm=0;
    if (channel ==3)lm=1;
    if (channel ==4)lm=2;
    sprintf(foutname,"./calibration/LM%i_out_0%i.root",lm,filenum);
	outfile = new TFile(foutname,"RECREATE");
	outTree = new TTree("LM","frascatirun output");
	calibTree = new TTree("LM_cal","frascatirun output");
	outTree->Branch("LM_PX1",&fPositionX1,"PX1/D");
	outTree->Branch("LM_PX2",&fPositionX2,"PX2/D");
	outTree->Branch("LM_PY1",&fPositionY1,"PY1/D");
	outTree->Branch("LM_PY2",&fPositionY2,"PY2/D");
	//outTree->Branch("baseline",baseline,"baseline[1024]/F");
	outTree->Branch("time",&timeline,"time/D");
	outTree->Branch("LM_P2_Integral",&integralP2,"IP2/D");
	calibTree->Branch("LM_P2_Integral_mean",&integralP2_mean,"IP2_mean/D");
	calibTree->Branch("LM_P2_Integral_mean_error",&integralP2_mean_error,"IP2_mean_error/D");
	calibTree->Branch("LM_P2_Integral_sigma",&integralP2_sigma,"IP2_sigma/D");
	calibTree->Branch("LM_P2_Integral_sigma_error",&integralP2_sigma_error,"IP2_sigma_error/D");

    /**************************************
     * read entries
     **************************************
    */
	for (int j = 0; j < entries; ++j){
		gSystem->Sleep (sleep);

		t->GetEntry(j);

		//TRIGGER SELECTION
		if(caen.trace[flagChannel][400]>1000 && caen.trace[flagChannel][800]<3000){
			timeline = caen.system_clock;

			/**************************************
		     * Peaks estimation
		     **************************************
		    */
			for (int i = 0; i < nbins; ++i){
				g->SetPoint(i, i, caen.trace[channel][i]);
			}

			Double_t y_max = TMath::MaxElement(g->GetN(),g->GetY());
			Float_t * source = new Float_t[nbins];
			Float_t * dest = new Float_t[nbins];

			for (int i = 0; i < nbins; ++i){
				source[i]=y_max-caen.trace[channel][i];
				g->SetPoint(i, i, source[i]);
			}

			//Use TSpectrum to find the peak candidates
			TSpectrum *s = new TSpectrum();
		   	Int_t nfound = s->SearchHighRes(source, dest, nbins, 3, 2, kTRUE, 2, kFALSE, 5);

		    /**************************************
		     * Background estimation
		     **************************************
		    */
		    Int_t  	ssize = nbins;
		    Int_t  	numberIterations = 20;
		    Int_t  	direction = s->kBackIncreasingWindow;
		    Int_t  	filterOrder = s->kBackOrder2;
		    bool  	smoothing = kFALSE;
		    Int_t  	smoothWindow = s->kBackSmoothing3;
		    bool  	compton = kFALSE;
		    for (int i = 0; i < nbins; ++i) baseline[i] = source[i];
		    s->Background(baseline, ssize, numberIterations, direction, filterOrder, smoothing, smoothWindow, compton);

		    /**************************************
		     * Peaks and integral estimation
		     **************************************
		    */
		    Double_t px[2], py[2];
		    for (int i = 0; i < nbins; ++i) dest[i] = source[i]-baseline[i];
		    if(nfound==2){
			   bin = s->GetPositionX()[0];
			   fPositionX1 = bin;
			   fPositionY1 = dest[bin];
			   px[0] = bin;
			   py[0] = dest[bin];
			   bin = s->GetPositionX()[1];
			   fPositionX2 = bin;
			   fPositionY2 = dest[bin];
			   px[1] = bin;
			   py[1] = dest[bin];
		    }
			int posxa=6;
		    int posxb=9;
		    switch (filenum){
		    	case 1081:
		    		posxa=6;
		    		posxb=9;
		    		break;

		    	case 1082:
		    		posxa=5;
		    		posxb=7;
		    		break;

		    	case 1083:
		    		posxa=5;
		    		posxb=8;
		    		break;

		    	case 1084:
		    		posxa=5;
		    		posxb=7;
		    		break;

		    	case 1085:
		    		posxa=5;
		    		posxb=7;
		    		break;

		    	case 1086:
		    		posxa=5;
		    		posxb=5;
		    		break;

		    	case 1087:
		    		posxa=4;
		    		posxb=4;
		    		break;

		    	case 1088:
		    		posxa=3;
		    		posxb=4;
		    		break;

		    	case 1089:
		    		posxa=3;
		    		posxb=3;
		    		break;

		    	default:
		    		posxa=6;
		    		posxb=9;
}

		    integralP2 = g->Integral (fPositionX2-posxa,fPositionX2+posxb);

		    /**************************************
		     * print and update the canvas
		     **************************************
		    */
		    if(gui==true){
				TH1F* gh = g->GetHistogram();
				gh->FillN(nbins,g->GetX(),g->GetY());
				g->Draw();

				TPolyMarker* pm = (TPolyMarker*)gh->GetListOfFunctions()->FindObject("TPolyMarker");
				if (pm) {
				   gh->GetListOfFunctions()->Remove(pm);
				   delete pm;
				}
				pm = new TPolyMarker(nfound, px, py);

				gh->GetListOfFunctions()->Add(pm);
				pm->SetMarkerStyle(23);
				pm->SetMarkerColor(kBlue);
				pm->SetMarkerSize(1.3);
				for (i = 0; i < nbins; i++) d->SetBinContent(i,dest[i]);
				d->SetLineColor(kRed);
				d->Draw("SAME");

				for (i = 0; i < nbins; i++) back->SetBinContent(i,baseline[i]);
			    back->SetLineColor(kGreen);
			    back->Draw("SAME");
				c1->Update();
		    }

		    /**************************************
		     * Fill tree and peaks data Histogram
		     **************************************
		    */
			if(nfound==2)
			{
				lmPeaks->Fill(integralP2);
				outTree->Fill();
			}
	        //printf("time= %d, posx1= %d, posy1= %d\n",time, fPositionX1, fPositionY1);
			//printf("time= %d, posx2= %d, posy2= %d\n",time, fPositionX2, fPositionY2);
			//for (int i=0;i<nbins;i++) printf("time = %d\n",baseline[i]);
		}
	}

	/**************************************
     * switch to the bottom pan and Draw Histogram
     **************************************
    */
	c1->cd(2);
	//lmPeaks->SetAxisRange(TMath::MinElement(entries,binmin),TMath::MaxElement(entries,binmax)+100);
	//lmPeaks->SetAxisRange(0,3000);
	lmPeaks->Fit("gaus");
	integralP2_mean = lmPeaks->GetFunction("gaus")->GetParameter(1);
	integralP2_sigma = lmPeaks->GetFunction("gaus")->GetParameter(2);
	integralP2_mean_error = lmPeaks->GetFunction("gaus")->GetParError(1);
	integralP2_sigma_error = lmPeaks->GetFunction("gaus")->GetParError(2);
	//printf("mean = %f\n",integralP2_mean);
	//printf("sigma = %f\n",integralP2_sigma);
	calibTree->Fill();
	lmPeaks->Draw();
	c1->Update();

	outfile->cd();
	gROOT->GetList()->Write();
	outTree->Write();
	calibTree->Write();
	outfile->Close();
}
Example #2
0
void monplots(TString runno, TString filename, TString module, TWISMacroResult & results)
{

  Double_t maxenerms = 1.5;
  Double_t maxpedrms = 0.8;

  TString defdir = "castor/cern.ch/user/t/tilebeam/commissioning/";
  TString deffile = "tiletb_"+runno+"_MonoCis.0.root";

  if(filename == ""){
    filename = defdir+deffile;
  }


  TFile *f = TFile::Open(filename);
  TTree *t = (TTree*)f->Get("TileRec/h1000");

  Float_t efit[48], pedfit[48];
  Int_t cispar[16];

  TString vare = "Efit"+module;
  TString varp = "Pedfit"+module;
  TString varc = "Cispar";
  t->SetBranchAddress(vare, &efit);
  t->SetBranchAddress(varp, &pedfit);
  t->SetBranchAddress(varc, &cispar);

  Int_t nevt = t->GetEntries();
  Int_t nevt_for_2D = (nevt>MAXEVT_FOR_2D) ? MAXEVT_FOR_2D : nevt;
  Int_t i, j;

  /********** MonExpert **********/
  Int_t samp[48][9];
  TString var = "Sample"+module;
  t->SetBranchAddress(var, &samp);

  TH1F *h[48];
  TH2F *c[48];
  TString hname, htitle;
  TString cname, ctitle;
  /*******************************/


  t->GetEntry(100);
  Double_t charge = 2*4.096*cispar[6]*cispar[7]/1023;
  Double_t uphist = charge +20;
  Double_t minmean = charge - 10;

  TH1F *hene[48], *hped[48];
  TString nene, tene, nped, tped;

  for(j=0;j<48;j++){
    nene = "ene";
    nene += j;
    tene = "Energy ";
    tene += j;
    hene[j]=new TH1F(nene, tene, 100, 0, uphist);

    nped = "ped";
    nped += j;
    tped = "Pedestal ";
    tped += j;
    hped[j]=new TH1F(nped, tped, 100, 0, 100);

    /********** MonExpert **********/
    hname = "Amp";
    hname += j;
    htitle="Sample 3, ch";
    htitle += j;
    h[j]=new TH1F(hname, htitle, 100, 0, 200);

    cname = "amptime";
    cname += j;
    ctitle="Sample3vsTime,ch";
    ctitle += j;
    c[j]=new TH2F(cname, ctitle, nevt_for_2D/10, 0, nevt_for_2D, 100, 0, 200);
    /*******************************/
  }

  for(Int_t i=0;i<nevt;i++)
  {
    t->GetEntry(i);

    for(j=0;j<48;j++)
    {
      hene[j]->Fill(efit[j]);
      hped[j]->Fill(pedfit[j]);

      /********** MonExpert **********/
      if (i % 20 == 0 && i < MAXEVT_FOR_2D)
      {
        h[j]->Fill(samp[j][3]);
        c[j]->Fill(i, samp[j][3]);
      }
      /*******************************/
    }
  }

  Double_t chan[48], meanene[48], rmsene[48], meanped[48], rmsped[48];
  vector<Int_t> bad;

  Double_t badMeanEneX[48], badRMSEneX[48], badPedRMSX[48];
  Double_t badMeanEneY[48], badRMSEneY[48], badPedRMSY[48];
  Int_t NbadMeanEne = 0, NbadRMSEne = 0, NbadPedRMS = 0;

  for(j=0;j<48;j++){
    chan[j]=j;

    if(j != 31 && j!=32 && j!=43){
      meanene[j]=hene[j]->GetMean();
      if (meanene[j] < minmean)
      {
      	badMeanEneX[NbadMeanEne] = j;
      	badMeanEneY[NbadMeanEne] = meanene[j];
      	NbadMeanEne++;
      }
      
      rmsene[j]=hene[j]->GetRMS();
      if (rmsene[j] > maxenerms)
      {
      	badRMSEneX[NbadRMSEne] = j;
      	badRMSEneY[NbadRMSEne] = rmsene[j];
      	NbadRMSEne++;
      }
      
      meanped[j]=hped[j]->GetMean();
      
      rmsped[j]=hped[j]->GetRMS();
      if (rmsped[j] > maxpedrms)
      {
      	badPedRMSX[NbadPedRMS] = j;
      	badPedRMSY[NbadPedRMS] = rmsped[j];
      	NbadPedRMS++;
      }

      if(meanene[j] < minmean || rmsene[j] > maxenerms || rmsped[j] > maxpedrms)
        bad.push_back(j);
    }
    else {
      meanene[j]=0.0;
      rmsene[j]=0.0;
      
      meanped[j]=0.0;
      rmsped[j]=0.0;
    }
  }

  TLine *lmean = new TLine(0, minmean, 50, minmean);
  lmean->SetLineColor(2);
  TLine *lenerms = new TLine(0, maxenerms, 50, maxenerms);
  lenerms->SetLineColor(2);
  TLine *lpedrms = new TLine(0, maxpedrms, 50, maxpedrms);
  lpedrms->SetLineColor(2);


  TPolyMarker *badMeanEne = new TPolyMarker(NbadMeanEne, badMeanEneX, badMeanEneY, "p");
  badMeanEne->SetMarkerColor(2);
  badMeanEne->SetMarkerStyle(21);

  TPolyMarker *badRMSEne = new TPolyMarker(NbadRMSEne, badRMSEneX, badRMSEneY, "p");
  badRMSEne->SetMarkerColor(2);
  badRMSEne->SetMarkerStyle(21);

  TPolyMarker *badPedRMS = new TPolyMarker(NbadPedRMS, badPedRMSX, badPedRMSY, "p");
  badPedRMS->SetMarkerColor(2);
  badPedRMS->SetMarkerStyle(21);


  TGraph *genemean = new TGraph(48, chan, meanene);
  genemean->SetMarkerStyle(21);
  genemean->SetTitle("Mean Energy");
  genemean->GetXaxis()->SetTitle("Channel");
  TGraph *generms = new TGraph(48, chan, rmsene);
  generms->SetMarkerStyle(21);
  generms->SetTitle("RMS Energy");
  generms->GetXaxis()->SetTitle("Channel");
  TGraph *gpedmean = new TGraph(48, chan, meanped);
  gpedmean->SetMarkerStyle(21);
  gpedmean->SetTitle("Mean Pedestal");
  gpedmean->GetXaxis()->SetTitle("Channel");
  TGraph *gpedrms = new TGraph(48, chan, rmsped);
  gpedrms->SetMarkerStyle(21);
  gpedrms->SetTitle("RMS Pedestal");
  gpedrms->GetXaxis()->SetTitle("Channel");

  TCanvas *cmon= new TCanvas("cmon", "MonoCis", 700, 500);
  cmon->Divide(2,2);
  cmon->cd(1);
  genemean->Draw("AP");
  lmean->Draw();
  badMeanEne->Draw();
  cmon->cd(2);
  generms->Draw("AP");
  lenerms->Draw();
  badRMSEne->Draw();
  cmon->cd(3);
  gpedmean->Draw("AP");
  cmon->cd(4);
  gpedrms->Draw("AP");
  lpedrms->Draw();
  badPedRMS->Draw();

  cout.precision(3);
  //cout<<"Number of bad channels is "<<bad.size()<<"<br />"<<endl;
  results.addValue("Number of bad channels", bad.size());

  if(bad.size() > 0)
  {
    //cout<<"Channel"<<'\t'<<"Mean energy"<<'\t'<<"RMS energy"<<'\t'<<"RMS Monocis"<<"<br />"<<endl;
    TString table;
    table  = "<table class=\"main\" xmlns=\"http://www.w3.org/1999/xhtml\">\n";
    table += "<tr><th>Channel</th><th>Mean energy</th><th>RMS energy</th><th>RMS Monocis</th></tr>\n";

    for(i=0;i<bad.size();i++)
    {
      Int_t ch = bad.at(i);
      //cout<<ch<<"\t"<<meanene[i]<<"\t\t"<<rmsene[i]<<"\t\t"<<rmsped[i]<<"<br />"<<endl;
      table += "<tr><td>"; table += ch; table += "</td><td>"; table += meanene[i]; table += "</td><td>";
      table += rmsene[i]; table +="</td><td>"; table += rmsped[i]; table +="</td></tr>\n";
    }
    
    table += "</table>\n";
    results.addTable("Bad channels", table);
  }

  TString moduleDir = "LB" + module + "/";
  
  TString filenameps = outputDir + moduleDir +"r"+runno+"_"+module+"_MonoCis.ps";
  TString filenamepng = outputDir + moduleDir +"r"+runno+"_"+module+"_MonoCis.png";
  cmon->Print(filenameps);
  cmon->Print(filenamepng);

  TString plotFilename = outputWebDir + moduleDir + "r"+runno+"_"+module+"_MonoCis.png";
  TString plotPsFilename = outputWebDir + moduleDir + "r"+runno+"_"+module+"_MonoCis.ps";

  TString completeModuleName = "LB" + module;
  wis2Tilecomm(runno.Data(), completeModuleName.Data(), plotFilename.Data(), results);
  wis2Tilecomm(runno.Data(), completeModuleName.Data(), plotPsFilename.Data(), results);

  TString linkTitle = "Send results to QC Sheet";
  TString linkHref = "http://atlasmonitor.web.cern.ch/atlasmonitor/saveValuesExample.jsp?module=";
  linkHref += "LB" + module + "&run=" + runno + "&badChannels=";
  linkHref += bad.size();
  //results.addLink(linkTitle, linkHref);
  
  results.addPlot("", plotFilename);

  
  /********** MonExpert **********/
  
  TCanvas *c1 = new TCanvas("c1", "Amp,1-24", 900, 900);
  c1->Divide(4,6);
  TCanvas *c5 = new TCanvas("c5", "Amp,25-48", 900, 900);
  c5->Divide(4,6);

  TCanvas *c3 = new TCanvas("c3", "AmpTime,1-24", 900, 900);
  c3->Divide(4,6);
  TCanvas *c7 = new TCanvas("c7", "AmpTime,25-48",900,900);
  c7->Divide(4,6);

  for(j = 0; j < 24; j++)
  {
    c1->cd(j+1);
    gPad->SetLogy();
    h[j]->Draw();
    c5->cd(j+1);
    gPad->SetLogy();
    h[j+24]->Draw();

    c3->cd(j+1);
    c[j]->Draw();
    c7->cd(j+1);
    c[j+24]->Draw();

  }

  // Saving plots to disk
  filenamepng = outputDir + "expert/" + moduleDir + "r" + runno + "_" + module + "_MonoCis_Expert_Amp1-24.png";
  c1->Print(filenamepng);
  filenamepng = outputDir + "expert/" + moduleDir + "r" + runno + "_" + module + "_MonoCis_Expert_Amp25-48.png";
  c5->Print(filenamepng);
  filenamepng = outputDir + "expert/" + moduleDir + "r" + runno + "_" + module + "_MonoCis_Expert_AmpTime1-24.png";
  c3->Print(filenamepng);
  filenamepng = outputDir + "expert/" + moduleDir + "r" + runno + "_" + module + "_MonoCis_Expert_AmpTime25-48.png";
  c7->Print(filenamepng);

  completeModuleName = "LB" + module;

  // Saving plots to Results Database (TileComm Analysis)
  TString plot1 = outputWebDir + "expert/" + moduleDir + "r"+runno+"_"+module+"_MonoCis_Expert_Amp1-24.png";
  wis2Tilecomm(runno.Data(), completeModuleName.Data(), plot1.Data(), results);

  TString plot2 = outputWebDir + "expert/" + moduleDir + "r"+runno+"_"+module+"_MonoCis_Expert_Amp25-48.png";
  wis2Tilecomm(runno.Data(), completeModuleName.Data(), plot2.Data(), results);

  TString plot3 = outputWebDir + "expert/" + moduleDir + "r"+runno+"_"+module+"_MonoCis_Expert_AmpTime1-24.png";
  wis2Tilecomm(runno.Data(), completeModuleName.Data(), plot3.Data(), results);

  TString plot4 = outputWebDir + "expert/" + moduleDir + "r"+runno+"_"+module+"_MonoCis_Expert_AmpTime25-48.png";
  wis2Tilecomm(runno.Data(), completeModuleName.Data(), plot4.Data(), results);

  
  // Showing links in macro results page
  results.addValue("MonoCis Expert Plots", "");
  results.addLink("Amp Channels 1-24", plot1);
  results.addLink("Amp Channels 25-48", plot2);
  results.addLink("AmpTime Channels 1-24", plot3);
  results.addLink("AmpTime Channels 25-48", plot4);

  /*******************************/

}
//--------------------------------------
//function to calculate sampling factors
std::pair<Double_t,Double_t> g4_sample(int snum, Double_t energy, bool do_pion, bool do_show, bool do_print=false, bool set_val=true){
	Sample* sp = sample_map[snum];
	if(!sp) { std::cout << "Sample " << snum << " is not loaded." << std::endl; return std::pair<Double_t,Double_t>(0.,0.); }

	//select correct file
	std::string fpre = sp->fpre;
	if(do_pion) fpre += "_pion";
	else fpre += "_elec";

	//make filenames
	std::stringstream drawname, fname, piname;
	fname << sp->dir << "/" << fpre << "_" << energy << "gev_10k.root";
	if(do_pion) piname << "#pi^{-} " << energy << " GeV";
	else piname << "e^{-} " << energy << " GeV";

	//open file and tree
	TFile* _file;
	_file = TFile::Open((fname.str()).c_str());
	TTree* totalTree = (TTree*)_file->Get("Total");

	//get histo from tree (no display)
	//define mip as sam_ecal*ecal < 1 gev = 1000 mev (for pions in HCAL)
	if(sp->det==Hcal) drawname << "(hcal+" << sp->zeroWt << "*zero)/1000>>hsam(200)";
	else drawname << "(ecal)/1000>>hsam(200)";
	
	totalTree->Draw((drawname.str()).c_str(),"","hist goff");
	TH1F* hsam = (TH1F*)gDirectory->Get("hsam");
	
	//use parameters from histo to start fit
	TSpectrum* spec = new TSpectrum(5);
	spec->Search(hsam,5,"nodraw goff");
	Float_t* xpos = spec->GetPositionX();
	Float_t* ypos = spec->GetPositionY();

	Double_t m = xpos[0];
	Double_t me = hsam->GetMeanError();
	Double_t N = hsam->GetEntries();
	std::stringstream s_mean;
	s_mean.precision(3);
	Double_t f = energy/m;
	Double_t f_err = energy*(me/(m*m));
	s_mean << f << " #pm " << f_err;

	TPolyMarker* pm = new TPolyMarker(1, xpos, ypos);
	hsam->GetListOfFunctions()->Add(pm);
	pm->SetMarkerStyle(23);
	pm->SetMarkerColor(kRed);
	pm->SetMarkerSize(1.3);

	std::cout.precision(6);
	std::cout << "f_" << (do_pion ? "pion" : "elec") << " = " << f << " +/- " << f_err << std::endl;
	
	//plotting and printing
	if (do_show){
		TCanvas* can = new TCanvas("sample","sample",700,500);
		can->cd();
		TPad* pad = new TPad("graph","",0,0,1,1);
		pad->SetMargin(0.12,0.05,0.15,0.05);
		pad->Draw();
		pad->cd();
		
		//formatting
		hsam->SetTitle("");
		hsam->GetXaxis()->SetTitle("Energy [GeV]");
		//hsam->SetStats(kTRUE);
		//gStyle->SetOptStat("mr");
		hsam->SetLineWidth(2);
		hsam->SetLineColor(kBlack);
		hsam->GetYaxis()->SetTitleSize(32/(pad->GetWh()*pad->GetAbsHNDC()));
		hsam->GetYaxis()->SetLabelSize(28/(pad->GetWh()*pad->GetAbsHNDC()));
		hsam->GetXaxis()->SetTitleSize(32/(pad->GetWh()*pad->GetAbsHNDC()));
		hsam->GetXaxis()->SetLabelSize(28/(pad->GetWh()*pad->GetAbsHNDC()));
		hsam->GetYaxis()->SetTickLength(12/(pad->GetWh()*pad->GetAbsHNDC()));
		hsam->GetXaxis()->SetTickLength(12/(pad->GetWh()*pad->GetAbsHNDC()));
		
		hsam->Draw();
		
		std::stringstream Nname;
		Nname << "N = " << N;
		
		//determine placing of pave
		Double_t xmin;
		if (m/((hsam->GetXaxis()->GetXmax() + hsam->GetXaxis()->GetXmin())/2) < 1) xmin = 0.65;
		else xmin = 0.2;
		
		//legend
		TPaveText *pave = new TPaveText(xmin,0.65,xmin+0.2,0.85,"NDC");
		pave->AddText((piname.str()).c_str());
		pave->AddText((Nname.str()).c_str());
		pave->AddText("Peak sampling factor:");
		pave->AddText((s_mean.str()).c_str());
		pave->SetFillColor(0);
		pave->SetBorderSize(0);
		pave->SetTextFont(42);
		pave->SetTextSize(0.05);
		pave->Draw("same");

		if(do_print) {
			std::stringstream oname;
			oname << pdir << "/" << fpre << "_sample_" << energy << "gev_peak.png";
			can->Print((oname.str()).c_str(),"png");
		}
	}
	else _file->Close();

	//store value in sample
	if(set_val){
		if(do_pion) sp->sam_pion = f;
		else sp->sam_elec = f;
	}

	return std::pair<Double_t,Double_t>(f,f_err);
}