329 TFile* baselineFile(
nullptr);
330 TTree* baselineTreeX(
nullptr);
331 TTree* baselineTreeY(
nullptr);
332 TTree* sectorNameBaselineTree(
nullptr);
334 std::ifstream baselineFileStream;
336 baselineFileStream.open(baselineFileName.c_str());
337 if (baselineFileStream.is_open()) {
338 baselineFileStream.close();
339 baselineFile =
new TFile(baselineFileName.c_str(),
"READ");
342 edm::LogInfo(
"CalculateAPE") <<
"Baseline file for APE values sucessfully opened";
343 baselineFile->GetObject(
"iterTreeX;1", baselineTreeX);
344 baselineFile->GetObject(
"iterTreeY;1", baselineTreeY);
345 baselineFile->GetObject(
"nameTree;1", sectorNameBaselineTree);
347 edm::LogWarning(
"CalculateAPE") <<
"There is NO baseline file for APE values, so normalized residual width =1 "
348 "for ideal conditions is assumed";
353 const std::string iterationFileName(setBaseline ? baselineFileName
356 TFile*
iterationFile =
new TFile(iterationFileName.c_str(), setBaseline ?
"RECREATE" :
"UPDATE");
359 TTree* iterationTreeX(
nullptr);
360 TTree* iterationTreeY(
nullptr);
364 TTree* sectorNameTree(
nullptr);
367 bool firstIter(
false);
368 if (!iterationTreeX) {
371 iterationTreeX =
new TTree(
"iterTreeX",
"Tree for APE x values of all iterations");
372 iterationTreeY =
new TTree(
"iterTreeY",
"Tree for APE y values of all iterations");
373 edm::LogInfo(
"CalculateAPE") <<
"First APE iteration (number 0.), create iteration file with TTree";
374 sectorNameTree =
new TTree(
"nameTree",
"Tree with names of sectors");
376 iterationTreeX =
new TTree(
"iterTreeX",
"Tree for baseline x values of normalized residual width");
377 iterationTreeY =
new TTree(
"iterTreeY",
"Tree for baseline y values of normalized residual width");
378 edm::LogInfo(
"CalculateAPE") <<
"Set baseline, create baseline file with TTree";
379 sectorNameTree =
new TTree(
"nameTree",
"Tree with names of sectors");
382 const unsigned int iteration(iterationTreeX->GetEntries());
384 <<
". one, is this wanted or forgot to delete old iteration file with TTree?";
396 const unsigned int iSector(i_sector.first);
397 const bool pixelSector(i_sector.second.isPixel);
398 a_apeSectorX[iSector] = 99.;
399 a_apeSectorY[iSector] = 99.;
400 a_baselineSectorX[iSector] = -99.;
401 a_baselineSectorY[iSector] = -99.;
403 a_sectorName[iSector] =
nullptr;
404 a_sectorBaselineName[iSector] =
nullptr;
405 std::stringstream ss_sector, ss_sectorSuffixed;
406 ss_sector <<
"Ape_Sector_" << iSector;
407 if (!setBaseline && baselineTreeX) {
408 baselineTreeX->SetBranchAddress(ss_sector.str().c_str(), &a_baselineSectorX[iSector]);
409 baselineTreeX->GetEntry(0);
411 baselineTreeY->SetBranchAddress(ss_sector.str().c_str(), &a_baselineSectorY[iSector]);
412 baselineTreeY->GetEntry(0);
414 sectorNameBaselineTree->SetBranchAddress(ss_sector.str().c_str(), &a_sectorBaselineName[iSector]);
415 sectorNameBaselineTree->GetEntry(0);
418 a_baselineSectorX[iSector] = 1.;
419 a_baselineSectorY[iSector] = 1.;
422 ss_sectorSuffixed << ss_sector.str() <<
"/D";
423 iterationTreeX->Branch(ss_sector.str().c_str(), &a_apeSectorX[iSector], ss_sectorSuffixed.str().c_str());
425 iterationTreeY->Branch(ss_sector.str().c_str(), &a_apeSectorY[iSector], ss_sectorSuffixed.str().c_str());
427 sectorNameTree->Branch(ss_sector.str().c_str(), &a_sectorName[iSector], 32000, 00);
429 iterationTreeX->SetBranchAddress(ss_sector.str().c_str(), &a_apeSectorX[iSector]);
430 iterationTreeX->GetEntry(iterationTreeX->GetEntries() - 1);
432 iterationTreeY->SetBranchAddress(ss_sector.str().c_str(), &a_apeSectorY[iSector]);
433 iterationTreeY->GetEntry(iterationTreeY->GetEntries() - 1);
435 sectorNameTree->SetBranchAddress(ss_sector.str().c_str(), &a_sectorName[iSector]);
436 sectorNameTree->GetEntry(0);
444 const std::string& nameLastIter(*a_sectorName[i_sector.first]);
445 if (
name != nameLastIter) {
446 edm::LogError(
"CalculateAPE") <<
"Inconsistent sector definition in iterationFile for sector " << i_sector.first
448 <<
"Recent iteration has name \"" <<
name <<
"\", while previous had \""
449 << nameLastIter <<
"\"\n"
450 <<
"...APE calculation stopped. Please check sector definitions in config!\n";
456 if (!setBaseline && baselineFile) {
457 const std::string& nameBaseline(*a_sectorBaselineName[i_sector.first]);
458 if (
name != nameBaseline) {
459 edm::LogError(
"CalculateAPE") <<
"Inconsistent sector definition in baselineFile for sector " << i_sector.first
461 <<
"Recent iteration has name \"" <<
name <<
"\", while baseline had \""
462 << nameBaseline <<
"\"\n"
463 <<
"...APE calculation stopped. Please check sector definitions in config!\n";
470 std::ofstream apeOutputFile;
473 apeOutputFile.open(apeOutputFileName.c_str());
474 if (apeOutputFile.is_open()) {
475 edm::LogInfo(
"CalculateAPE") <<
"Text file for writing APE values successfully opened";
477 edm::LogError(
"CalculateAPE") <<
"Text file for writing APE values NOT opened,\n"
478 <<
"...APE calculation stopped. Please check path of text file name in config:\n"
479 <<
"\t" << apeOutputFileName;
487 if (apeWeightName ==
"unity")
489 else if (apeWeightName ==
"entries")
491 else if (apeWeightName ==
"entriesOverSigmaX2")
494 edm::LogError(
"CalculateAPE") <<
"Invalid parameter 'apeWeight' in cfg file: \"" << apeWeightName
495 <<
"\"\nimplemented apeWeights are \"unity\", \"entries\", \"entriesOverSigmaX2\""
496 <<
"\n...APE calculation stopped.";
504 if (smoothFraction <= 0. || smoothFraction > 1.) {
505 edm::LogError(
"CalculateAPE") <<
"Incorrect parameter in cfg file,"
506 <<
"\nsmoothFraction has to be in [0,1], but is " << smoothFraction
507 <<
"\n...APE calculation stopped.";
511 typedef std::pair<double, double> Error2AndResidualWidth2PerBin;
512 typedef std::pair<double, Error2AndResidualWidth2PerBin> WeightAndResultsPerBin;
513 std::vector<WeightAndResultsPerBin> v_weightAndResultsPerBinX;
514 std::vector<WeightAndResultsPerBin> v_weightAndResultsPerBinY;
516 double baselineWidthX2(a_baselineSectorX[i_sector.first]);
517 double baselineWidthY2(a_baselineSectorY[i_sector.first]);
520 for (
auto const& i_errBins : i_sector.second.m_binnedHists) {
521 std::map<std::string, TH1*> mHists = i_errBins.second;
523 double entriesX = mHists[
"sigmaX"]->GetEntries();
524 double meanSigmaX = mHists[
"sigmaX"]->GetMean();
527 double xMin = mHists[
"norResX"]->GetXaxis()->GetXmin();
528 double xMax = mHists[
"norResX"]->GetXaxis()->GetXmax();
529 double integralX = mHists[
"norResX"]->Integral();
530 double meanX = mHists[
"norResX"]->GetMean();
531 double rmsX = mHists[
"norResX"]->GetRMS();
532 double maximumX = mHists[
"norResX"]->GetBinContent(mHists[
"norResX"]->GetMaximumBin());
536 funcX_1.SetParameters(maximumX, meanX, rmsX);
537 TString fitOpt(
"ILERQ");
538 if (integralX > minHitsPerInterval) {
539 if (mHists[
"norResX"]->
Fit(&funcX_1, fitOpt)) {
540 edm::LogWarning(
"CalculateAPE") <<
"Fit1 did not work: " << mHists[
"norResX"]->Fit(&funcX_1, fitOpt);
543 LogDebug(
"CalculateAPE") <<
"FitResultX1\t" << mHists[
"norResX"]->Fit(&funcX_1, fitOpt) <<
"\n";
545 double meanX_1 = funcX_1.GetParameter(1);
546 double sigmaX_1 = funcX_1.GetParameter(2);
549 TF1 funcX_2(
"mygausX2",
551 meanX_1 - sigmaFactorFit *
TMath::Abs(sigmaX_1),
552 meanX_1 + sigmaFactorFit *
TMath::Abs(sigmaX_1));
553 funcX_2.SetParameters(funcX_1.GetParameter(0), meanX_1, sigmaX_1);
554 if (integralX > minHitsPerInterval) {
555 if (mHists[
"norResX"]->
Fit(&funcX_2, fitOpt)) {
556 edm::LogWarning(
"CalculateAPE") <<
"Fit2 did not work for x : " << mHists[
"norResX"]->Fit(&funcX_2, fitOpt);
559 LogDebug(
"CalculateAPE") <<
"FitResultX2\t" << mHists[
"norResX"]->Fit(&funcX_2, fitOpt) <<
"\n";
561 double meanX_2 = funcX_2.GetParameter(1);
562 double sigmaX_2 = funcX_2.GetParameter(2);
566 double meanSigmaY(0.);
567 if (i_sector.second.isPixel) {
568 entriesY = mHists[
"sigmaY"]->GetEntries();
569 meanSigmaY = mHists[
"sigmaY"]->GetMean();
578 if (i_sector.second.isPixel) {
580 double yMin = mHists[
"norResY"]->GetXaxis()->GetXmin();
581 double yMax = mHists[
"norResY"]->GetXaxis()->GetXmax();
582 double integralY = mHists[
"norResY"]->Integral();
583 meanY = mHists[
"norResY"]->GetMean();
584 rmsY = mHists[
"norResY"]->GetRMS();
585 double maximumY = mHists[
"norResY"]->GetBinContent(mHists[
"norResY"]->GetMaximumBin());
589 funcY_1.SetParameters(maximumY, meanY, rmsY);
590 if (integralY > minHitsPerInterval) {
591 if (mHists[
"norResY"]->
Fit(&funcY_1, fitOpt)) {
592 edm::LogWarning(
"CalculateAPE") <<
"Fit1 did not work: " << mHists[
"norResY"]->Fit(&funcY_1, fitOpt);
595 LogDebug(
"CalculateAPE") <<
"FitResultY1\t" << mHists[
"norResY"]->Fit(&funcY_1, fitOpt) <<
"\n";
597 meanY_1 = funcY_1.GetParameter(1);
598 sigmaY_1 = funcY_1.GetParameter(2);
601 TF1 funcY_2(
"mygausY2",
603 meanY_1 - sigmaFactorFit *
TMath::Abs(sigmaY_1),
604 meanY_1 + sigmaFactorFit *
TMath::Abs(sigmaY_1));
605 funcY_2.SetParameters(funcY_1.GetParameter(0), meanY_1, sigmaY_1);
606 if (integralY > minHitsPerInterval) {
607 if (mHists[
"norResY"]->
Fit(&funcY_2, fitOpt)) {
608 edm::LogWarning(
"CalculateAPE") <<
"Fit2 did not work for y : " << mHists[
"norResY"]->Fit(&funcY_2, fitOpt);
611 LogDebug(
"CalculateAPE") <<
"FitResultY2\t" << mHists[
"norResY"]->Fit(&funcY_2, fitOpt) <<
"\n";
613 meanY_2 = funcY_2.GetParameter(1);
614 sigmaY_2 = funcY_2.GetParameter(2);
618 double fitMeanX_1(meanX_1), fitMeanX_2(meanX_2);
619 double residualWidthX_1(sigmaX_1), residualWidthX_2(sigmaX_2);
620 double fitMeanY_1(meanY_1), fitMeanY_2(meanY_2);
621 double residualWidthY_1(sigmaY_1), residualWidthY_2(sigmaY_2);
623 double correctionX2_1(-0.0010), correctionX2_2(-0.0010);
624 double correctionY2_1(-0.0010), correctionY2_2(-0.0010);
625 correctionX2_1 = meanSigmaX * meanSigmaX * (residualWidthX_1 * residualWidthX_1 - baselineWidthX2);
626 correctionX2_2 = meanSigmaX * meanSigmaX * (residualWidthX_2 * residualWidthX_2 - baselineWidthX2);
627 if (i_sector.second.isPixel) {
628 correctionY2_1 = meanSigmaY * meanSigmaY * (residualWidthY_1 * residualWidthY_1 - baselineWidthY2);
629 correctionY2_2 = meanSigmaY * meanSigmaY * (residualWidthY_2 * residualWidthY_2 - baselineWidthY2);
632 double correctionX_1 = correctionX2_1 >= 0. ?
std::sqrt(correctionX2_1) : -
std::
sqrt(-correctionX2_1);
633 double correctionX_2 = correctionX2_2 >= 0. ?
std::sqrt(correctionX2_2) : -
std::
sqrt(-correctionX2_2);
634 double correctionY_1 = correctionY2_1 >= 0. ?
std::sqrt(correctionY2_1) : -
std::
sqrt(-correctionY2_1);
635 double correctionY_2 = correctionY2_2 >= 0. ?
std::sqrt(correctionY2_2) : -
std::
sqrt(-correctionY2_2);
637 if (
isnan(correctionX_1))
638 correctionX_1 = -0.0010;
639 if (
isnan(correctionX_2))
640 correctionX_2 = -0.0010;
641 if (
isnan(correctionY_1))
642 correctionY_1 = -0.0010;
643 if (
isnan(correctionY_2))
644 correctionY_2 = -0.0010;
646 if (entriesX < minHitsPerInterval) {
650 correctionX_1 = residualWidthX_1 = -0.0010;
652 correctionX_2 = residualWidthX_2 = -0.0010;
655 if (entriesY < minHitsPerInterval) {
659 correctionY_1 = residualWidthY_1 = -0.0010;
661 correctionY_2 = residualWidthY_2 = -0.0010;
664 i_sector.second.MeanX->SetBinContent(i_errBins.first, meanX);
665 i_sector.second.RmsX->SetBinContent(i_errBins.first, rmsX);
667 i_sector.second.FitMeanX1->SetBinContent(i_errBins.first, fitMeanX_1);
668 i_sector.second.ResidualWidthX1->SetBinContent(i_errBins.first, residualWidthX_1);
669 i_sector.second.CorrectionX1->SetBinContent(i_errBins.first, correctionX_1 * 10000.);
671 i_sector.second.FitMeanX2->SetBinContent(i_errBins.first, fitMeanX_2);
672 i_sector.second.ResidualWidthX2->SetBinContent(i_errBins.first, residualWidthX_2);
673 i_sector.second.CorrectionX2->SetBinContent(i_errBins.first, correctionX_2 * 10000.);
675 if (i_sector.second.isPixel) {
676 i_sector.second.MeanY->SetBinContent(i_errBins.first, meanY);
677 i_sector.second.RmsY->SetBinContent(i_errBins.first, rmsY);
679 i_sector.second.FitMeanY1->SetBinContent(i_errBins.first, fitMeanY_1);
680 i_sector.second.ResidualWidthY1->SetBinContent(i_errBins.first, residualWidthY_1);
681 i_sector.second.CorrectionY1->SetBinContent(i_errBins.first, correctionY_1 * 10000.);
683 i_sector.second.FitMeanY2->SetBinContent(i_errBins.first, fitMeanY_2);
684 i_sector.second.ResidualWidthY2->SetBinContent(i_errBins.first, residualWidthY_2);
685 i_sector.second.CorrectionY2->SetBinContent(i_errBins.first, correctionY_2 * 10000.);
689 if (entriesX < minHitsPerInterval && entriesY < minHitsPerInterval)
694 if (apeWeight ==
wUnity) {
701 weightX = entriesX / (meanSigmaX * meanSigmaX);
702 weightY = entriesY / (meanSigmaY * meanSigmaY);
705 const Error2AndResidualWidth2PerBin error2AndResidualWidth2PerBinX(meanSigmaX * meanSigmaX,
706 residualWidthX_1 * residualWidthX_1);
707 const WeightAndResultsPerBin weightAndResultsPerBinX(weightX, error2AndResidualWidth2PerBinX);
708 if (!(entriesX < minHitsPerInterval)) {
710 i_sector.second.WeightX->SetBinContent(i_errBins.first, weightX);
711 v_weightAndResultsPerBinX.push_back(weightAndResultsPerBinX);
714 const Error2AndResidualWidth2PerBin error2AndResidualWidth2PerBinY(meanSigmaY * meanSigmaY,
715 residualWidthY_1 * residualWidthY_1);
716 const WeightAndResultsPerBin weightAndResultsPerBinY(weightY, error2AndResidualWidth2PerBinY);
717 if (!(entriesY < minHitsPerInterval)) {
719 i_sector.second.WeightY->SetBinContent(i_errBins.first, weightY);
720 v_weightAndResultsPerBinY.push_back(weightAndResultsPerBinY);
726 if (v_weightAndResultsPerBinX.empty()) {
727 edm::LogError(
"CalculateAPE") <<
"NO error interval of sector " << i_sector.first
728 <<
" has a valid x APE calculated,\n...so cannot set APE";
732 if (i_sector.second.isPixel && v_weightAndResultsPerBinY.empty()) {
733 edm::LogError(
"CalculateAPE") <<
"NO error interval of sector " << i_sector.first
734 <<
" has a valid y APE calculated,\n...so cannot set APE";
738 double correctionX2(999.);
739 double correctionY2(999.);
742 double weightSumX(0.);
743 for (
auto const& i_apeBin : v_weightAndResultsPerBinX) {
744 weightSumX += i_apeBin.first;
746 i_sector.second.WeightX->Scale(1 / weightSumX);
747 double weightSumY(0.);
748 if (i_sector.second.isPixel) {
749 for (
auto const& i_apeBin : v_weightAndResultsPerBinY) {
750 weightSumY += i_apeBin.first;
752 i_sector.second.WeightY->Scale(1 / weightSumY);
757 bool firstIntervalX(
true);
758 for (
auto const& i_apeBin : v_weightAndResultsPerBinX) {
759 if (firstIntervalX) {
760 correctionX2 = i_apeBin.first * i_apeBin.second.first * (i_apeBin.second.second - baselineWidthX2);
761 firstIntervalX =
false;
763 correctionX2 += i_apeBin.first * i_apeBin.second.first * (i_apeBin.second.second - baselineWidthX2);
766 correctionX2 = correctionX2 / weightSumX;
768 double numeratorX(0.), denominatorX(0.);
769 for (
auto const& i_apeBin : v_weightAndResultsPerBinX) {
770 numeratorX += i_apeBin.first * i_apeBin.second.first * i_apeBin.second.second;
771 denominatorX += i_apeBin.first * i_apeBin.second.first;
773 correctionX2 = numeratorX / denominatorX;
776 if (i_sector.second.isPixel) {
779 bool firstIntervalY(
true);
780 for (
auto const& i_apeBin : v_weightAndResultsPerBinY) {
781 if (firstIntervalY) {
782 correctionY2 = i_apeBin.first * i_apeBin.second.first * (i_apeBin.second.second - baselineWidthY2);
783 firstIntervalY =
false;
785 correctionY2 += i_apeBin.first * i_apeBin.second.first * (i_apeBin.second.second - baselineWidthY2);
788 correctionY2 = correctionY2 / weightSumY;
790 double numeratorY(0.), denominatorY(0.);
791 for (
auto const& i_apeBin : v_weightAndResultsPerBinY) {
792 numeratorY += i_apeBin.first * i_apeBin.second.first * i_apeBin.second.second;
793 denominatorY += i_apeBin.first * i_apeBin.second.first;
795 correctionY2 = numeratorY / denominatorY;
809 apeX2 = a_apeSectorX[i_sector.first];
810 apeY2 = a_apeSectorY[i_sector.first];
812 const double apeX2old = apeX2;
813 const double apeY2old = apeY2;
816 edm::LogInfo(
"CalculateAPE") <<
"Unscaled correction x for sector " << i_sector.first <<
" is "
817 << (correctionX2 > 0. ? +1. : -1.) *
std::sqrt(std::fabs(correctionX2));
818 if (!smoothIteration || firstIter)
819 correctionX2 = correctionX2 * correctionScaling * correctionScaling;
820 if (i_sector.second.isPixel) {
821 edm::LogInfo(
"CalculateAPE") <<
"Unscaled correction y for sector " << i_sector.first <<
" is "
822 << (correctionY2 > 0. ? +1. : -1.) *
std::sqrt(std::fabs(correctionY2));
823 if (!smoothIteration || firstIter)
824 correctionY2 = correctionY2 * correctionScaling * correctionScaling;
829 if (apeX2 + correctionX2 < 0.)
830 correctionX2 = -apeX2;
831 if (apeY2 + correctionY2 < 0.)
832 correctionY2 = -apeY2;
833 const double apeX2new(apeX2old + correctionX2);
834 const double apeY2new(apeY2old + correctionY2);
835 if (!smoothIteration || firstIter) {
839 const double apeXtmp = smoothFraction *
std::sqrt(apeX2new) + (1 - smoothFraction) *
std::sqrt(apeX2old);
840 const double apeYtmp = smoothFraction *
std::sqrt(apeY2new) + (1 - smoothFraction) *
std::sqrt(apeY2old);
841 apeX2 = apeXtmp * apeXtmp;
842 apeY2 = apeYtmp * apeYtmp;
844 if (apeX2 < 0. || apeY2 < 0.)
845 edm::LogError(
"CalculateAPE") <<
"\n\n\tBad APE, but why???\n\n\n";
846 a_apeSectorX[i_sector.first] = apeX2;
847 a_apeSectorY[i_sector.first] = apeY2;
852 const double apeZ(
std::sqrt(0.5 * (apeX2 + apeY2)));
853 for (
auto const& i_rawId : i_sector.second.v_rawId) {
854 if (i_sector.second.isPixel) {
855 apeOutputFile << i_rawId <<
" " <<
std::fixed << std::setprecision(5) << apeX <<
" " << apeY <<
" " << apeZ
858 apeOutputFile << i_rawId <<
" " <<
std::fixed << std::setprecision(5) << apeX <<
" " << apeX <<
" " << apeX
863 a_apeSectorX[i_sector.first] = correctionX2;
864 a_apeSectorY[i_sector.first] = correctionY2;
868 apeOutputFile.close();
870 iterationTreeX->Fill();
871 iterationTreeX->Write(
"iterTreeX",
872 TObject::kOverwrite);
873 iterationTreeY->Fill();
874 iterationTreeY->Write(
"iterTreeY",
875 TObject::kOverwrite);
877 sectorNameTree->Fill();
878 sectorNameTree->Write(
"nameTree");
884 baselineFile->Close();