240 B2INFO(
"Starting eclNOptimalAlgorithm");
246 const int lastBin = inputParameters->GetNbinsX();
247 const double scale = inputParameters->GetBinContent(lastBin);
248 for (
int ib = 1; ib < lastBin; ib++) {
249 double param = inputParameters->GetBinContent(ib);
250 inputParameters->SetBinContent(ib, param / scale);
251 inputParameters->SetBinError(ib, 0.);
257 const double groupNum = groupNumberOfEachCellID->GetBinContent(ic);
258 groupNumberOfEachCellID->SetBinContent(ic, groupNum / scale);
259 groupNumberOfEachCellID->SetBinError(ic, 0.);
273 TFile* histFile =
new TFile(
"eclNOptimalAlgorithm.root",
"recreate");
274 inputParameters->Write();
275 groupNumberOfEachCellID->Write();
276 entriesPerThetaIdEnergy->Write();
277 mcEnergyDiff->Write();
278 eMCOverEGenerated->Write();
279 clusterTime->Write();
280 angularDiff->Write();
281 nOutOfTimeCrystals->Write();
282 timeSinceInjection->Write();
287 const int nCrystalGroups = (int)(inputParameters->GetBinContent(1) + 0.5);
288 const int nEnergies = (int)(inputParameters->GetBinContent(2) + 0.5);
289 const int nLeakReg = 3;
290 auto generatedE = create2Dvector<float>(nLeakReg, nEnergies);
292 for (
int ireg = 0; ireg < nLeakReg; ireg++) {
293 for (
int ie = 0; ie < nEnergies; ie++) {
295 generatedE[ireg][ie] = inputParameters->GetBinContent(bin);
298 B2INFO(
"nCrystalGroups = " << nCrystalGroups);
303 const int iExp = exprun[0].first;
304 const int iRun = exprun[0].second;
305 B2INFO(
"Experiment, run = " << iExp <<
", " << iRun);
323 B2INFO(
"eclNOptimalAlgorithm: reading previous payload");
325 std::vector<float> eUpperBoundariesFwdPrev = existingECLnOptimal->getUpperBoundariesFwd();
326 std::vector<float> eUpperBoundariesBrlPrev = existingECLnOptimal->getUpperBoundariesBrl();
327 std::vector<float> eUpperBoundariesBwdPrev = existingECLnOptimal->getUpperBoundariesBwd();
328 TH2F nOptimal2DPrev = existingECLnOptimal->getNOptimal();
329 nOptimal2DPrev.SetName(
"nOptimal2DPrev");
331 const int nPrevE = eUpperBoundariesFwdPrev.size();
332 B2INFO(
"Energy upper boundaries from previous payload for each region");
333 for (
int ie = 0; ie < nPrevE; ie++) {
334 B2INFO(
" " << ie <<
" " << eUpperBoundariesFwdPrev[ie] <<
" " << eUpperBoundariesBrlPrev[ie] <<
" " << eUpperBoundariesBwdPrev[ie]);
339 nOptimal2DPrev.Write();
343 std::vector< std::vector<int> > initialNOptimal;
344 initialNOptimal.resize(nCrystalGroups, std::vector<int>(nEnergies, 0));
347 TH2F* nInitialPerGroup =
new TH2F(
"nInitialPerGroup",
"initial nCrys, energy point vs group number;group;energy point",
348 nCrystalGroups, 0., nCrystalGroups, nEnergies, 0., nEnergies);
349 TH2F* generatedEPerGroup =
new TH2F(
"generatedEPerGroup",
"Generated energy, energy point vs group number;group;energy point",
350 nCrystalGroups, 0., nCrystalGroups, nEnergies, 0., nEnergies);
351 TH1F* firstCellIDPerGroup =
new TH1F(
"firstCellIDPerGroup",
"First cellID of group;group", nCrystalGroups, 0., nCrystalGroups);
352 TH1F* nCrystalsPerGroup =
new TH1F(
"nCrystalsPerGroup",
"Number of crystals per group;group", nCrystalGroups, 0., nCrystalGroups);
353 std::vector<int> crystalsPerGroup;
354 crystalsPerGroup.resize(nCrystalGroups, 0);
357 for (
int cellID = 1; cellID <= nCrystalsTotal; cellID++) {
360 int iGroup = (int)(0.5 + groupNumberOfEachCellID->GetBinContent(cellID));
363 std::vector<float> eUpperBoundariesPrev = eUpperBoundariesBrlPrev;
366 eUpperBoundariesPrev = eUpperBoundariesFwdPrev;
369 eUpperBoundariesPrev = eUpperBoundariesBwdPrev;
376 for (
int ie = 0; ie < nEnergies; ie++) {
377 float energy = generatedE[iRegion][ie];
379 while (energy > eUpperBoundariesPrev[iEnergy]) {iEnergy++;}
380 initialNOptimal[iGroup][ie] = (int)(0.5 + nOptimal2DPrev.GetBinContent(iGroup + 1, iEnergy + 1));
382 B2INFO(
"ie iEnergy mismatch: cellID " << cellID <<
" ie " << ie <<
" iEnergy " << iEnergy);
386 generatedEPerGroup->SetBinContent(iGroup + 1, ie + 1, energy);
387 nInitialPerGroup->SetBinContent(iGroup + 1, ie + 1, initialNOptimal[iGroup][ie]);
391 if (crystalsPerGroup[iGroup] == 0) {
392 firstCellIDPerGroup->SetBinContent(iGroup + 1, cellID);
393 firstCellIDPerGroup->SetBinError(iGroup + 1, 0.);
395 crystalsPerGroup[iGroup]++;
399 for (
int ig = 0; ig < nCrystalGroups; ig++) {
400 nCrystalsPerGroup->SetBinContent(ig + 1, crystalsPerGroup[ig]);
401 nCrystalsPerGroup->SetBinError(ig + 1, 0.);
404 nInitialPerGroup->Write();
405 generatedEPerGroup->Write();
406 firstCellIDPerGroup->Write();
407 nCrystalsPerGroup->Write();
408 B2INFO(
"Wrote initial diagnostic histograms");
412 for (
int ig = 0; ig < nCrystalGroups; ig++) {
413 for (
int ie = 0; ie < nEnergies; ie++) {
414 std::string name =
"eSum_" + std::to_string(ig) +
"_" + std::to_string(ie);
416 name =
"biasSum_" + std::to_string(ig) +
"_" + std::to_string(ie);
423 B2INFO(
"Wrote eSum and biasSum histograms");
430 TH2F* nOptimalPerGroup =
new TH2F(
"nOptimalPerGroup",
"nOptimal;group;energy point", nCrystalGroups, 0., nCrystalGroups, nEnergies,
432 TH2F* changeInNOptimal =
new TH2F(
"changeInNOptimal",
"nOptimal minus nInitial;group;energy point", nCrystalGroups, 0.,
433 nCrystalGroups, nEnergies, 0., nEnergies);
434 TH2F* binsInFit =
new TH2F(
"binsInFit",
"Number of bins used in Novo fit, energy point vs group number;group;energy point",
435 nCrystalGroups, 0., nCrystalGroups, nEnergies, 0., nEnergies);
436 TH2F* maxEntriesPerHist =
new TH2F(
"maxEntriesPerHist",
437 "Max entries in histogram bin, energy point vs group number;group;energy point", nCrystalGroups, 0., nCrystalGroups, nEnergies, 0.,
439 TH2F* peakPerGroup =
new TH2F(
"peakPerGroup",
"peak energy, energy point vs group number;group;energy point", nCrystalGroups, 0.,
440 nCrystalGroups, nEnergies, 0., nEnergies);
441 TH2F* effSigmaPerGroup =
new TH2F(
"effSigmaPerGroup",
"fit effective sigma, energy point vs group number;group;energy point",
442 nCrystalGroups, 0., nCrystalGroups, nEnergies, 0., nEnergies);
443 TH2F* etaPerGroup =
new TH2F(
"etaPerGroup",
"fit eta, energy point vs group number;group;energy point", nCrystalGroups, 0.,
444 nCrystalGroups, nEnergies, 0., nEnergies);
445 TH2F* fitProbPerGroup =
new TH2F(
"fitProbPerGroup",
"fit probability, energy point vs group number;group;energy point",
446 nCrystalGroups, 0., nCrystalGroups, nEnergies, 0., nEnergies);
447 TH2F* resolutionPerGroup =
new TH2F(
"resolutionPerGroup",
"resolution/(peak-bias), energy point vs group number;group;energy point",
448 nCrystalGroups, 0., nCrystalGroups, nEnergies, 0., nEnergies);
449 TH2F* fracContainedEPerGroup =
new TH2F(
"fracContainedEPerGroup",
450 "peak fraction of energy contained in nOpt crystals;group;energy point", nCrystalGroups, 0., nCrystalGroups, nEnergies, 0.,
453 TH2F* biasPerGroup =
new TH2F(
"biasPerGroup",
"bias (GeV), energy point vs group number;group;energy point", nCrystalGroups, 0.,
454 nCrystalGroups, nEnergies, 0., nEnergies);
455 TH2F* sigmaBiasPerGroup =
new TH2F(
"sigmaBiasPerGroup",
"sigma bias (GeV), energy point vs group number;group;energy point",
456 nCrystalGroups, 0., nCrystalGroups, nEnergies, 0., nEnergies);
458 TH2F* existingResolutionPerGroup =
new TH2F(
"existingResolutionPerGroup",
459 "existing resolution/peak, energy point vs group number;group;energy point", nCrystalGroups, 0., nCrystalGroups, nEnergies, 0.,
466 TF1* func =
new TF1(
"eclNOptimalNovo", eclNOptimalNovo, 0.4, 1.4, 4);
467 func->SetLineColor(kRed);
469 for (
int ig = 0; ig < nCrystalGroups; ig++) {
470 for (
int ie = 0; ie < nEnergies; ie++) {
473 std::string name =
"eSum_" + std::to_string(ig) +
"_" + std::to_string(ie);
477 std::string biasName =
"biasSum_" + std::to_string(ig) +
"_" + std::to_string(ie);
481 const double genEnergy = generatedEPerGroup->GetBinContent(ig + 1, ie + 1);
486 const int nCrysBins = eSum->GetNbinsX();
487 const int nCrysMax = nCrysBins - 1;
490 TH1D* eSumOpt{
nullptr};
492 double bestFractionalResolution = 999.;
493 double existingFractionalResolution = 999.;
494 double biasForNOpt = 0.;
495 double biasSigmaForNOpt = 0.;
501 const int initialnCrysSumToFit = initialNOptimal[ig][ie];
502 int nCrysSumToFit = initialnCrysSumToFit;
503 while (nCrysSumToFit > 0) {
505 TH1D* hEnergy = (TH1D*)eSum->ProjectionY(
"hEnergy", nCrysSumToFit, nCrysSumToFit);
506 TString newName = name +
"_" + std::to_string(nCrysSumToFit);
507 hEnergy->SetName(newName);
511 const double minESumEntries = 800.;
512 if (hEnergy->GetEntries() < minESumEntries) {
513 B2INFO(
"Insufficient entries in eSum: " << hEnergy->GetEntries() <<
" for group " << ig <<
" energy point " << ie);
515 B2INFO(
"closed histFile; quitting");
520 const double minPeakValue = 300.;
521 while (hEnergy->GetMaximum() < minPeakValue) {hEnergy->Rebin(2);}
525 double fitFraction = 0.5;
527 int iHi = hEnergy->GetNbinsX();
528 const int maxBinsToFit = 59;
529 while ((iHi - iLo) > maxBinsToFit) {
530 std::vector<int> iBins = eclNOptimalFitRange(hEnergy, fitFraction);
533 if ((iHi - iLo) > maxBinsToFit) {hEnergy->Rebin(2);}
537 const int nBinsX = hEnergy->GetNbinsX();
538 const double fitlow = hEnergy->GetBinLowEdge(iLo);
539 const double fithigh = hEnergy->GetBinLowEdge(iHi + 1);
540 double sum = hEnergy->Integral(iLo, iHi);
541 B2INFO(
"group " << ig <<
" ie " << ie <<
" name " << name <<
" newName " << newName <<
" nBinsX " << nBinsX <<
" 50% target: " <<
542 fitFraction * hEnergy->GetEntries() <<
" iLo: " << iLo <<
" iHi: " << iHi <<
" sum: " << sum);
546 double normalization = hEnergy->GetMaximum();
547 const int iMax = hEnergy->GetMaximumBin();
548 double peak = hEnergy->GetBinLowEdge(iMax);
549 double effSigma = 0.5 * (fithigh - fitlow);
552 func->SetParameters(normalization, peak, effSigma, eta);
553 func->SetParNames(
"normalization",
"peak",
"effSigma",
"eta");
556 func->SetParLimits(1, fitlow, fithigh);
557 func->SetParLimits(2, 0., 2.*effSigma);
558 func->SetParLimits(3, -1, 3);
561 if (nCrysSumToFit == 1) {
562 const double etaForOneCrystal = 0.95;
563 func->SetParameter(3, etaForOneCrystal);
564 func->SetParLimits(3, etaForOneCrystal, etaForOneCrystal);
568 hEnergy->Fit(func,
"LIEQ",
"", fitlow, fithigh);
574 double biasSigma = 0.;
575 if (nCrysSumToFit < nCrysBins) {
576 TH1D* hBias = (TH1D*)biasSum->ProjectionY(
"hBias", nCrysSumToFit, nCrysSumToFit);
578 std::vector<int> jBins = eclNOptimalFitRange(hBias, fitFraction);
579 const double lowEdge = hBias->GetBinLowEdge(jBins[0]);
580 const double highEdge = hBias->GetBinLowEdge(jBins[1] + 1);
581 bias = 0.5 * (lowEdge + highEdge);
582 biasSigma = 0.5 * (highEdge - lowEdge);
589 std::vector<int> iBins = eclNOptimalFitRange(hEnergy, fitFraction);
590 const double resolution = eclNOptimalResolution(hEnergy, iBins[0], iBins[1]);
595 peak = func->GetParameter(1);
596 const double fractionalResolution = resolution / (peak - bias / genEnergy);
600 if (fractionalResolution < bestFractionalResolution and nCrysSumToFit != nCrysBins) {
601 bestFractionalResolution = fractionalResolution;
602 nOpt = nCrysSumToFit;
604 nFitBins = 1 + iHi - iLo;
606 biasSigmaForNOpt = biasSigma;
607 }
else if (nCrysSumToFit == nCrysBins) {
608 existingFractionalResolution = fractionalResolution;
615 const double resTolerance = 1.05;
616 if (nCrysSumToFit == initialnCrysSumToFit) {
619 if (nCrysSumToFit > 1) {
624 }
else if (nCrysSumToFit < initialnCrysSumToFit) {
628 if (fractionalResolution < resTolerance* bestFractionalResolution and nCrysSumToFit > 1) {
630 }
else if (initialnCrysSumToFit != nCrysMax) {
631 nCrysSumToFit = initialnCrysSumToFit + 1;
633 nCrysSumToFit = nCrysBins;
635 }
else if (nCrysSumToFit < nCrysBins) {
639 if (fractionalResolution < resTolerance * bestFractionalResolution and nCrysSumToFit < nCrysMax) {
642 nCrysSumToFit = nCrysBins;
644 }
else if (nCrysSumToFit == nCrysBins) {
651 B2INFO(
" ig: " << ig <<
" ie: " << ie <<
" initial nOpt: " << initialnCrysSumToFit <<
" final nOpt: " << nOpt);
657 TF1* funcOpt = (TF1*)eSumOpt->GetFunction(
"eclNOptimalNovo");
659 nOptimalPerGroup->SetBinContent(ig + 1, ie + 1, nOpt);
661 changeInNOptimal->SetBinContent(ig + 1, ie + 1, nOpt - initialnCrysSumToFit);
662 changeInNOptimal->SetBinError(ig + 1, ie + 1, 0.);
664 biasPerGroup->SetBinContent(ig + 1, ie + 1, biasForNOpt);
665 biasPerGroup->SetBinError(ig + 1, ie + 1, 0.);
667 sigmaBiasPerGroup->SetBinContent(ig + 1, ie + 1, biasSigmaForNOpt);
668 sigmaBiasPerGroup->SetBinError(ig + 1, ie + 1, 0.);
670 binsInFit->SetBinContent(ig + 1, ie + 1, nFitBins);
671 binsInFit->SetBinError(ig + 1, ie + 1, 0.);
673 maxEntriesPerHist->SetBinContent(ig + 1, ie + 1, eSumOpt->GetMaximum());
674 maxEntriesPerHist->SetBinError(ig + 1, ie + 1, 0.);
676 const double peakOpt = funcOpt->GetParameter(1);
677 const double peakOptUnc = funcOpt->GetParError(1);
678 peakPerGroup->SetBinContent(ig + 1, ie + 1, peakOpt);
679 peakPerGroup->SetBinError(ig + 1, ie + 1, peakOptUnc);
681 const double genE = generatedEPerGroup->GetBinContent(ig + 1, ie + 1);
682 const double peakCor = peakOpt - biasForNOpt / genE;
683 fracContainedEPerGroup->SetBinContent(ig + 1, ie + 1, peakCor);
684 fracContainedEPerGroup->SetBinError(ig + 1, ie + 1, peakOptUnc);
686 effSigmaPerGroup->SetBinContent(ig + 1, ie + 1, funcOpt->GetParameter(2));
687 effSigmaPerGroup->SetBinError(ig + 1, ie + 1, funcOpt->GetParError(2));
689 etaPerGroup->SetBinContent(ig + 1, ie + 1, funcOpt->GetParameter(3));
690 etaPerGroup->SetBinError(ig + 1, ie + 1, funcOpt->GetParError(3));
692 fitProbPerGroup->SetBinContent(ig + 1, ie + 1, funcOpt->GetProb());
693 fitProbPerGroup->SetBinError(ig + 1, ie + 1, 0.);
695 resolutionPerGroup->SetBinContent(ig + 1, ie + 1, bestFractionalResolution);
696 resolutionPerGroup->SetBinError(ig + 1, ie + 1, 0.);
698 existingResolutionPerGroup->SetBinContent(ig + 1, ie + 1, existingFractionalResolution);
699 existingResolutionPerGroup->SetBinError(ig + 1, ie + 1, 0.);
711 changeInNOptimal->Write();
712 biasPerGroup->Write();
713 sigmaBiasPerGroup->Write();
715 maxEntriesPerHist->Write();
716 peakPerGroup->Write();
717 effSigmaPerGroup->Write();
718 etaPerGroup->Write();
719 fitProbPerGroup->Write();
720 resolutionPerGroup->Write();
721 existingResolutionPerGroup->Write();
722 fracContainedEPerGroup->Write();
724 B2INFO(
"Wrote fit summary histograms");
732 TH2F* fracContainedAdjacent[2];
733 TH2F* biasAdjacent[2];
734 const TString updown[2] = {
"lower",
"higher"};
735 for (
int ia = 0; ia < 2; ia++) {
736 TString name =
"fracContainedAdjacent_" + std::to_string(ia);
737 TString title =
"peak fraction of energy contained in nOpt crystals, " + updown[ia] +
" E;group;energy point";
738 fracContainedAdjacent[ia] =
new TH2F(name, title, nCrystalGroups, 0., nCrystalGroups, nEnergies, 0., nEnergies);
740 name =
"biasAdjacent_" + std::to_string(ia);
741 title =
"bias (GeV) in nOpt crystals, " + updown[ia] +
" E;group;energy point";
742 biasAdjacent[ia] =
new TH2F(name, title, nCrystalGroups, 0., nCrystalGroups, nEnergies, 0., nEnergies);
747 for (
int ig = 0; ig < nCrystalGroups; ig++) {
748 for (
int ie = 0; ie < nEnergies; ie++) {
751 const int nOpt = nOptimalPerGroup->GetBinContent(ig + 1, ie + 1);
755 for (
int ia = 0; ia < 2; ia++) {
756 const int ieAdj = ie + 2 * ia - 1;
757 double eFracPeakAdj = fracContainedEPerGroup->GetBinContent(ig + 1, ie + 1);
758 double biasAdj = biasPerGroup->GetBinContent(ig + 1, ie + 1);
761 if (ieAdj >= 0 and ieAdj < nEnergies) {
765 std::string biasName =
"biasSum_" + std::to_string(ig) +
"_" + std::to_string(ieAdj);
767 TH1D* hBias = (TH1D*)biasSum->ProjectionY(
"hBias", nOpt, nOpt);
770 double fitFraction = 0.683;
771 std::vector<int> jBins = eclNOptimalFitRange(hBias, fitFraction);
772 const double lowEdge = hBias->GetBinLowEdge(jBins[0]);
773 const double highEdge = hBias->GetBinLowEdge(jBins[1] + 1);
774 biasAdj = 0.5 * (lowEdge + highEdge);
778 std::string name =
"eSum_" + std::to_string(ig) +
"_" + std::to_string(ieAdj);
780 TH1D* hEnergy = (TH1D*)eSum->ProjectionY(
"hEnergy", nOpt, nOpt);
781 TString newName = name +
"_" + std::to_string(nOpt);
782 hEnergy->SetName(newName);
784 B2INFO(
"fit adj ig = " << ig <<
" ie = " << ie <<
" ia = " << ia <<
" " << newName <<
" " <<
" entries = " << hEnergy->GetEntries()
785 <<
" GetMaxiumum = " << hEnergy->GetMaximum());
788 const double minPeakValue = 300.;
789 while (hEnergy->GetMaximum() < minPeakValue) {hEnergy->Rebin(2);}
794 int iHi = hEnergy->GetNbinsX();
795 const int maxBinsToFit = 59;
796 while ((iHi - iLo) > maxBinsToFit) {
797 std::vector<int> iBins = eclNOptimalFitRange(hEnergy, fitFraction);
800 if ((iHi - iLo) > maxBinsToFit) {hEnergy->Rebin(2);}
804 const double fitlow = hEnergy->GetBinLowEdge(iLo);
805 const double fithigh = hEnergy->GetBinLowEdge(iHi + 1);
806 double normalization = hEnergy->GetMaximum();
807 const int iMax = hEnergy->GetMaximumBin();
808 double peak = hEnergy->GetBinLowEdge(iMax);
809 double effSigma = 0.5 * (fithigh - fitlow);
812 func->SetParameters(normalization, peak, effSigma, eta);
813 func->SetParNames(
"normalization",
"peak",
"effSigma",
"eta");
816 func->SetParLimits(1, fitlow, fithigh);
817 func->SetParLimits(2, 0., 2.*effSigma);
818 func->SetParLimits(3, -1, 3);
822 const double etaForOneCrystal = 0.95;
823 func->SetParameter(3, etaForOneCrystal);
824 func->SetParLimits(3, etaForOneCrystal, etaForOneCrystal);
828 hEnergy->Fit(func,
"LIEQ",
"", fitlow, fithigh);
831 const double peakAdj = func->GetParameter(1);
832 const double genE = generatedEPerGroup->GetBinContent(ig + 1, ieAdj + 1);
833 eFracPeakAdj = peakAdj - biasAdj / genE;
837 fracContainedAdjacent[ia]->SetBinContent(ig + 1, ie + 1, eFracPeakAdj);
838 biasAdjacent[ia]->SetBinContent(ig + 1, ie + 1, biasAdj);
841 B2INFO(
" ig " << ig <<
" ie " << ie <<
" eFrac (3): "
842 << fracContainedAdjacent[0]->GetBinContent(ig + 1, ie + 1) <<
" "
843 << fracContainedEPerGroup->GetBinContent(ig + 1, ie + 1) <<
" "
844 << fracContainedAdjacent[1]->GetBinContent(ig + 1, ie + 1)
846 << biasAdjacent[0]->GetBinContent(ig + 1, ie + 1) <<
" "
847 << biasPerGroup->GetBinContent(ig + 1, ie + 1) <<
" "
848 << biasAdjacent[1]->GetBinContent(ig + 1, ie + 1)
856 fracContainedAdjacent[0]->Write();
857 fracContainedAdjacent[1]->Write();
858 biasAdjacent[0]->Write();
859 biasAdjacent[1]->Write();
861 B2INFO(
"Wrote adjacent energy point summary histograms");
868 auto boundaryE = create2Dvector<float>(nLeakReg, nEnergies);
869 for (
int ireg = 0; ireg < nLeakReg; ireg++) {
870 B2INFO(
"Generated energies and boundaries for region = " << ireg);
871 for (
int ie = 0; ie < nEnergies - 1; ie++) {
872 double logE0 = log(generatedE[ireg][ie]);
873 double logE1 = log(generatedE[ireg][ie + 1]);
874 double logBoundary = 0.5 * (logE0 + logE1);
875 boundaryE[ireg][ie] = exp(logBoundary);
876 B2INFO(
" " << ie <<
" " << generatedE[ireg][ie] <<
" " << boundaryE[ireg][ie] <<
" GeV");
880 boundaryE[ireg][nEnergies - 1] = 9999.;
881 B2INFO(
" " << nEnergies - 1 <<
" " << generatedE[ireg][nEnergies - 1] <<
" " << boundaryE[ireg][nEnergies - 1] <<
" GeV");
885 std::vector<int> groupNumber;
887 const int iGroup = (int)(0.5 + groupNumberOfEachCellID->GetBinContent(cellID));
888 groupNumber.push_back(iGroup);
892 TH2F nOptimal2D(
"nOptimal2D",
"Optimal nCrys, energy bin vs group number", nCrystalGroups, 0, nCrystalGroups, nEnergies, 0.,
894 for (
int ig = 0; ig < nCrystalGroups; ig++) {
895 for (
int ie = 0; ie < nEnergies; ie++) {
896 double nOpt = nOptimalPerGroup->GetBinContent(ig + 1, ie + 1);
897 nOptimal2D.SetBinContent(ig + 1, ie + 1, nOpt);
903 TH2F peakFracEnergy(
"peakFracEnergy",
"peak contained energy over generated E, energy bin vs group number", 3 * nCrystalGroups, 0,
904 nCrystalGroups, nEnergies, 0., nEnergies);
905 TH2F bias(
"bias",
"median bias (GeV), energy bin vs group number", 3 * nCrystalGroups, 0, nCrystalGroups, nEnergies, 0., nEnergies);
906 TH2F logPeakEnergy(
"logPeakEnergy",
"log peak Energy (GeV), energy bin vs group number", 3 * nCrystalGroups, 0, nCrystalGroups,
907 nEnergies, 0., nEnergies);
908 for (
int ig = 0; ig < nCrystalGroups; ig++) {
909 for (
int ie = 0; ie < nEnergies; ie++) {
910 const int iy = ie + 1;
911 const int ix = 1 + 3 * ig;
916 double peakAdj = fracContainedEPerGroup->GetBinContent(ig + 1, ie + 1);
917 const double genE = generatedEPerGroup->GetBinContent(ig + 1, ie + 1);
918 double logE = log(genE * peakAdj);
920 peakFracEnergy.SetBinContent(ix, iy, peakAdj);
921 logPeakEnergy.SetBinContent(ix, iy, logE);
924 double peakAdj0 = peakAdj;
927 peakAdj0 = fracContainedAdjacent[0]->GetBinContent(ig + 1, ie + 1);
928 const double genE0 = generatedEPerGroup->GetBinContent(ig + 1, ie);
929 logE0 = log(genE0 * peakAdj0);
932 peakFracEnergy.SetBinContent(ix + 1, iy, peakAdj0);
933 logPeakEnergy.SetBinContent(ix + 1, iy, logE0);
936 double peakAdj1 = peakAdj;
938 if (ie < nEnergies - 1) {
939 peakAdj1 = fracContainedAdjacent[1]->GetBinContent(ig + 1, ie + 1);
940 const double genE1 = generatedEPerGroup->GetBinContent(ig + 1, ie + 2);
941 logE1 = log(genE1 * peakAdj1);
944 peakFracEnergy.SetBinContent(ix + 2, iy, peakAdj1);
945 logPeakEnergy.SetBinContent(ix + 2, iy, logE1);
948 double medianBias = biasPerGroup->GetBinContent(ig + 1, ie + 1);
949 bias.SetBinContent(ix, iy, medianBias);
950 medianBias = biasAdjacent[0]->GetBinContent(ig + 1, ie + 1);
951 bias.SetBinContent(ix + 1, iy, medianBias);
952 medianBias = biasAdjacent[1]->GetBinContent(ig + 1, ie + 1);
953 bias.SetBinContent(ix + 2, iy, medianBias);
960 peakFracEnergy.Write();
961 logPeakEnergy.Write();
970 for (
int ireg = 0; ireg < nLeakReg; ireg++) {
971 std::vector<float> eUpperBoundaries;
972 for (
int ie = 0; ie < nEnergies; ie++) {eUpperBoundaries.push_back(boundaryE[ireg][ie]);}
975 }
else if (ireg == 1) {
995 B2RESULT(
"eclNOptimalAlgorithm: successfully stored payload ECLnOptimal");