209 B2ERROR(
"TOPGainEfficiencyCalculator : fail to open input file \"" <<
m_inputFile <<
"\"");
213 for (
int iHisto = 0 ; iHisto < c_NChannelPerPMT ; iHisto++) {
215 std::ostringstream pixelstr;
216 pixelstr << histotype <<
"_"
217 <<
"s" << std::setw(2) << std::setfill(
'0') <<
m_targetSlotId <<
"_PMT"
219 <<
"_" << std::setw(2) << std::setfill(
'0') << (iHisto + 1);
220 std::ostringstream hname;
221 hname <<
"hTime" << pixelstr.str();
229 std::ostringstream hnameProj[2];
230 hnameProj[0] <<
"hTime_" << pixelstr.str();
231 hnameProj[1] <<
"hCharge_" << pixelstr.str();
232 TH1D* hTime =
static_cast<TH1D*
>(h2D->ProjectionX(hnameProj[0].str().c_str()));
238 TF1* funcLaser =
new TF1(std::string(std::string(
"func_") + hnameProj[1].str()).c_str(),
239 "gaus(0)", fitMin, fitMax);
240 funcLaser->SetParameters(hTime->GetBinContent(hTime->GetXaxis()->FindBin(peakTime)), peakTime,
m_fitHalfWidth);
241 funcLaser->SetParLimits(1, fitMin, fitMax);
242 hTime->Fit(funcLaser,
"Q",
"", fitMin, fitMax);
250 TH1D* hCharge =
static_cast<TH1D*
>(h2D->ProjectionY(hnameProj[1].str().c_str(), binNumMin, binNumMax));
256 B2WARNING(
"TOPGainEfficiencyCalculator : no histogram for the number of events with calibration pulses identified in the given input file");
264 int globalAsicId = 0;
265 if (LoadHisto == c_LoadForFitIntegral || LoadHisto == c_LoadHitRateIntegral) threshold =
m_thresholdForIntegral;
267 for (
int iHisto = 0 ; iHisto < c_NChannelPerPMT ; iHisto++) {
271 + ((
m_targetPmtId - 1) / c_NPMTPerRow) * c_NPixelPerModule / 2
272 + (iHisto / c_NChannelPerPMTRow) * c_NPixelPerRow + (iHisto % c_NChannelPerPMTRow) + 1;
275 if (LoadHisto == c_LoadForFitHeight) {
284 std::cout <<
" ***** fitting charge distribution for " << hCharge->GetName() <<
" *****" << std::endl;
285 int nBins = hCharge->GetXaxis()->GetNbins();
286 double binWidth = hCharge->GetXaxis()->GetBinUpEdge(1) - hCharge->GetXaxis()->GetBinLowEdge(1);
287 double histoMax = hCharge->GetXaxis()->GetBinUpEdge(nBins);
289 double wholeIntegral = hCharge->Integral(0, hCharge->GetXaxis()->GetNbins() + 1);
291 while (hCharge->Integral(0, hCharge->GetXaxis()->FindBin(
m_fitMax - 0.01 * binWidth)) / wholeIntegral < fitRangeFraction)
293 if (
m_fitMax < threshold +
static_cast<double>(c_NParameterGainFit) * binWidth) {
294 B2WARNING(
"TOPGainEfficiencyCalculator : no enough entries for fitting at slot"
296 << std::setw(2) << std::setfill(
'0') <<
m_targetPmtId <<
", Ch"
297 << std::setw(2) << std::setfill(
'0') <<
m_pmtChId);
301 std::ostringstream fname;
302 fname <<
"func_" << (iHisto + 1);
303 TObject*
object = gROOT->FindObject(fname.str().c_str());
304 if (
object)
delete object;
306 double initGain = TMath::Max(hCharge->GetMean(), 26.1) - 25;
307 double initP1 = TMath::Min(4.0, TMath::Max(10000.*TMath::Power(initGain - 25, -2), 0.01));
308 double initP2 = TMath::Min(0.8 + 0.005 * TMath::Power(initP1, -3), 4.);
309 double initX0 = TMath::Max(initGain * 2 - 150, 10.);
311 double initP1overP2 = initP1 / initP2;
312 double initP0 = hCharge->GetBinContent(hCharge->GetMaximumBin())
313 / (TMath::Power(initP1overP2, initP1overP2) * TMath::Exp(-initP1overP2)) / binWidth;
315 else if (LoadHisto == c_LoadForFitHeight)
316 func->SetParameter(3, 150 + 0.5 * hCharge->GetMean());
317 else if (LoadHisto == c_LoadForFitIntegral)
318 func->SetParameter(3, 1000 + 0.5 * hCharge->GetMean());
324 else func->SetParameter(0,
m_initialP0 * hCharge->GetEntries()*binWidth);
326 func->FixParameter(4, 0);
328 func->SetParName(0,
"#it{p}_{0}");
329 func->SetParName(1,
"#it{p}_{1}");
330 func->SetParName(2,
"#it{p}_{2}");
331 func->SetParName(3,
"#it{x}_{0}");
332 func->SetParName(4,
"pedestal");
333 func->SetParName(5,
"pedestal #sigma");
334 func->SetParLimits(0, 1e-8, 1e8);
335 func->SetParLimits(1, 1e-8, 10);
336 func->SetParLimits(2, 1e-8, 10);
337 func->SetParLimits(3, 1e-8, 1e8);
338 func->SetLineColor(2);
339 func->SetLineWidth(1);
340 TF1* funcFull = NULL;
341 if (LoadHisto == c_LoadForFitHeight or LoadHisto == c_LoadForFitIntegral) {
346 double funcFullMax = histoMax * 2;
347 funcFull =
new TF1((fname.str() +
"_full").c_str(),
TOPGainFunc, (-1)*
func->GetParameter(5), funcFullMax, c_NParameterGainFit);
348 for (
int iPar = 0 ; iPar < c_NParameterGainFit ; iPar++)
349 funcFull->SetParameter(iPar,
func->GetParameter(iPar));
350 funcFull->SetLineColor(3);
351 funcFull->SetLineWidth(2);
353 double totalWeight = 0;
354 double weightedIntegral = 0;
355 double x = (-1) *
func->GetParameter(5);
356 while (x < funcFullMax) {
357 double funcVal = funcFull->Eval(x);
358 totalWeight += funcVal;
359 weightedIntegral += funcVal * x;
364 m_gain = weightedIntegral / totalWeight;
365 m_efficiency = funcFull->Integral(threshold, funcFullMax) / funcFull->Integral((-1) *
func->GetParameter(5), funcFullMax);
378 }
else std::cout <<
"*****fitting is skipped***** " << std::endl;
379 int threBin = hCharge->GetXaxis()->FindBin(threshold + 0.01 * binWidth);
380 int fitMaxBin = hCharge->GetXaxis()->FindBin(
m_fitMax - 0.01 * binWidth);
384 for (
int iBin = threBin ; iBin < nBins + 1 ; iBin++) {
385 m_histoMeanAboveThre += (hCharge->GetBinContent(iBin) * hCharge->GetXaxis()->GetBinCenter(iBin));
405 for (
auto itr =
m_branch[LoadHisto].begin(); itr !=
m_branch[LoadHisto].end(); ++itr) {
409 std::cout << std::endl;
412 else m_tree->SetEntries(1);
452 std::ostringstream pdfFilename;
455 pdfFilename <<
"_" <<
"ch" << std::setw(2) << std::setfill(
'0') <<
m_targetPmtChId;
456 pdfFilename <<
".pdf";
458 gStyle->SetFrameFillStyle(0);
459 gStyle->SetFillStyle(0);
460 gStyle->SetStatStyle(0);
461 gStyle->SetOptStat(112210);
462 gStyle->SetOptFit(1110);
463 TCanvas* canvas =
new TCanvas();
464 canvas->SetFillStyle(0);
465 canvas->Print((pdfFilename.str() +
"[").c_str());
467 TLine* line =
new TLine();
468 line->SetLineWidth(1);
469 line->SetLineStyle(1);
470 line->SetLineColor(4);
471 TArrow* arrow =
new TArrow();
472 arrow->SetLineWidth(1);
473 arrow->SetLineStyle(1);
474 arrow->SetLineColor(3);
475 TLatex* latex =
new TLatex();
477 latex->SetTextFont(22);
478 latex->SetTextSize(0.05);
479 latex->SetTextAlign(32);
486 for (
int iHisto = 0 ; iHisto < c_NChannelPerPMT ; iHisto++) {
488 if ((iHisto % c_NChannelPerPage) == 0) {
490 canvas->Divide(c_NPlotsPerChannel, c_NChannelPerPage);
494 canvas->cd(3 * (iHisto % c_NChannelPerPage) + 1);
495 gPad->SetFrameFillStyle(0);
496 gPad->SetFillStyle(0);
500 h2D->GetXaxis()->SetTitle(
"hit timing [ns]");
501 h2D->GetYaxis()->SetTitle(
"pulse charge [ADC count]");
505 canvas->cd(c_NPlotsPerChannel * (iHisto % c_NChannelPerPage) + 2);
506 gPad->SetFrameFillStyle(0);
507 gPad->SetFillStyle(0);
512 hTime->SetLineColor(1);
513 hTime->GetXaxis()->SetTitle(
"hit timing [ns]");
514 float binWidth = hTime->GetXaxis()->GetBinUpEdge(1) - hTime->GetXaxis()->GetBinLowEdge(1);
515 std::ostringstream ytitle;
516 ytitle <<
"Entries [/(" << binWidth <<
" ns)]";
517 hTime->GetYaxis()->SetTitle(ytitle.str().c_str());
521 double charge = funcLaser->GetParameter(0);
522 double peakTime = funcLaser->GetParameter(1);
523 float xMin = hTime->GetXaxis()->GetBinLowEdge(hTime->GetXaxis()->FindBin(peakTime - 2 *
m_fitHalfWidth));
524 float xMax = hTime->GetXaxis()->GetBinUpEdge(hTime->GetXaxis()->FindBin(peakTime + 2 *
m_fitHalfWidth));
525 line->DrawLine(xMin, 0.5, xMin, charge * 2.);
526 line->DrawLine(xMax, 0.5, xMax, charge * 2.);
527 arrow->DrawArrow(xMin, charge * 1.5, xMax, charge * 1.5, 0.01,
"<>");
532 canvas->cd(c_NPlotsPerChannel * (iHisto % c_NChannelPerPage) + 3);
533 gPad->SetFrameFillStyle(0);
534 gPad->SetFillStyle(0);
539 hCharge->SetLineColor(1);
540 hCharge->GetXaxis()->SetTitle(
"charge [ADC counts]");
541 float binWidth = hCharge->GetXaxis()->GetBinUpEdge(1) - hCharge->GetXaxis()->GetBinLowEdge(1);
542 std::ostringstream ytitle;
543 ytitle <<
"Entries [/(" << binWidth <<
" ADC counts)]";
544 hCharge->GetYaxis()->SetTitle(ytitle.str().c_str());
549 double charge = hCharge->GetBinContent(hCharge->GetMaximumBin());
550 line->DrawLine(threshold, 0.5, threshold, charge * 2.);
552 if ((
object = gROOT->FindObject(
"dummy")))
delete object;
553 std::ostringstream cut;
554 cut <<
"pmtChId==" << (iHisto + 1);
556 std::ostringstream summarystr[2];
557 if (LoadHisto == c_LoadForFitHeight) {
558 nEntries =
m_tree->Project(
"dummy",
"gain:efficiency", cut.str().c_str());
560 summarystr[0] <<
"gain = " << std::setiosflags(std::ios::fixed) << std::setprecision(1)
562 latex->DrawLatex(0.875, 0.34, summarystr[0].str().c_str());
563 summarystr[1] <<
"efficiency = " << std::setiosflags(std::ios::fixed) << std::setprecision(1)
564 << (
m_tree->GetV2()[0] * 100) <<
" %";
565 latex->DrawLatex(0.875, 0.29, summarystr[1].str().c_str());
567 }
else if (LoadHisto == c_LoadForFitIntegral) {
568 nEntries =
m_tree->Project(
"dummy",
"gainUseIntegral:efficiencyUseIntegral", cut.str().c_str());
570 summarystr[0] <<
"gain = " << std::setiosflags(std::ios::fixed) << std::setprecision(1)
572 latex->DrawLatex(0.875, 0.34, summarystr[0].str().c_str());
573 summarystr[1] <<
"efficiency = " << std::setiosflags(std::ios::fixed) << std::setprecision(1)
574 << (
m_tree->GetV2()[0] * 100) <<
" %";
575 latex->DrawLatex(0.875, 0.29, summarystr[1].str().c_str());
580 B2WARNING(
"TOPGainEfficiencyCalculator : multiple entries with the same channel ID ("
581 <<
m_pmtChId <<
") in the output TTree");
586 if (((iHisto + 1) % c_NChannelPerPage) == 0)
587 canvas->Print(pdfFilename.str().c_str());
600 canvas->Print((pdfFilename.str() +
"]").c_str());
606 if ((
object = gROOT->FindObject(
"dummy")))
delete object;