330 TFile* baselineFile(
nullptr);
331 TTree* baselineTreeX(
nullptr);
332 TTree* baselineTreeY(
nullptr);
333 TTree* sectorNameBaselineTree(
nullptr);
335 std::ifstream baselineFileStream;
337 baselineFileStream.open(baselineFileName.c_str());
338 if (baselineFileStream.is_open()) {
339 baselineFileStream.close();
340 baselineFile =
new TFile(baselineFileName.c_str(),
"READ");
343 edm::LogInfo(
"CalculateAPE") <<
"Baseline file for APE values sucessfully opened";
344 baselineFile->GetObject(
"iterTreeX;1", baselineTreeX);
345 baselineFile->GetObject(
"iterTreeY;1", baselineTreeY);
346 baselineFile->GetObject(
"nameTree;1", sectorNameBaselineTree);
348 edm::LogWarning(
"CalculateAPE") <<
"There is NO baseline file for APE values, so normalized residual width =1 "
349 "for ideal conditions is assumed";
354 const std::string iterationFileName(setBaseline ? baselineFileName
357 TFile*
iterationFile =
new TFile(iterationFileName.c_str(), setBaseline ?
"RECREATE" :
"UPDATE");
360 TTree* iterationTreeX(
nullptr);
361 TTree* iterationTreeY(
nullptr);
365 TTree* sectorNameTree(
nullptr);
368 const bool firstIter(!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);
447 const std::string& nameLastIter(*a_sectorName[i_sector.first]);
448 if (
name != nameLastIter) {
449 edm::LogError(
"CalculateAPE") <<
"Inconsistent sector definition in iterationFile for sector " << i_sector.first
451 <<
"Recent iteration has name \"" <<
name <<
"\", while previous had \""
452 << nameLastIter <<
"\"\n"
453 <<
"...APE calculation stopped. Please check sector definitions in config!\n";
457 if (!setBaseline && baselineFile) {
458 const std::string& nameBaseline(*a_sectorBaselineName[i_sector.first]);
459 if (
name != nameBaseline) {
461 edm::LogError(
"CalculateAPE") <<
"Inconsistent sector definition in baselineFile for sector " << i_sector.first
463 <<
"Recent iteration has name \"" <<
name <<
"\", while baseline had \""
464 << nameBaseline <<
"\"\n"
465 <<
"...APE calculation stopped. Please check sector definitions in config!\n";
473 delete a_sectorName[i_sector.first];
480 std::ofstream apeOutputFile;
483 apeOutputFile.open(apeOutputFileName.c_str());
484 if (apeOutputFile.is_open()) {
485 edm::LogInfo(
"CalculateAPE") <<
"Text file for writing APE values successfully opened";
487 edm::LogError(
"CalculateAPE") <<
"Text file for writing APE values NOT opened,\n"
488 <<
"...APE calculation stopped. Please check path of text file name in config:\n"
489 <<
"\t" << apeOutputFileName;
497 if (apeWeightName ==
"unity")
499 else if (apeWeightName ==
"entries")
501 else if (apeWeightName ==
"entriesOverSigmaX2")
504 edm::LogError(
"CalculateAPE") <<
"Invalid parameter 'apeWeight' in cfg file: \"" << apeWeightName
505 <<
"\"\nimplemented apeWeights are \"unity\", \"entries\", \"entriesOverSigmaX2\""
506 <<
"\n...APE calculation stopped.";
514 if (smoothFraction <= 0. || smoothFraction > 1.) {
515 edm::LogError(
"CalculateAPE") <<
"Incorrect parameter in cfg file,"
516 <<
"\nsmoothFraction has to be in [0,1], but is " << smoothFraction
517 <<
"\n...APE calculation stopped.";
521 typedef std::pair<double, double> Error2AndResidualWidth2PerBin;
522 typedef std::pair<double, Error2AndResidualWidth2PerBin> WeightAndResultsPerBin;
523 std::vector<WeightAndResultsPerBin> v_weightAndResultsPerBinX;
524 std::vector<WeightAndResultsPerBin> v_weightAndResultsPerBinY;
526 double baselineWidthX2(a_baselineSectorX[i_sector.first]);
527 double baselineWidthY2(a_baselineSectorY[i_sector.first]);
530 for (
auto const& i_errBins : i_sector.second.m_binnedHists) {
531 std::map<std::string, TH1*> mHists = i_errBins.second;
533 double entriesX = mHists[
"sigmaX"]->GetEntries();
534 double meanSigmaX = mHists[
"sigmaX"]->GetMean();
537 double xMin = mHists[
"norResX"]->GetXaxis()->GetXmin();
538 double xMax = mHists[
"norResX"]->GetXaxis()->GetXmax();
539 double integralX = mHists[
"norResX"]->Integral();
540 double meanX = mHists[
"norResX"]->GetMean();
541 double rmsX = mHists[
"norResX"]->GetRMS();
542 double maximumX = mHists[
"norResX"]->GetBinContent(mHists[
"norResX"]->GetMaximumBin());
545 TF1 funcX_1(
"mygausX",
"gaus",
xMin,
xMax);
546 funcX_1.SetParameters(maximumX, meanX, rmsX);
547 TString fitOpt(
"ILERQ");
548 if (integralX > minHitsPerInterval) {
549 if (mHists[
"norResX"]->
Fit(&funcX_1, fitOpt)) {
550 edm::LogWarning(
"CalculateAPE") <<
"Fit1 did not work: " << mHists[
"norResX"]->Fit(&funcX_1, fitOpt);
553 LogDebug(
"CalculateAPE") <<
"FitResultX1\t" << mHists[
"norResX"]->Fit(&funcX_1, fitOpt) <<
"\n";
555 double meanX_1 = funcX_1.GetParameter(1);
556 double sigmaX_1 = funcX_1.GetParameter(2);
559 TF1 funcX_2(
"mygausX2",
561 meanX_1 - sigmaFactorFit *
TMath::Abs(sigmaX_1),
562 meanX_1 + sigmaFactorFit *
TMath::Abs(sigmaX_1));
563 funcX_2.SetParameters(funcX_1.GetParameter(0), meanX_1, sigmaX_1);
564 if (integralX > minHitsPerInterval) {
565 if (mHists[
"norResX"]->
Fit(&funcX_2, fitOpt)) {
566 edm::LogWarning(
"CalculateAPE") <<
"Fit2 did not work for x : " << mHists[
"norResX"]->Fit(&funcX_2, fitOpt);
569 LogDebug(
"CalculateAPE") <<
"FitResultX2\t" << mHists[
"norResX"]->Fit(&funcX_2, fitOpt) <<
"\n";
571 double meanX_2 = funcX_2.GetParameter(1);
572 double sigmaX_2 = funcX_2.GetParameter(2);
576 double meanSigmaY(0.);
577 if (i_sector.second.isPixel) {
578 entriesY = mHists[
"sigmaY"]->GetEntries();
579 meanSigmaY = mHists[
"sigmaY"]->GetMean();
588 if (i_sector.second.isPixel) {
590 double yMin = mHists[
"norResY"]->GetXaxis()->GetXmin();
591 double yMax = mHists[
"norResY"]->GetXaxis()->GetXmax();
592 double integralY = mHists[
"norResY"]->Integral();
593 meanY = mHists[
"norResY"]->GetMean();
594 rmsY = mHists[
"norResY"]->GetRMS();
595 double maximumY = mHists[
"norResY"]->GetBinContent(mHists[
"norResY"]->GetMaximumBin());
598 TF1 funcY_1(
"mygausY",
"gaus",
yMin,
yMax);
599 funcY_1.SetParameters(maximumY, meanY, rmsY);
600 if (integralY > minHitsPerInterval) {
601 if (mHists[
"norResY"]->
Fit(&funcY_1, fitOpt)) {
602 edm::LogWarning(
"CalculateAPE") <<
"Fit1 did not work: " << mHists[
"norResY"]->Fit(&funcY_1, fitOpt);
605 LogDebug(
"CalculateAPE") <<
"FitResultY1\t" << mHists[
"norResY"]->Fit(&funcY_1, fitOpt) <<
"\n";
607 meanY_1 = funcY_1.GetParameter(1);
608 sigmaY_1 = funcY_1.GetParameter(2);
611 TF1 funcY_2(
"mygausY2",
613 meanY_1 - sigmaFactorFit *
TMath::Abs(sigmaY_1),
614 meanY_1 + sigmaFactorFit *
TMath::Abs(sigmaY_1));
615 funcY_2.SetParameters(funcY_1.GetParameter(0), meanY_1, sigmaY_1);
616 if (integralY > minHitsPerInterval) {
617 if (mHists[
"norResY"]->
Fit(&funcY_2, fitOpt)) {
618 edm::LogWarning(
"CalculateAPE") <<
"Fit2 did not work for y : " << mHists[
"norResY"]->Fit(&funcY_2, fitOpt);
621 LogDebug(
"CalculateAPE") <<
"FitResultY2\t" << mHists[
"norResY"]->Fit(&funcY_2, fitOpt) <<
"\n";
623 meanY_2 = funcY_2.GetParameter(1);
624 sigmaY_2 = funcY_2.GetParameter(2);
628 double fitMeanX_1(meanX_1), fitMeanX_2(meanX_2);
629 double residualWidthX_1(sigmaX_1), residualWidthX_2(sigmaX_2);
630 double fitMeanY_1(meanY_1), fitMeanY_2(meanY_2);
631 double residualWidthY_1(sigmaY_1), residualWidthY_2(sigmaY_2);
633 double correctionX2_1(-0.0010), correctionX2_2(-0.0010);
634 double correctionY2_1(-0.0010), correctionY2_2(-0.0010);
635 correctionX2_1 = meanSigmaX * meanSigmaX * (residualWidthX_1 * residualWidthX_1 - baselineWidthX2);
636 correctionX2_2 = meanSigmaX * meanSigmaX * (residualWidthX_2 * residualWidthX_2 - baselineWidthX2);
637 if (i_sector.second.isPixel) {
638 correctionY2_1 = meanSigmaY * meanSigmaY * (residualWidthY_1 * residualWidthY_1 - baselineWidthY2);
639 correctionY2_2 = meanSigmaY * meanSigmaY * (residualWidthY_2 * residualWidthY_2 - baselineWidthY2);
642 double correctionX_1 = correctionX2_1 >= 0. ?
std::sqrt(correctionX2_1) : -
std::
sqrt(-correctionX2_1);
643 double correctionX_2 = correctionX2_2 >= 0. ?
std::sqrt(correctionX2_2) : -
std::
sqrt(-correctionX2_2);
644 double correctionY_1 = correctionY2_1 >= 0. ?
std::sqrt(correctionY2_1) : -
std::
sqrt(-correctionY2_1);
645 double correctionY_2 = correctionY2_2 >= 0. ?
std::sqrt(correctionY2_2) : -
std::
sqrt(-correctionY2_2);
648 correctionX_1 = -0.0010;
650 correctionX_2 = -0.0010;
652 correctionY_1 = -0.0010;
654 correctionY_2 = -0.0010;
656 if (entriesX < minHitsPerInterval) {
660 correctionX_1 = residualWidthX_1 = -0.0010;
662 correctionX_2 = residualWidthX_2 = -0.0010;
665 if (entriesY < minHitsPerInterval) {
669 correctionY_1 = residualWidthY_1 = -0.0010;
671 correctionY_2 = residualWidthY_2 = -0.0010;
674 i_sector.second.MeanX->SetBinContent(i_errBins.first, meanX);
675 i_sector.second.RmsX->SetBinContent(i_errBins.first, rmsX);
677 i_sector.second.FitMeanX1->SetBinContent(i_errBins.first, fitMeanX_1);
678 i_sector.second.ResidualWidthX1->SetBinContent(i_errBins.first, residualWidthX_1);
679 i_sector.second.CorrectionX1->SetBinContent(i_errBins.first, correctionX_1 * 10000.);
681 i_sector.second.FitMeanX2->SetBinContent(i_errBins.first, fitMeanX_2);
682 i_sector.second.ResidualWidthX2->SetBinContent(i_errBins.first, residualWidthX_2);
683 i_sector.second.CorrectionX2->SetBinContent(i_errBins.first, correctionX_2 * 10000.);
685 if (i_sector.second.isPixel) {
686 i_sector.second.MeanY->SetBinContent(i_errBins.first, meanY);
687 i_sector.second.RmsY->SetBinContent(i_errBins.first, rmsY);
689 i_sector.second.FitMeanY1->SetBinContent(i_errBins.first, fitMeanY_1);
690 i_sector.second.ResidualWidthY1->SetBinContent(i_errBins.first, residualWidthY_1);
691 i_sector.second.CorrectionY1->SetBinContent(i_errBins.first, correctionY_1 * 10000.);
693 i_sector.second.FitMeanY2->SetBinContent(i_errBins.first, fitMeanY_2);
694 i_sector.second.ResidualWidthY2->SetBinContent(i_errBins.first, residualWidthY_2);
695 i_sector.second.CorrectionY2->SetBinContent(i_errBins.first, correctionY_2 * 10000.);
699 if (entriesX < minHitsPerInterval && entriesY < minHitsPerInterval)
704 if (apeWeight ==
wUnity) {
711 weightX = entriesX / (meanSigmaX * meanSigmaX);
712 weightY = entriesY / (meanSigmaY * meanSigmaY);
715 const Error2AndResidualWidth2PerBin error2AndResidualWidth2PerBinX(meanSigmaX * meanSigmaX,
716 residualWidthX_1 * residualWidthX_1);
717 const WeightAndResultsPerBin weightAndResultsPerBinX(weightX, error2AndResidualWidth2PerBinX);
718 if (!(entriesX < minHitsPerInterval)) {
720 i_sector.second.WeightX->SetBinContent(i_errBins.first, weightX);
721 v_weightAndResultsPerBinX.push_back(weightAndResultsPerBinX);
724 const Error2AndResidualWidth2PerBin error2AndResidualWidth2PerBinY(meanSigmaY * meanSigmaY,
725 residualWidthY_1 * residualWidthY_1);
726 const WeightAndResultsPerBin weightAndResultsPerBinY(weightY, error2AndResidualWidth2PerBinY);
727 if (!(entriesY < minHitsPerInterval)) {
729 i_sector.second.WeightY->SetBinContent(i_errBins.first, weightY);
730 v_weightAndResultsPerBinY.push_back(weightAndResultsPerBinY);
736 if (v_weightAndResultsPerBinX.empty()) {
737 edm::LogError(
"CalculateAPE") <<
"NO error interval of sector " << i_sector.first
738 <<
" has a valid x APE calculated,\n...so cannot set APE";
742 if (i_sector.second.isPixel && v_weightAndResultsPerBinY.empty()) {
743 edm::LogError(
"CalculateAPE") <<
"NO error interval of sector " << i_sector.first
744 <<
" has a valid y APE calculated,\n...so cannot set APE";
748 double correctionX2(999.);
749 double correctionY2(999.);
752 double weightSumX(0.);
753 for (
auto const& i_apeBin : v_weightAndResultsPerBinX) {
754 weightSumX += i_apeBin.first;
756 i_sector.second.WeightX->Scale(1 / weightSumX);
757 double weightSumY(0.);
758 if (i_sector.second.isPixel) {
759 for (
auto const& i_apeBin : v_weightAndResultsPerBinY) {
760 weightSumY += i_apeBin.first;
762 i_sector.second.WeightY->Scale(1 / weightSumY);
767 bool firstIntervalX(
true);
768 for (
auto const& i_apeBin : v_weightAndResultsPerBinX) {
769 if (firstIntervalX) {
770 correctionX2 = i_apeBin.first * i_apeBin.second.first * (i_apeBin.second.second - baselineWidthX2);
771 firstIntervalX =
false;
773 correctionX2 += i_apeBin.first * i_apeBin.second.first * (i_apeBin.second.second - baselineWidthX2);
776 correctionX2 = correctionX2 / weightSumX;
778 double numeratorX(0.), denominatorX(0.);
779 for (
auto const& i_apeBin : v_weightAndResultsPerBinX) {
780 numeratorX += i_apeBin.first * i_apeBin.second.first * i_apeBin.second.second;
781 denominatorX += i_apeBin.first * i_apeBin.second.first;
783 correctionX2 = numeratorX / denominatorX;
786 if (i_sector.second.isPixel) {
789 bool firstIntervalY(
true);
790 for (
auto const& i_apeBin : v_weightAndResultsPerBinY) {
791 if (firstIntervalY) {
792 correctionY2 = i_apeBin.first * i_apeBin.second.first * (i_apeBin.second.second - baselineWidthY2);
793 firstIntervalY =
false;
795 correctionY2 += i_apeBin.first * i_apeBin.second.first * (i_apeBin.second.second - baselineWidthY2);
798 correctionY2 = correctionY2 / weightSumY;
800 double numeratorY(0.), denominatorY(0.);
801 for (
auto const& i_apeBin : v_weightAndResultsPerBinY) {
802 numeratorY += i_apeBin.first * i_apeBin.second.first * i_apeBin.second.second;
803 denominatorY += i_apeBin.first * i_apeBin.second.first;
805 correctionY2 = numeratorY / denominatorY;
819 apeX2 = a_apeSectorX[i_sector.first];
820 apeY2 = a_apeSectorY[i_sector.first];
822 const double apeX2old = apeX2;
823 const double apeY2old = apeY2;
826 edm::LogInfo(
"CalculateAPE") <<
"Unscaled correction x for sector " << i_sector.first <<
" is "
827 << (correctionX2 > 0. ? +1. : -1.) *
std::sqrt(std::fabs(correctionX2));
828 if (!smoothIteration || firstIter)
829 correctionX2 = correctionX2 * correctionScaling * correctionScaling;
830 if (i_sector.second.isPixel) {
831 edm::LogInfo(
"CalculateAPE") <<
"Unscaled correction y for sector " << i_sector.first <<
" is "
832 << (correctionY2 > 0. ? +1. : -1.) *
std::sqrt(std::fabs(correctionY2));
833 if (!smoothIteration || firstIter)
834 correctionY2 = correctionY2 * correctionScaling * correctionScaling;
839 if (apeX2 + correctionX2 < 0.)
840 correctionX2 = -apeX2;
841 if (apeY2 + correctionY2 < 0.)
842 correctionY2 = -apeY2;
843 const double apeX2new(apeX2old + correctionX2);
844 const double apeY2new(apeY2old + correctionY2);
845 if (!smoothIteration || firstIter) {
849 const double apeXtmp = smoothFraction *
std::sqrt(apeX2new) + (1 - smoothFraction) *
std::sqrt(apeX2old);
850 const double apeYtmp = smoothFraction *
std::sqrt(apeY2new) + (1 - smoothFraction) *
std::sqrt(apeY2old);
851 apeX2 = apeXtmp * apeXtmp;
852 apeY2 = apeYtmp * apeYtmp;
854 if (apeX2 < 0. || apeY2 < 0.)
855 edm::LogError(
"CalculateAPE") <<
"\n\n\tBad APE, but why???\n\n\n";
856 a_apeSectorX[i_sector.first] = apeX2;
857 a_apeSectorY[i_sector.first] = apeY2;
862 const double apeZ(
std::sqrt(0.5 * (apeX2 + apeY2)));
863 for (
auto const& i_rawId : i_sector.second.v_rawId) {
864 if (i_sector.second.isPixel) {
865 apeOutputFile << i_rawId <<
" " <<
std::fixed << std::setprecision(5) << apeX <<
" " << apeY <<
" " << apeZ
868 apeOutputFile << i_rawId <<
" " <<
std::fixed << std::setprecision(5) << apeX <<
" " << apeX <<
" " << apeX
873 a_apeSectorX[i_sector.first] = correctionX2;
874 a_apeSectorY[i_sector.first] = correctionY2;
878 apeOutputFile.close();
880 iterationTreeX->Fill();
881 iterationTreeX->Write(
"iterTreeX",
882 TObject::kOverwrite);
883 iterationTreeY->Fill();
884 iterationTreeY->Write(
"iterTreeY",
885 TObject::kOverwrite);
887 sectorNameTree->Fill();
888 sectorNameTree->Write(
"nameTree");
890 delete a_sectorName[i_sector.first];
897 baselineFile->Close();