TH2D* GetJetCorrFunc2D_ZYAM(int itrg, int jass)
{
                    TH2D* hcorr = (TH2D*)GetRawCorrFunc2D_ratio(itrg,jass);
                    TH2D* hcorr_clone = (TH2D*)hcorr->Clone(Form("corr_clone_itrg%d_jass%d",itrg,jass));
                    hcorr_clone->Reset();
		    for(int ietabin=1;ietabin<=hcorr->GetNbinsX();ietabin++)
		    {
                      TH1D* hcorrphi = (TH1D*)hcorr->ProjectionY(Form("corrphi_%d",ietabin),ietabin,ietabin,"e");  
                     // hcorrphi->SetAxisRange(0.35,1.57,"X");
                      double histminX = hcorrphi->GetBinCenter(hcorrphi->GetMinimumBin());
                      double histminY = hcorrphi->GetBinContent(hcorrphi->GetMinimumBin());
	   	      fitfunc = new TF1(Form("fitfunc_%d",ietabin),"[0]+[1]*(x-[2])*(x-[2])",0.6,1.2);		    
                      fitfunc->SetParameters(histminY,1,histminX);
                      fitfunc->SetParLimits(1,0,0.10000);
                  //    fitfunc->SetParLimits(2,0.35,1.57);
		      for(int ifit=0;ifit<3;ifit++) hcorrphi->Fit(Form("fitfunc_%d",ietabin),"RNO");                     		  
		      float level = fitfunc->GetParameter(0);
		      for(int iphibin=1;iphibin<=hcorr->GetNbinsY();iphibin++) 
                        hcorr_clone->SetBinContent(ietabin,iphibin,hcorr->GetBinContent(ietabin,iphibin)-level);
		    }
                    
                    float max = hcorr_clone->GetBinContent(hcorr_clone->GetMaximumBin());
                    hcorr_clone->SetAxisRange(ymin,max*1.3,"Z");		    
                    return hcorr_clone;
}
Exemple #2
0
TF1* fit(float ptmin, float ptmax, int s, int b, int widVar)
{

    static int count=0;
    count++;

  TCanvas* c = new TCanvas(Form("c_%.0f_%.0f",ptmin,ptmax),"",400,400);
  TFile* infile = new TFile(Form("%s/%s_%.0f_%.0f.root",infname.Data(),collisionsystem.Data(),ptmin,ptmax));
  TH1D* h = (TH1D*)infile->Get("h");                    h->SetName(Form("h_%.0f_%.0f",ptmin,ptmax));
  TH1D* hMCSignal = (TH1D*)infile->Get("hMCSignal");    hMCSignal->SetName(Form("hMCSignal_%.0f_%.0f",ptmin,ptmax));
    
  TF1* f;  
  TF1* background;
  TF1* bkpi;
  TF1* mass;

  if(b==0) f = new TF1(Form("f%d",count),Form("%s+%s+%s",sig[s].Data(),sig_bkg[s].Data(),bkgerf.Data()), 5.0, 6.0);
  else f = new TF1(Form("f%d",count),Form("%s+%s+%s",sig[s].Data(),bkg[b].Data(),bkgerf.Data()), 5.0, 6.0);

    clean0(h);
    h->Draw();

    double hmin = h->GetBinContent(h->GetMinimumBin());
    double hmax = h->GetBinContent(h->GetMaximumBin());
    double havg = h->Integral();

    double mcmin = hMCSignal->GetBinContent(h->GetMinimumBin());
    double mcmax = hMCSignal->GetBinContent(h->GetMaximumBin());
    double mcavg = hMCSignal->Integral();

    f->SetParLimits(0,0,2*hmax);
    f->SetParLimits(1,5.27,5.29);
    f->SetParLimits(2,0.01,0.05);
    f->SetParLimits(8,0.01,0.05);
    f->SetParLimits(7,0,1);
    f->SetParLimits(6,0,1);
    if(s==1) f->SetParLimits(9,0,1);
    //if(s==2) f->SetParLimits(10,1,10);
    if(b==0 && sigmax[s]==8)
    {
	//f->SetParLimits(9,0.5*hmin,1.5*hmax);
	f->SetParLimits(10,-1000,0);
    }
    if(b==0 && sigmax[s]==10)
    {
	//f->SetParLimits(11,0.5*hmin,1.5*hmax);
	f->SetParLimits(12,-1000,0);
    }
    if(b==3)
    {
	//f->SetParLimits(9,0,1.5*hmax);
	f->SetParLimits(10,-100,0);
    }

    f->SetParLimits(3,0,1000);
    f->FixParameter(4,NPpar[0]);
    f->FixParameter(5,NPpar[1]);

    f->SetParameter(0,100);
    f->SetParameter(1,5.28);
    f->SetParameter(2,0.05);
    f->SetParameter(8,0.03);

    f->FixParameter(1,5.279);
    f->FixParameter(3,0);
    if(s==2) f->FixParameter(7,0);

    if(s>0 && bkgmax[b]>=11) f->FixParameter(11,0);
    if(s>0 && bkgmax[b]>=12) f->FixParameter(12,0); 
 
    h->GetEntries();
    hMCSignal->Fit(Form("f%d",count),"q","",minhisto,maxhisto);
    hMCSignal->Fit(Form("f%d",count),"q","",minhisto,maxhisto);
    f->ReleaseParameter(1);
    f->SetParLimits(1,5.27,5.29);
    hMCSignal->Fit(Form("f%d",count),"L q","",minhisto,maxhisto);
    hMCSignal->Fit(Form("f%d",count),"L q","",minhisto,maxhisto);
    hMCSignal->Fit(Form("f%d",count),"L q","",minhisto,maxhisto);
    hMCSignal->Fit(Form("f%d",count),"L m","",minhisto,maxhisto);

    f->FixParameter(1,f->GetParameter(1));
    f->FixParameter(2,f->GetParameter(2));  
    f->FixParameter(7,f->GetParameter(7)); 
    f->FixParameter(8,f->GetParameter(8));
    f->FixParameter(6,f->GetParameter(6));
    if(sigmax[s]>=9) f->FixParameter(9,f->GetParameter(9));
    if(sigmax[s]>=10) f->FixParameter(10,f->GetParameter(10));

    if(s==2) 
    {
	f->ReleaseParameter(7);
	f->SetParLimits(7,0,1);
    }
 
    if(s>0 && bkgmax[b]>=11) f->ReleaseParameter(11);
    if(s>0 && bkgmax[b]>=12) f->ReleaseParameter(12); 
    f->ReleaseParameter(3);
    f->SetParLimits(3,0,1000);
 
    h->Fit(Form("f%d",count),"q","",minhisto,maxhisto);
    h->Fit(Form("f%d",count),"q","",minhisto,maxhisto);
    f->ReleaseParameter(1);
    f->SetParLimits(1,5.27,5.29);
    h->Fit(Form("f%d",count),"L q","",minhisto,maxhisto);
    h->Fit(Form("f%d",count),"L q","",minhisto,maxhisto);
    h->Fit(Form("f%d",count),"L q","",minhisto,maxhisto);
    h->Fit(Form("f%d",count),"L m","",minhisto,maxhisto);
    
    if(b==0)
    {
	background = new TF1(Form("background%d",count),bkg_new[b].Data(),minhisto,maxhisto);
	background->SetParameter(0,f->GetParameter(sigmax[s]+1));
	background->SetParameter(1,f->GetParameter(sigmax[s]+2));
    }
    else
    {
	background = new TF1(Form("background%d",count),bkg_new[b].Data(),minhisto,maxhisto);
	background->SetParameter(0,f->GetParameter(9));
	background->SetParameter(1,f->GetParameter(10));
	if(bkgmax[b]>=11) background->SetParameter(2,f->GetParameter(11));
	if(bkgmax[b]>=12) background->SetParameter(3,f->GetParameter(12));
    }

    bkpi = new TF1(Form("bpki%d",count),bkgerf_new.Data(),minhisto,maxhisto);
    bkpi->SetParameter(0,f->GetParameter(3));
    bkpi->SetParameter(1,NPpar[0]);
    bkpi->SetParameter(2,NPpar[1]);

    mass = new TF1(Form("fmass%d",count),sig_new[s].Data(),minhisto,maxhisto);
    if(s==0 || s==3) mass->SetParameters(f->GetParameter(0),f->GetParameter(1),f->GetParameter(2),f->GetParameter(7),f->GetParameter(8),f->GetParameter(6));
    if(s==1) mass->SetParameters(f->GetParameter(0),f->GetParameter(1),f->GetParameter(2),f->GetParameter(7),f->GetParameter(8),f->GetParameter(6),f->GetParameter(9));
    if(s==2) mass->SetParameters(f->GetParameter(0),f->GetParameter(1),f->GetParameter(2),f->GetParameter(7),f->GetParameter(8),f->GetParameter(6),f->GetParameter(9),f->GetParameter(10));

    mass->SetParError(0,f->GetParError(0));
    mass->SetParError(1,f->GetParError(1));
    mass->SetParError(2,f->GetParError(2));
    mass->SetParError(3,f->GetParError(7));
    mass->SetParError(4,f->GetParError(8));
    mass->SetParError(5,f->GetParError(6));
    if(sigmax[s]>=9) mass->SetParError(6,f->GetParError(9));
    if(sigmax[s]>=10) mass->SetParError(7,f->GetParError(10));

      f->SetLineColor(kRed);
      f->SetLineWidth(2);

   background->SetLineColor(4);
   background->SetLineStyle(2);
   background->SetLineWidth(3);
   background->SetRange(minhisto,maxhisto);
   
   bkpi->SetFillColor(kGreen+4);
   bkpi->SetFillStyle(3005);
   bkpi->SetLineColor(kGreen+4);
   bkpi->SetLineWidth(3);

   mass->SetLineColor(kOrange-3);
   mass->SetLineStyle(2);
   mass->SetLineWidth(3);
   mass->SetFillColor(kOrange-3);
   mass->SetFillStyle(3002);

  h->SetXTitle("m_{#mu#muK} (GeV/c^{2})");
  h->SetYTitle("Entries / (5 MeV/c^{2})");
  h->GetXaxis()->CenterTitle();
  h->GetYaxis()->CenterTitle();
  h->SetAxisRange(0,h->GetMaximum()*1.4*1.2,"Y");
  h->GetXaxis()->SetTitleOffset(1.0);
  h->GetYaxis()->SetTitleOffset(1.5);
  h->GetXaxis()->SetLabelOffset(0.008);
  h->GetYaxis()->SetLabelOffset(0.008);
  h->GetXaxis()->SetTitleSize(0.060);
  h->GetYaxis()->SetTitleSize(0.060);
  h->GetXaxis()->SetTitleFont(42);
  h->GetYaxis()->SetTitleFont(42);
  h->GetXaxis()->SetLabelFont(42);
  h->GetYaxis()->SetLabelFont(42);
  h->GetXaxis()->SetLabelSize(0.06);
  h->GetYaxis()->SetLabelSize(0.06);
  h->Draw("e");
  
  double axisymin = -0.05;
  h->SetAxisRange(axisymin,h->GetMaximum()*1.2,"Y");
  h->GetXaxis()->SetNdivisions(-50205);
  int ci = TColor::GetColor("#000099");
  h->SetLineColor(ci);
  h->SetStats(0);
  
      h->SetMarkerStyle(20); // 24?
      h->SetMarkerSize(0.8);

   h->Draw("e");
   bkpi->Draw("same");
   background->Draw("same");   
   mass->SetRange(minhisto,maxhisto);
   mass->Draw("same");
   f->Draw("same");

   yield = mass->Integral(minhisto,maxhisto)/binwidthmass;
   yieldErr = mass->Integral(minhisto,maxhisto)/binwidthmass*mass->GetParError(0)/mass->GetParameter(0);

  TLegend* leg = new TLegend(0.55,0.45,0.875,0.76,NULL,"brNDC");
  leg->SetBorderSize(0);
  leg->SetTextSize(0.05);
  leg->SetTextFont(42);
  leg->SetFillStyle(0);
  leg->AddEntry(h,"Data","pl");
  leg->AddEntry(f,"Fit","l");
  leg->AddEntry(mass,"B^{+} Signal","f");
  leg->AddEntry(background,"Combinatorial","l");
  leg->AddEntry(bkpi,"B #rightarrow J/#psi X","f");
  leg->Draw("same");

  TLatex* texCms = new TLatex(0.225,0.87, "#scale[1.25]{CMS} Preliminary");
  texCms->SetNDC();
  texCms->SetTextAlign(12);
  texCms->SetTextSize(0.04);
  texCms->SetTextFont(42);
  texCms->Draw();

  TLatex* texCol;
  if(collisionsystem=="pp"||collisionsystem=="PP") texCol= new TLatex(0.39,0.94, Form("25.8 pb^{-1} (%s #sqrt{s_{NN}} = 5.02 TeV)","pp"));
  else texCol= new TLatex(0.35,0.94, Form("345 #mub^{-1} (%s #sqrt{s_{NN}} = 5.02 TeV)","PbPb"));
  texCol->SetNDC();
  texCol->SetTextSize(0.05);
  texCol->SetLineWidth(2);
  texCol->SetTextFont(42);
  texCol->Draw();

  TLatex* tex;
  
  tex = new TLatex(0.53,0.85,Form("%.1f < p_{T} < %.1f GeV/c",ptmin,ptmax));
  tex->SetNDC();
  tex->SetTextFont(42);
  tex->SetTextSize(0.05);
  tex->SetLineWidth(2);
  tex->Draw();
  
  if(centmax>0){
  TString texper="%";
  tex = new TLatex(0.225,0.78,Form("Centrality %.0f-%.0f%s",centmin,centmax,texper.Data()));//0.2612903,0.8425793
  tex->SetNDC();
  tex->SetTextColor(1);
  tex->SetTextFont(42);
  tex->SetTextSize(0.05);
  tex->SetLineWidth(2);
  tex->Draw();
  }

  tex = new TLatex(0.77,0.78,"|y_{lab}| < 2.4");
  tex->SetNDC();
  tex->SetTextFont(42);
  tex->SetTextSize(0.05);
  tex->SetLineWidth(2);
  tex->Draw();

  tex = new TLatex(0.30,0.54,"B^{+}");
  tex->SetNDC();
  tex->SetTextFont(42);
  tex->SetTextSize(0.06);
  tex->SetLineWidth(2);
  tex->Draw();

    if(widVar==0) 
      c->SaveAs(Form("SystPDF/%s_%s_%s_%.0f_%.0f.pdf",collisionsystem.Data(),signame[s].Data(),bkgname[b].Data(),ptmin,ptmax));
    else
      c->SaveAs(Form("SystPDF/%s_%s_%.0f_%.0f.pdf",collisionsystem.Data(),"widvar",ptmin,ptmax));

    return mass;
}
// Called once for each event in the main event loop
// Return non-zero to indicate a problem and terminate the event loop
int TemplateCreator::ProcessEntry(TGlobalData* gData, const TSetupData* setup){

  // Prepare a few variables
  std::string bankname, detname;
  PulseIslandList thePulseIslands;
  StringPulseIslandMap::const_iterator it;

  // Loop over each detector
  for(it = gData->fPulseIslandToChannelMap.begin(); it != gData->fPulseIslandToChannelMap.end(); ++it){

    // Get the bank and detector names for this detector
    bankname = it->first;
    detname = setup->GetDetectorName(bankname);

    // See if we already have a converged template for this detector
    if (fConvergedStatuses[detname] == true) {
      continue;
    }

    // Create the pulse candidate finder for this detector
    PulseCandidateFinder* pulse_candidate_finder = new PulseCandidateFinder(detname, fOpts);

    // Create the TemplateFitter that we will use for this channel
    fTemplateFitter = new TemplateFitter(detname, fRefineFactor);

    // Get the TPIs
    thePulseIslands = it->second;
    if (thePulseIslands.size() == 0) continue; // no pulses here..

    // Try and get the template (it may have been created in a previous event)
    std::string template_name = "hTemplate_" + detname;
    TH1D* hTemplate = NULL;
    if (fTemplates.find(detname) != fTemplates.end()) {
      hTemplate = fTemplates[detname];
    }

    // Store a couple of numbers to get an idea of how many successful fits there are
    int& n_fit_attempts = fNFitAttempts[detname]; // number of pulses we try to fit to
    int& n_successful_fits = fNSuccessfulFits[detname];
    int& n_pulses_in_template = fNPulsesInTemplate[detname];

    // Loop through all the pulses
    for (PulseIslandList::iterator pulseIter = thePulseIslands.begin(); pulseIter != thePulseIslands.end(); ++pulseIter) {

      // First we will see how many candidate pulses there are on the TPI
      pulse_candidate_finder->FindPulseCandidates(*pulseIter);
      int n_pulse_candidates = pulse_candidate_finder->GetNPulseCandidates();

      // only continue if there is one pulse candidate on the TPI
      if (n_pulse_candidates == 1) {

	TPulseIsland* pulse = *pulseIter;

        // Add the first pulse directly to the template (although we may try and choose a random pulse to start with)
	if (hTemplate == NULL) {
	  std::string histname = "hTemplate_" + detname;
	  std::string histtitle = "Template Histogram for the " + detname + " channel";

	  int pulse_length = pulse->GetSamples().size();
	  if (pulse->GetPeakSample() >= pulse_length - pulse_length/5.0) {
	    if (Debug()) {
	      std::cout << "TemplateCreator: Pulse #" << pulseIter - thePulseIslands.begin() << " is too close to one end of the island and so won't be used as the first pulse in the template." << std::endl;
	    }
	    continue;
	  }
	  hTemplate = CreateRefinedPulseHistogram(pulse, histname.c_str(), histtitle.c_str(), true);
	  ++n_pulses_in_template;

	  if (Debug()) {
	    std::cout << "TemplateCreator: Adding " << detname << " Pulse #" << pulseIter - thePulseIslands.begin() << " directly to the template" << std::endl;
	  }
	  fTemplates[detname] = hTemplate;
	  continue;
	}

	// Get the samples so we can check for digitiser overflow
	const std::vector<int>& theSamples = (pulse)->GetSamples();
	int n_samples = theSamples.size();

	// Calculate the maximum ADC value for this digitiser
	int n_bits = TSetupData::Instance()->GetNBits(bankname);
	double max_adc_value = std::pow(2, n_bits);

	// Loop through the samples and check for digitizer overflow
	bool overflowed = false;
	for (int i = 0; i < n_samples; ++i) {
	  int sample_value = theSamples.at(i);
	  if (sample_value >= max_adc_value-1 && sample_value <= max_adc_value+1) {
	    if (Debug()) {
	      std::cout << "TemplateCreator: Pulse #" << pulseIter - thePulseIslands.begin() << " has overflowed the digitizer and won't be added to the template" << std::endl;
	    }
	    overflowed = true;
	    break;
	  }
	  else if (sample_value == 0) {
	    if (Debug()) {
	      std::cout << "TemplateCreator: Pulse #" << pulseIter - thePulseIslands.begin() << " has underflowed the digitizer and won't be added to the template" << std::endl;
	    }
	    overflowed = true;
	    break;
	  }
	}
	if (overflowed) {
	  continue; // skip this pulse
	}

	// Create the refined pulse waveform
	TH1D* hPulseToFit = CreateRefinedPulseHistogram(pulse, "hPulseToFit", "hPulseToFit", false);

	// Create some histograms that monitor the progression of the template
	if (fErrorVsPulseAddedHistograms.find(detname) == fErrorVsPulseAddedHistograms.end()) {
	  std::string error_histname = "hErrorVsPulseAdded_" + detname;
	  std::string error_histtitle = "Plot of the Error as each new Pulse is added to the template for the " + detname + " channel";
	  int n_bins = 10000;
	  TH1D* error_hist = new TH1D(error_histname.c_str(), error_histtitle.c_str(), n_bins,0,n_bins);
	  fErrorVsPulseAddedHistograms[detname] = error_hist;
	}

	// all the other pulses will be fitted to the template and then added to it
	// Get some initial estimates for the fitter
	double template_pedestal = hTemplate->GetBinContent(1);
	double template_amplitude;
	double template_time;

	double pulse_pedestal = hPulseToFit->GetBinContent(1);
	double pulse_amplitude;
	double pulse_time;

	double pedestal_offset_estimate = pulse_pedestal; // now we're dealing with actual pulses since we subtract the template_pedestal in the transformation
	double amplitude_scale_factor_estimate;
	double time_offset_estimate;
	if (TSetupData::Instance()->GetTriggerPolarity(bankname) == 1) { 
	  template_amplitude = (hTemplate->GetMaximum() - template_pedestal);
	  template_time = hTemplate->GetMaximumBin() - 1; // go from bin numbering (1, n_samples) to clock ticks (0, n_samples-1)

	  pulse_amplitude = (hPulseToFit->GetMaximum() - pulse_pedestal);
	  pulse_time = hPulseToFit->GetMaximumBin() - 1;

	  amplitude_scale_factor_estimate = pulse_amplitude / template_amplitude;  // estimated scale factor
	  time_offset_estimate = pulse_time - template_time;
	}
	else if (TSetupData::Instance()->GetTriggerPolarity(bankname) == -1) {
	  template_amplitude = (template_pedestal - hTemplate->GetMinimum());
	  template_time = hTemplate->GetMinimumBin() - 1; // go from bin numbering (1, n_samples) to clock ticks (0, n_samples-1)

	  pulse_amplitude = (pulse_pedestal - hPulseToFit->GetMinimum());
	  pulse_time = hPulseToFit->GetMinimumBin() - 1; // go from bin numbering (1, n_samples) to clock ticks (0, n_samples-1)

	  amplitude_scale_factor_estimate = pulse_amplitude / template_amplitude;  // estimated scale factor
	  time_offset_estimate = pulse_time - template_time;
	}

	fTemplateFitter->SetInitialParameterEstimates(pedestal_offset_estimate, amplitude_scale_factor_estimate, time_offset_estimate);
	
	if (Debug()) {
	  std::cout << "TemplateCreator: " << detname << "(" << bankname << "): Pulse #" << pulseIter - thePulseIslands.begin() << ": " << std::endl
		    << "TemplateCreator: Template: pedestal = " << template_pedestal << ", amplitude = " << template_amplitude << ", time = " << template_time << std::endl
		    << "TemplateCreator: Pulse: pedestal = " << pulse_pedestal << ", amplitude = " << pulse_amplitude << ", time = " << pulse_time << std::endl
		    << "TemplateCreator: Initial Estimates: pedestal = " << pedestal_offset_estimate << ", amplitude = " << amplitude_scale_factor_estimate 
		    << ", time = " << time_offset_estimate << std::endl;
	}

	int fit_status = fTemplateFitter->FitPulseToTemplate(hTemplate, hPulseToFit, bankname);
	++n_fit_attempts;
	if (fit_status != 0) {
	  if (Debug()) {
	    std::cout << "TemplateCreator: Problem with fit (status = " << fit_status << ")" << std::endl;
	  }
	  delete hPulseToFit; // delete this here since it is no longer needed
	  continue;
	}
	++n_successful_fits;

	if (Debug()) {
	  std::cout << "Template Creator: Fitted Parameters: PedOffset = " << fTemplateFitter->GetPedestalOffset() << ", AmpScaleFactor = " << fTemplateFitter->GetAmplitudeScaleFactor()
	            << ", TimeOffset = " << fTemplateFitter->GetTimeOffset() << ", Chi2 = " << fTemplateFitter->GetChi2() << ", NDoF = " << fTemplateFitter->GetNDoF() 
		    << ", Prob = " << TMath::Prob(fTemplateFitter->GetChi2(), fTemplateFitter->GetNDoF()) << std::endl << std::endl;
	}

	if (fPulseDebug) {
	  // Print out some templates as we go along
	  if (n_pulses_in_template <= 10 || 
	      (n_pulses_in_template <= 100 && n_pulses_in_template%10 == 0) ||
	      (n_pulses_in_template%100 == 0) ) {
	    std::stringstream newhistname;
	    newhistname << "hTemplate_" << n_pulses_in_template << "Pulses_" << detname;
	    TH1D* new_template = (TH1D*) hTemplate->Clone(newhistname.str().c_str());
	  }
	}

	// Add the pulse to the template (we'll do correct the sample values there)
	AddPulseToTemplate(hTemplate, hPulseToFit, bankname);
	++n_pulses_in_template;
	

	if (fPulseDebug) {
	  // Print out the uncorrected and corrected pulse that has been added to the template

	  // Create the histograms that we will use to plot the corrected and uncorrected pulses
	  std::stringstream histname;
	  histname << template_name << "_Event" << EventNavigator::Instance().EntryNo() << "_Pulse" << pulseIter - thePulseIslands.begin() << "_" << n_pulses_in_template << "Added";
	  TH1D* hUncorrectedPulse = (TH1D*) hPulseToFit->Clone(histname.str().c_str());
	  histname << "_Corrected";
	  TH1D* hCorrectedPulse = (TH1D*) hPulseToFit->Clone(histname.str().c_str());
	  hCorrectedPulse->SetEntries(0); // set entries back to 0
	  
	  double pedestal_error = SetupNavigator::Instance()->GetNoise(bankname);

	  // Loop through the bins of the uncorrected pulse and set the values in the corrected pulse histogram
	  for (int iPulseBin = 1; iPulseBin <= hPulseToFit->GetNbinsX(); ++iPulseBin) {
	    
	    double uncorrected_value = hPulseToFit->GetBinContent(iPulseBin);
	    double corrected_value = CorrectSampleValue(uncorrected_value, template_pedestal);
	    
	    hCorrectedPulse->SetBinContent(iPulseBin +0.5 - fTemplateFitter->GetTimeOffset(), corrected_value); 
	    hCorrectedPulse->SetBinError(iPulseBin +0.5 - fTemplateFitter->GetTimeOffset(), pedestal_error);
	  }
	}

	delete hPulseToFit;

	// we keep on adding pulses until adding pulses has no effect on the template
	bool converged = CheckConvergence(hTemplate, bankname);
	if (converged) {
	  fConvergedStatuses[detname] = true;
	  std::cout << "TemplateCreator: " << detname << " template terminated at iteration " << n_pulses_in_template << std::endl;
	  break; // break from the for loop
	}
      } // end if only one pulse candidate
    } //end for loop through channels
  }

  return 0;
}