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; }
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; }