File indexing completed on 2025-12-17 09:12:32
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <bitset>
0010 #include <fstream>
0011 #include <iostream>
0012 #include <limits>
0013 #include <map>
0014 #include <string>
0015 #include <vector>
0016
0017 #include <TCanvas.h>
0018 #include <TChain.h>
0019 #include <TF1.h>
0020 #include <TFile.h>
0021 #include <TH1F.h>
0022 #include <TH2F.h>
0023 #include <TH3F.h>
0024 #include <TLegend.h>
0025 #include <TMath.h>
0026 #include <TStyle.h>
0027 #include <TTree.h>
0028 #include <TVectorF.h>
0029
0030 #include "CommonUtils.h"
0031 #include "TreeReader.h"
0032
0033 using namespace ROOT;
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053 int trackSummaryAnalysis(
0054 const std::vector<std::string>& inFiles, const std::string& inTree,
0055 const std::string& outFile, const std::string& inConfig = "",
0056 const std::string& outConfig = "", unsigned long nEntries = 0,
0057 unsigned int nPeakEntries = 0, float pullRange = 6.,
0058 unsigned int nHistBins = 61, unsigned int nPhiBins = 10,
0059 const std::array<float, 2>& phiRange = {-M_PI, M_PI},
0060 unsigned int nEtaBins = 10, const std::array<float, 2>& etaRange = {-3, 3},
0061 const std::vector<double>& ptBorders =
0062 {0., std::numeric_limits<double>::infinity()},
0063 const std::bitset<7>& residualPulls = std::bitset<7>{"1111111"},
0064 const std::bitset<5>& auxiliary = std::bitset<5>{"11111"}) {
0065
0066 TChain* treeChain = new TChain(inTree.c_str());
0067 for (const auto& inFile : inFiles) {
0068 treeChain->Add(inFile.c_str());
0069
0070 std::cout << "*** Adding file: " << inFile << std::endl;
0071 }
0072
0073 if (treeChain->GetEntries() == 0) {
0074 std::cout << "xxx No entries found ... bailing out." << std::endl;
0075 return -1;
0076 }
0077
0078 TCanvas* rangeCanvas =
0079 new TCanvas("rangeCanvas", "Range Estimation", 100, 100, 620, 400);
0080
0081 TrackSummaryReader tracks(treeChain, true);
0082
0083
0084 unsigned long entries = estimateEntries(*tracks.tree, nEntries);
0085 unsigned long peakEntries = estimateEntries(*tracks.tree, nPeakEntries);
0086
0087
0088 unsigned int histBarcode = 0;
0089
0090
0091 unsigned int nPtBins = ptBorders.size() - 1;
0092
0093
0094 using ResidualPulls = std::vector<ResidualPullHandle>;
0095 ResidualPulls baseResidualPulls = {};
0096
0097 if (residualPulls.test(0)) {
0098
0099 ResidualPullHandle d0Handle;
0100 d0Handle.tag = "d0";
0101 d0Handle.residualStr = "d_{0}^{rec} - d_{0}^{true}";
0102 d0Handle.residualUnit = "[mm]";
0103 d0Handle.errorStr = "#sigma(d_{0})";
0104 d0Handle.rangeDrawStr = "eLOC0_fit-t_d0";
0105 d0Handle.rangeMaxStr = "(1000,-10,10)";
0106 d0Handle.value = ResidualAccessor{tracks.eLOC0_fit, tracks.t_d0};
0107 d0Handle.error = DirectAccessor<float>{tracks.err_eLOC0_fit};
0108 d0Handle.accept = AcceptAll{};
0109
0110 baseResidualPulls.push_back(d0Handle);
0111 }
0112
0113 if (residualPulls.test(1)) {
0114
0115 ResidualPullHandle z0Handle;
0116 z0Handle.tag = "z0";
0117 z0Handle.residualStr = "z_{0}^{rec} - z_{0}^{true}";
0118 z0Handle.residualUnit = "[mm]";
0119 z0Handle.errorStr = "#sigma(z_{0})";
0120 z0Handle.rangeDrawStr = "eLOC1_fit-t_z0";
0121 z0Handle.rangeMaxStr = "(1000,-10,10)";
0122 z0Handle.value = ResidualAccessor{tracks.eLOC1_fit, tracks.t_z0};
0123 z0Handle.error = DirectAccessor<float>{tracks.err_eLOC1_fit};
0124 z0Handle.accept = AcceptAll{};
0125
0126 baseResidualPulls.push_back(z0Handle);
0127 }
0128
0129 if (residualPulls.test(2)) {
0130
0131 ResidualPullHandle phi0Handle;
0132 phi0Handle.tag = "phi0";
0133 phi0Handle.residualStr = "#phi_{0}^{rec} - #phi_{0}^{true}";
0134 phi0Handle.errorStr = "#sigma(phi_{0})";
0135 phi0Handle.rangeDrawStr = "ePHI_fit-t_phi";
0136 phi0Handle.rangeMaxStr = "(1000,-0.01,0.01)";
0137 phi0Handle.value = ResidualAccessor{tracks.ePHI_fit, tracks.t_phi};
0138 phi0Handle.error = DirectAccessor<float>{tracks.err_ePHI_fit};
0139 phi0Handle.accept = AcceptAll{};
0140
0141 baseResidualPulls.push_back(phi0Handle);
0142 }
0143
0144 if (residualPulls.test(3)) {
0145
0146 ResidualPullHandle theta0Handle;
0147 theta0Handle.tag = "theta0";
0148 theta0Handle.residualStr = "#theta_{0}^{rec} - #theta_{0}^{true}";
0149 theta0Handle.errorStr = "#sigma(theta_{0})";
0150 theta0Handle.rangeDrawStr = "eTHETA_fit-t_theta";
0151 theta0Handle.rangeMaxStr = "(1000,-0.01,0.01)";
0152 theta0Handle.value = ResidualAccessor{tracks.eTHETA_fit, tracks.t_theta};
0153 theta0Handle.error = DirectAccessor<float>{tracks.err_eTHETA_fit};
0154 theta0Handle.accept = AcceptAll{};
0155
0156 baseResidualPulls.push_back(theta0Handle);
0157 }
0158
0159 if (residualPulls.test(4)) {
0160
0161 ResidualPullHandle qopHandle;
0162 qopHandle.tag = "qop";
0163 qopHandle.residualStr = "q/p^{rec} - q/p^{true}";
0164 qopHandle.residualUnit = "[GeV^{-1}]";
0165 qopHandle.errorStr = "#sigma(q/p)";
0166 qopHandle.rangeDrawStr = "eQOP_fit-t_charge/t_p";
0167 qopHandle.rangeMaxStr = "(1000,-0.1,0.1)";
0168 qopHandle.value =
0169 QopResidualAccessor{tracks.eQOP_fit, tracks.t_charge, tracks.t_p};
0170 qopHandle.error = DirectAccessor<float>{tracks.err_eQOP_fit};
0171 qopHandle.accept = AcceptAll{};
0172
0173 baseResidualPulls.push_back(qopHandle);
0174 }
0175
0176 if (residualPulls.test(5)) {
0177
0178 ResidualPullHandle tHandle;
0179 tHandle.tag = "t";
0180 tHandle.residualStr = "t^{rec} - t^{true}";
0181 tHandle.residualUnit = "[ns]";
0182 tHandle.errorStr = "#sigma(t})";
0183 tHandle.rangeDrawStr = "eT_fit - t_time";
0184 tHandle.rangeMaxStr = "(1000,-10.,10.)";
0185 tHandle.value = ResidualAccessor{tracks.eT_fit, tracks.t_time};
0186 tHandle.error = DirectAccessor<float>{tracks.err_eT_fit};
0187 tHandle.accept = AcceptAll{};
0188
0189 baseResidualPulls.push_back(tHandle);
0190 }
0191
0192 if (residualPulls.test(6)) {
0193
0194 ResidualPullHandle ptHandle;
0195 ptHandle.tag = "pt";
0196 ptHandle.residualStr = "p_{T}^{rec} - p_{T}^{true}";
0197 ptHandle.residualUnit = "[GeV]";
0198 ptHandle.errorStr = "#sigma(p_{T})";
0199 ptHandle.rangeDrawStr = "1./abs(eQOP_fit) * sin(eTHETA_fit) - (1./t_pT)";
0200 ptHandle.rangeMaxStr = "(1000,-10.,10.)";
0201 ptHandle.value =
0202 PtResidualAccessor{tracks.eQOP_fit, tracks.eTHETA_fit, tracks.t_pT};
0203 ptHandle.error = PtErrorAccessor{tracks.eQOP_fit, tracks.err_eQOP_fit,
0204 tracks.eTHETA_fit, tracks.err_eTHETA_fit};
0205 ptHandle.accept = AcceptAll{};
0206
0207 baseResidualPulls.push_back(ptHandle);
0208 }
0209
0210 using Auxiliaries = std::vector<SingleHandle>;
0211 Auxiliaries baseAuxilaries;
0212
0213 if (auxiliary.test(0)) {
0214
0215 SingleHandle chi2ndf;
0216 chi2ndf.tag = "chi2ndf";
0217 chi2ndf.label = "#Chi^{2}/ndf";
0218 chi2ndf.bins = nHistBins;
0219 chi2ndf.range = {0., 5.};
0220 chi2ndf.value =
0221 DivisionAccessor<float, unsigned int>{tracks.chi2Sum, tracks.NDF};
0222 chi2ndf.accept = AcceptAll{};
0223
0224 baseAuxilaries.push_back(chi2ndf);
0225 }
0226
0227 if (auxiliary.test(1)) {
0228
0229 SingleHandle measurements;
0230 measurements.tag = "measurements";
0231 measurements.label = "#(measurements)";
0232 measurements.rangeDrawStr = "nMeasurements";
0233 measurements.value = DirectAccessor<unsigned int>{tracks.nMeasurements};
0234 measurements.accept = AcceptAll{};
0235 estimateIntegerRange(measurements, *rangeCanvas, *tracks.tree, peakEntries,
0236 250, 5, ++histBarcode);
0237
0238 baseAuxilaries.push_back(measurements);
0239 }
0240
0241 if (auxiliary.test(2)) {
0242
0243 SingleHandle holes;
0244 holes.tag = "holes";
0245 holes.label = "#(holes)";
0246 holes.rangeDrawStr = "nHoles";
0247 holes.value = DirectAccessor<unsigned int>{tracks.nHoles};
0248 holes.accept = AcceptAll{};
0249 estimateIntegerRange(holes, *rangeCanvas, *tracks.tree, peakEntries, 10, 2,
0250 ++histBarcode);
0251
0252 baseAuxilaries.push_back(holes);
0253 }
0254
0255 if (auxiliary.test(3)) {
0256
0257 SingleHandle outliers;
0258 outliers.tag = "outliers";
0259 outliers.label = "#(outliers)";
0260 outliers.rangeDrawStr = "nOutliers";
0261 outliers.value = DirectAccessor<unsigned int>{tracks.nOutliers};
0262 outliers.accept = AcceptAll{};
0263 estimateIntegerRange(outliers, *rangeCanvas, *tracks.tree, peakEntries, 10,
0264 2, ++histBarcode);
0265
0266 baseAuxilaries.push_back(outliers);
0267 }
0268
0269 if (auxiliary.test(4)) {
0270
0271 SingleHandle shared;
0272 shared.tag = "shared";
0273 shared.label = "#(shared)";
0274 shared.rangeDrawStr = "nSharedHits";
0275 shared.value = DirectAccessor<unsigned int>{tracks.nSharedHits};
0276 shared.accept = AcceptAll{};
0277 estimateIntegerRange(shared, *rangeCanvas, *tracks.tree, peakEntries, 10, 2,
0278 ++histBarcode);
0279
0280 baseAuxilaries.push_back(shared);
0281 }
0282
0283
0284 #ifdef NLOHMANN_AVAILABLE
0285 nlohmann::json handle_configs;
0286 if (! inConfig.empty()) {
0287 std::ifstream ifs(inConfig.c_str());
0288 handle_configs = nlohmann::json::parse(ifs);
0289 }
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299 auto handleRange = [&](ResidualPullHandle& handle, const TString& handleTag, unsigned int peakE) -> void {
0300 bool rangeDetermined = false;
0301 if (! inConfig.empty()) {
0302 if (handle_configs.contains((handleTag).Data())) {
0303 auto handle_config = handle_configs[(handleTag).Data()];
0304 handle.range = handle_config["range"].get<std::array<float, 2>>();
0305 rangeDetermined = true;
0306 }
0307 }
0308 if (! rangeDetermined) {
0309 estimateResiudalRange(handle, *rangeCanvas, *tracks.tree, peakE,
0310 ++histBarcode);
0311 }
0312
0313 if (! outConfig.empty()) {
0314 nlohmann::json range_config;
0315 range_config["range"] = handle.range;
0316 handle_configs[(handleTag).Data()] = range_config;
0317 }
0318 };
0319 #else
0320
0321
0322
0323
0324
0325 auto handleRange = [&](ResidualPullHandle& handle, const TString& handleTag,
0326 unsigned long peakEntries) -> void {
0327 estimateResiudalRange(handle, *rangeCanvas, *tracks.tree, peakEntries,
0328 ++histBarcode);
0329 };
0330 #endif
0331
0332
0333 ResidualPulls fullResidualPulls = baseResidualPulls;
0334
0335 for (auto& fHandle : fullResidualPulls) {
0336
0337 TString handleTag(fHandle.tag + std::string("_all"));
0338 handleRange(fHandle, handleTag, peakEntries);
0339
0340 bookHistograms(fHandle, pullRange, nHistBins, ++histBarcode);
0341
0342 TString residualN = TString("res_") + handleTag;
0343 TString pullN = TString("pull_") + handleTag;
0344
0345 setHistStyle(fHandle.residualHist);
0346 fHandle.residualHist->SetName(residualN);
0347 setHistStyle(fHandle.pullHist);
0348 fHandle.pullHist->SetName(pullN);
0349 }
0350
0351
0352 using ResidualPullsVector = std::vector<ResidualPulls>;
0353 using ResidualPullsMatrix = std::vector<ResidualPullsVector>;
0354
0355
0356 ResidualPullsVector ptResidualPulls =
0357 ResidualPullsVector(nPtBins, baseResidualPulls);
0358 ResidualPullsMatrix etaPtResidualPulls =
0359 ResidualPullsMatrix(nEtaBins, ptResidualPulls);
0360
0361
0362 ResidualPullsVector phiResidualPulls =
0363 ResidualPullsVector(nPhiBins, baseResidualPulls);
0364 ResidualPullsMatrix etaPhiResidualPulls =
0365 ResidualPullsMatrix(nEtaBins, phiResidualPulls);
0366
0367 Auxiliaries fullAuxiliaries = baseAuxilaries;
0368
0369
0370 for (auto& fAuxiliary : fullAuxiliaries) {
0371 fAuxiliary.hist =
0372 new TH1F(fAuxiliary.tag.c_str(), fAuxiliary.tag.c_str(),
0373 fAuxiliary.bins, fAuxiliary.range[0], fAuxiliary.range[1]);
0374 fAuxiliary.hist->GetXaxis()->SetTitle(fAuxiliary.label.c_str());
0375 fAuxiliary.hist->GetYaxis()->SetTitle("Entries");
0376 setHistStyle(fAuxiliary.hist);
0377 }
0378
0379 using AuxiliariesVector = std::vector<Auxiliaries>;
0380 using AuxiliariesMatrix = std::vector<AuxiliariesVector>;
0381
0382
0383 AuxiliariesVector ptAuxiliaries = AuxiliariesVector(nPtBins, baseAuxilaries);
0384 AuxiliariesMatrix etaPtAuxiliaries =
0385 AuxiliariesMatrix(nEtaBins, ptAuxiliaries);
0386
0387
0388 AuxiliariesVector phiAuxiliaries =
0389 AuxiliariesVector(nPhiBins, baseAuxilaries);
0390 AuxiliariesMatrix etaPhiAuxiliaries =
0391 AuxiliariesMatrix(nEtaBins, phiAuxiliaries);
0392
0393
0394 float phiStep = (phiRange[1] - phiRange[0]) / nPhiBins;
0395 float etaStep = (etaRange[1] - etaRange[0]) / nEtaBins;
0396
0397 TVectorF phiVals(nPhiBins + 1);
0398 TVectorF etaVals(nEtaBins + 1);
0399 TVectorF ptVals(nPtBins + 1);
0400
0401 phiVals[0] = phiRange[0];
0402 etaVals[0] = etaRange[0];
0403 ptVals[0] = ptBorders[0];
0404
0405 #ifdef BOOST_AVAILABLE
0406 std::cout << "*** Handle Preparation: " << std::endl;
0407 progress_display handle_preparation_progress(
0408 nPhiBins * nEtaBins * nPtBins * baseResidualPulls.size());
0409 #endif
0410
0411 std::string land = " && ";
0412
0413
0414 for (unsigned int iphi = 0; iphi < nPhiBins; ++iphi) {
0415
0416 float phiMin = phiRange[0] + iphi * phiStep;
0417 float phiMax = phiRange[0] + (iphi + 1) * phiStep;
0418 phiVals[iphi + 1] = phiMax;
0419
0420
0421 AcceptRange phiBin{tracks.t_phi, {phiMin, phiMax}};
0422
0423 TString phiTag = "_phi";
0424 phiTag += iphi;
0425
0426 std::string phiCut = "t_phi >= ";
0427 phiCut += std::to_string(phiMin);
0428 phiCut += land;
0429 phiCut += std::string("t_phi < ");
0430 phiCut += std::to_string(phiMax);
0431
0432 for (unsigned int ieta = 0; ieta < nEtaBins; ++ieta) {
0433
0434 float etaMin = etaRange[0] + ieta * etaStep;
0435 float etaMax = etaRange[0] + (ieta + 1) * etaStep;
0436 etaVals[ieta + 1] = etaMax;
0437
0438 AcceptRange etaBin{tracks.t_eta, {etaMin, etaMax}};
0439
0440 TString etaTag = "_eta";
0441 etaTag += ieta;
0442
0443 std::string etaCut = "t_eta >= ";
0444 etaCut += std::to_string(etaMin);
0445 etaCut += land;
0446 etaCut += std::string("t_eta < ");
0447 etaCut += std::to_string(etaMax);
0448
0449
0450 AcceptCombination etaPhiBin{etaBin, phiBin};
0451 TString etaPhiTag = etaTag + phiTag;
0452
0453 for (unsigned int ipt = 0; ipt < nPtBins; ++ipt) {
0454
0455 float ptMin = static_cast<float>(ptBorders[ipt]);
0456 float ptMax = static_cast<float>(ptBorders[ipt + 1]);
0457 AcceptRange ptBin{tracks.t_pT, {ptMin, ptMax}};
0458
0459 float upperPtBorder =
0460 ptBorders[ipt + 1] == std::numeric_limits<double>::infinity()
0461 ? 100.
0462 : ptBorders[ipt + 1];
0463 ptVals[ipt + 1] = upperPtBorder;
0464
0465 TString ptTag = "_pt";
0466 ptTag += ipt;
0467
0468
0469 std::string ptCut = "t_pT >= ";
0470 ptCut += std::to_string(ptMin);
0471 ptCut += land;
0472 ptCut += std::string("t_pT < ");
0473 ptCut += std::to_string(ptMax);
0474
0475
0476 AcceptCombination etaPtBin{etaBin, ptBin};
0477
0478 for (unsigned int iresp = 0; iresp < baseResidualPulls.size();
0479 ++iresp) {
0480
0481 if (iphi == 0) {
0482 auto& etaPtHandle = etaPtResidualPulls[ieta][ipt][iresp];
0483
0484 TString handleTag(etaPtHandle.tag + etaTag + ptTag);
0485
0486 etaPtHandle.accept = etaPtBin;
0487 etaPtHandle.rangeCutStr = ptCut + land + etaCut;
0488 handleRange(etaPtHandle, handleTag, peakEntries);
0489 bookHistograms(etaPtHandle, pullRange, nHistBins, ++histBarcode);
0490
0491
0492 TString residualN = TString("res_") + handleTag;
0493 TString pullN = TString("pull_") + handleTag;
0494
0495 if (etaPtHandle.rangeHist != nullptr) {
0496 TString rangeN = TString("range_") + handleTag;
0497 setHistStyle(etaPtHandle.rangeHist);
0498 etaPtHandle.rangeHist->SetName(rangeN);
0499 }
0500 setHistStyle(etaPtHandle.residualHist);
0501 etaPtHandle.residualHist->SetName(residualN);
0502 setHistStyle(etaPtHandle.pullHist);
0503 etaPtHandle.pullHist->SetName(pullN);
0504 }
0505
0506 if (ipt == 0) {
0507 auto& etaPhiHandle = etaPhiResidualPulls[ieta][iphi][iresp];
0508
0509 TString handleTag(etaPhiHandle.tag + etaTag + phiTag);
0510 etaPhiHandle.accept = etaPhiBin;
0511 handleRange(etaPhiHandle, handleTag, peakEntries);
0512 bookHistograms(etaPhiHandle, pullRange, nHistBins, ++histBarcode);
0513
0514
0515 TString residualN = TString("res_") + handleTag;
0516 TString pullN = TString("pull_") + handleTag;
0517
0518
0519 if (etaPhiHandle.rangeHist != nullptr) {
0520 TString rangeN = TString("range_") + handleTag;
0521 setHistStyle(etaPhiHandle.rangeHist);
0522 etaPhiHandle.rangeHist->SetName(rangeN);
0523 }
0524 setHistStyle(etaPhiHandle.residualHist);
0525 etaPhiHandle.residualHist->SetName(residualN);
0526 setHistStyle(etaPhiHandle.pullHist);
0527 etaPhiHandle.pullHist->SetName(pullN);
0528 }
0529
0530 #ifdef BOOST_AVAILABLE
0531 ++handle_preparation_progress;
0532 #endif
0533 }
0534
0535
0536 for (unsigned int iaux = 0; iaux < baseAuxilaries.size(); ++iaux) {
0537
0538 if (iphi == 0) {
0539 auto& etaPtAux = etaPtAuxiliaries[ieta][ipt][iaux];
0540 etaPtAux.accept = etaPtBin;
0541 TString handleTag(etaPtAux.tag + etaTag + ptTag);
0542 etaPtAux.hist =
0543 new TH1F(handleTag.Data(), etaPtAux.tag.c_str(), etaPtAux.bins,
0544 etaPtAux.range[0], etaPtAux.range[1]);
0545 etaPtAux.hist->GetXaxis()->SetTitle(etaPtAux.label.c_str());
0546 etaPtAux.hist->GetYaxis()->SetTitle("Entries");
0547 setHistStyle(etaPtAux.hist);
0548 }
0549
0550
0551 if (ipt == 0) {
0552 auto& etaPhiAux = etaPhiAuxiliaries[ieta][iphi][iaux];
0553 etaPhiAux.accept = etaPhiBin;
0554 TString handleTag(etaPhiAux.tag + etaTag + phiTag);
0555 etaPhiAux.hist = new TH1F(handleTag.Data(), etaPhiAux.tag.c_str(),
0556 etaPhiAux.bins, etaPhiAux.range[0],
0557 etaPhiAux.range[1]);
0558 etaPhiAux.hist->GetXaxis()->SetTitle(etaPhiAux.label.c_str());
0559 etaPhiAux.hist->GetYaxis()->SetTitle("Entries");
0560 setHistStyle(etaPhiAux.hist);
0561 }
0562 }
0563 }
0564 }
0565 }
0566
0567 #ifdef NLOHMANN_AVAILABLE
0568 if (! outConfig.empty()) {
0569 std::ofstream config_out;
0570 config_out.open(outConfig.c_str());
0571 config_out << handle_configs.dump(4);
0572 }
0573 #endif
0574
0575 #ifdef BOOST_AVAILABLE
0576 std::cout << "*** Event Loop: " << std::endl;
0577 progress_display event_loop_progress(entries);
0578 #endif
0579
0580 for (unsigned long ie = 0; ie < entries; ++ie) {
0581 #ifdef BOOST_AVAILABLE
0582 ++event_loop_progress;
0583 #endif
0584
0585
0586 tracks.tree->GetEntry(ie);
0587 std::size_t nTracks = tracks.hasFittedParams->size();
0588 for (std::size_t it = 0; it < nTracks; ++it) {
0589 if (tracks.hasFittedParams->at(it)) {
0590
0591
0592 for (auto& fHandle : fullResidualPulls) {
0593 fHandle.fill(it);
0594 }
0595
0596
0597 for (auto& etaBatch : etaPtResidualPulls) {
0598 for (auto& ptBatch : etaBatch) {
0599 for (auto& bHandle : ptBatch) {
0600 bHandle.fill(it);
0601 }
0602 }
0603 }
0604
0605
0606 for (auto& etaBatch : etaPhiResidualPulls) {
0607 for (auto& phiBatch : etaBatch) {
0608 for (auto& bHandle : phiBatch) {
0609 bHandle.fill(it);
0610 }
0611 }
0612 }
0613 }
0614
0615
0616
0617 for (auto& fAuxiliary : fullAuxiliaries) {
0618 fAuxiliary.fill(it);
0619 }
0620
0621
0622 for (auto& etaBatch : etaPtAuxiliaries) {
0623 for (auto& ptBatch : etaBatch) {
0624 for (auto& bHandle : ptBatch) {
0625 bHandle.fill(it);
0626 }
0627 }
0628 }
0629
0630
0631 for (auto& etaBatch : etaPhiAuxiliaries) {
0632 for (auto& phiBatch : etaBatch) {
0633 for (auto& bHandle : phiBatch) {
0634 bHandle.fill(it);
0635 }
0636 }
0637 }
0638 }
0639 }
0640
0641
0642 auto output = TFile::Open(outFile.c_str(), "recreate");
0643 output->cd();
0644
0645
0646 for (auto& fHandle : fullResidualPulls) {
0647 if (fHandle.rangeHist != nullptr) {
0648 fHandle.rangeHist->Write();
0649 }
0650 fHandle.residualHist->Write();
0651 fHandle.pullHist->Write();
0652 }
0653
0654
0655 for (auto& fAuxiliary : fullAuxiliaries) {
0656 fAuxiliary.hist->SetName(fAuxiliary.hist->GetName() + TString("_all"));
0657 fAuxiliary.hist->Write();
0658 }
0659
0660 struct SummaryHistograms {
0661 TH2F* fillStats = nullptr;
0662
0663 std::vector<TH2F*> residualRMS;
0664 std::vector<TH2F*> residualMean;
0665 std::vector<TH2F*> pullSigma;
0666 std::vector<TH2F*> pullMean;
0667
0668 std::vector<TH2F*> auxiliaries;
0669 };
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681 auto analyseBins = [&](ResidualPullsMatrix& residualPullsMatrix,
0682 AuxiliariesMatrix& auxiliaryMatrix,
0683 const TString& matrixTag, const TVectorF& outerBorders,
0684 const TVectorF& innerBorders,
0685 const TString& fXTitle = "#eta",
0686 const TString& sXTitle = "#phi") -> void {
0687
0688 SummaryHistograms summary;
0689
0690
0691 unsigned int nOuterBins = outerBorders.GetNrows() - 1;
0692 auto outerValues = outerBorders.GetMatrixArray();
0693 unsigned int nInnerBins = innerBorders.GetNrows() - 1;
0694 auto innerValues = innerBorders.GetMatrixArray();
0695
0696 TString statN = TString("entries") + matrixTag;
0697 summary.fillStats =
0698 new TH2F(statN, "", nOuterBins, outerValues, nInnerBins, innerValues);
0699
0700 #ifdef BOOST_AVAILABLE
0701 progress_display analysis_progress(nOuterBins * nInnerBins);
0702 #endif
0703
0704
0705 for (auto& bHandle : baseResidualPulls) {
0706
0707 TString handleTag = TString(bHandle.tag) + matrixTag;
0708
0709 TString residualRMSN = TString("res_rms_") + handleTag;
0710 TString residualMeanN = TString("res_mean_") + handleTag;
0711 TString pullSigmaN = TString("pull_sigma_") + handleTag;
0712 TString pullMeanN = TString("pull_mean_") + handleTag;
0713
0714 TH2F* residualRMS = new TH2F(residualRMSN, "", nOuterBins, outerValues,
0715 nInnerBins, innerValues);
0716 TH2F* residualMean = new TH2F(residualMeanN, "", nOuterBins, outerValues,
0717 nInnerBins, innerValues);
0718 TH2F* pullSigma = new TH2F(pullSigmaN, "", nOuterBins, outerValues,
0719 nInnerBins, innerValues);
0720 TH2F* pullMean = new TH2F(pullMeanN, "", nOuterBins, outerValues,
0721 nInnerBins, innerValues);
0722
0723 summary.residualRMS.push_back(residualRMS);
0724 summary.residualMean.push_back(residualMean);
0725 summary.pullSigma.push_back(pullSigma);
0726 summary.pullMean.push_back(pullMean);
0727 }
0728
0729
0730 for (auto& aHandle : baseAuxilaries) {
0731
0732 TString auxiliaryTag = TString(aHandle.tag) + matrixTag;
0733 TH2F* auxHist = new TH2F(auxiliaryTag, auxiliaryTag, nOuterBins,
0734 outerValues, nInnerBins, innerValues);
0735 summary.auxiliaries.push_back(auxHist);
0736 }
0737
0738 unsigned int io = 0;
0739 for (auto& outerBatch : residualPullsMatrix) {
0740 unsigned int ii = 0;
0741 for (auto& innerBatch : outerBatch) {
0742
0743 unsigned int iresp = 0;
0744 for (auto& bHandle : innerBatch) {
0745
0746 if (bHandle.rangeHist != nullptr) {
0747 bHandle.rangeHist->Write();
0748 }
0749
0750 if (iresp == 0) {
0751 summary.fillStats->SetBinContent(io + 1, ii + 1, bHandle.accepted);
0752 }
0753
0754
0755
0756 float rrms = bHandle.residualHist->GetRMS();
0757 float rrerr = bHandle.residualHist->GetRMSError();
0758 float rmean = bHandle.residualHist->GetMean();
0759 float rmerr = bHandle.residualHist->GetMeanError();
0760 summary.residualRMS[iresp]->SetBinContent(io + 1, ii + 1, rrms);
0761 summary.residualRMS[iresp]->SetBinError(io + 1, ii + 1, rrerr);
0762 summary.residualMean[iresp]->SetBinContent(io + 1, ii + 1, rmean);
0763 summary.residualMean[iresp]->SetBinError(io + 1, ii + 1, rmerr);
0764 bHandle.residualHist->Write();
0765
0766 bHandle.pullHist->Fit("gaus", "q");
0767 TF1* gauss = bHandle.pullHist->GetFunction("gaus");
0768 if (gauss != nullptr) {
0769 float pmu = gauss->GetParameter(1);
0770 float pmerr = gauss->GetParError(1);
0771 float psigma = gauss->GetParameter(2);
0772 float pserr = gauss->GetParError(2);
0773 summary.pullSigma[iresp]->SetBinContent(io + 1, ii + 1, psigma);
0774 summary.pullSigma[iresp]->SetBinError(io + 1, ii + 1, pserr);
0775 summary.pullMean[iresp]->SetBinContent(io + 1, ii + 1, pmu);
0776 summary.pullMean[iresp]->SetBinError(io + 1, ii + 1, pmerr);
0777 }
0778 bHandle.pullHist->Write();
0779 ++iresp;
0780 }
0781
0782
0783 auto auxiliaryBatch = auxiliaryMatrix[io][ii];
0784 unsigned int iaux = 0;
0785 for (auto& aHandle : auxiliaryBatch) {
0786 float value = aHandle.hist->GetMean();
0787 float error = aHandle.hist->GetMeanError();
0788 summary.auxiliaries[iaux]->SetBinContent(io + 1, ii + 1, value);
0789 summary.auxiliaries[iaux]->SetBinError(io + 1, ii + 1, error);
0790 aHandle.hist->Write();
0791
0792 ++iaux;
0793 }
0794 #ifdef BOOST_AVAILABLE
0795 ++analysis_progress;
0796 #endif
0797 ++ii;
0798 }
0799 ++io;
0800 }
0801
0802
0803
0804
0805
0806
0807
0808
0809 auto writeProjections = [](const TH2F& h2, const TString& fXTitleP = "#eta",
0810 const TString& fYTitleP = "sigma",
0811 const TString& sXTitleP = "#phi",
0812 const TString& sYTitleP = "sigma") -> void {
0813 const TString& fTag = "_pX";
0814 const TString& sTag = "_pY";
0815
0816 unsigned int nBinsX = h2.GetXaxis()->GetNbins();
0817 unsigned int nBinsY = h2.GetYaxis()->GetNbins();
0818 if (fTag != "") {
0819 TH1D* pX =
0820 dynamic_cast<TH1D*>(h2.ProjectionX((h2.GetName() + fTag).Data()));
0821 setHistStyle(pX);
0822 if (pX != nullptr) {
0823 pX->GetXaxis()->SetTitle(fXTitleP.Data());
0824 pX->GetYaxis()->SetTitle(fYTitleP.Data());
0825 pX->Write();
0826 }
0827
0828 for (unsigned int iy = 1; iy <= nBinsY; ++iy) {
0829 pX = dynamic_cast<TH1D*>(h2.ProjectionX(
0830 (h2.GetName() + fTag + sTag + (iy - 1)).Data(), iy, iy));
0831 setHistStyle(pX);
0832 if (pX != nullptr) {
0833 pX->GetXaxis()->SetTitle(fXTitleP.Data());
0834 pX->GetYaxis()->SetTitle(fYTitleP.Data());
0835 pX->Write();
0836 }
0837 }
0838 }
0839 if (sTag != "") {
0840 TH1D* pY =
0841 dynamic_cast<TH1D*>(h2.ProjectionY((h2.GetName() + sTag).Data()));
0842 setHistStyle(pY);
0843 if (pY != nullptr) {
0844 pY->GetXaxis()->SetTitle(sXTitleP.Data());
0845 pY->GetYaxis()->SetTitle(sYTitleP.Data());
0846 pY->Write();
0847 }
0848
0849 for (unsigned int ix = 1; ix <= nBinsX; ++ix) {
0850 pY = dynamic_cast<TH1D*>(h2.ProjectionY(
0851 (h2.GetName() + sTag + fTag + (ix - 1)).Data(), ix, ix));
0852 setHistStyle(pY);
0853 if (pY != nullptr) {
0854 pY->GetXaxis()->SetTitle(sXTitleP.Data());
0855 pY->GetYaxis()->SetTitle(sYTitleP.Data());
0856 pY->Write();
0857 }
0858 }
0859 }
0860 };
0861
0862 setHistStyle(summary.fillStats);
0863 summary.fillStats->Write();
0864
0865
0866 for (unsigned int iresp = 0; iresp < baseResidualPulls.size(); ++iresp) {
0867
0868 auto bHandle = baseResidualPulls[iresp];
0869
0870 TString rrms = TString("RMS[") + bHandle.residualStr + TString("] ") +
0871 bHandle.residualUnit;
0872 TString rmu = TString("#mu[") + bHandle.residualStr + TString("] ") +
0873 bHandle.residualUnit;
0874
0875 TString psigma = TString("#sigma[(") + bHandle.residualStr +
0876 TString(")/") + bHandle.errorStr + TString("]");
0877 TString pmu = TString("#mu[(") + bHandle.residualStr + TString(")/") +
0878 bHandle.errorStr + TString("]");
0879
0880
0881 setHistStyle(summary.residualRMS[iresp]);
0882 summary.residualRMS[iresp]->GetXaxis()->SetTitle(fXTitle);
0883 summary.residualRMS[iresp]->GetYaxis()->SetTitle(sXTitle);
0884 summary.residualRMS[iresp]->GetZaxis()->SetTitle(rrms);
0885 summary.residualRMS[iresp]->Write();
0886
0887 setHistStyle(summary.residualMean[iresp]);
0888 summary.residualMean[iresp]->GetXaxis()->SetTitle(fXTitle);
0889 summary.residualMean[iresp]->GetYaxis()->SetTitle(sXTitle);
0890 summary.residualMean[iresp]->GetZaxis()->SetTitle(rmu);
0891 summary.residualMean[iresp]->Write();
0892
0893 setHistStyle(summary.pullSigma[iresp]);
0894 adaptColorPalette(summary.pullSigma[iresp], 0., 4., 1., 0.1, 104);
0895 summary.pullSigma[iresp]->GetXaxis()->SetTitle(fXTitle);
0896 summary.pullSigma[iresp]->GetYaxis()->SetTitle(sXTitle);
0897 summary.pullSigma[iresp]->GetZaxis()->SetRangeUser(0., 4.);
0898 summary.pullSigma[iresp]->GetZaxis()->SetTitle(psigma);
0899 summary.pullSigma[iresp]->Write();
0900
0901 setHistStyle(summary.pullMean[iresp]);
0902 adaptColorPalette(summary.pullMean[iresp], -1., 1., 0., 0.1, 104);
0903 summary.pullMean[iresp]->GetXaxis()->SetTitle(fXTitle);
0904 summary.pullMean[iresp]->GetYaxis()->SetTitle(sXTitle);
0905 summary.pullMean[iresp]->GetZaxis()->SetRangeUser(-1., 1.);
0906 summary.pullMean[iresp]->GetZaxis()->SetTitle(pmu);
0907 summary.pullMean[iresp]->Write();
0908
0909
0910 writeProjections(*summary.residualRMS[iresp], fXTitle, rrms, sXTitle,
0911 rrms);
0912 writeProjections(*summary.residualMean[iresp], fXTitle, rmu, sXTitle,
0913 rmu);
0914 writeProjections(*summary.pullSigma[iresp], fXTitle, psigma, sXTitle,
0915 psigma);
0916 writeProjections(*summary.pullMean[iresp], fXTitle, pmu, sXTitle, pmu);
0917 }
0918
0919
0920 for (unsigned int iaux = 0; iaux < baseAuxilaries.size(); ++iaux) {
0921 setHistStyle(summary.auxiliaries[iaux]);
0922 summary.auxiliaries[iaux]->GetXaxis()->SetTitle(fXTitle);
0923 summary.auxiliaries[iaux]->GetYaxis()->SetTitle(sXTitle);
0924 summary.auxiliaries[iaux]->GetZaxis()->SetTitle(
0925 baseAuxilaries[iaux].label.c_str());
0926 summary.auxiliaries[iaux]->Write();
0927
0928 writeProjections(*summary.auxiliaries[iaux], fXTitle,
0929 baseAuxilaries[iaux].label, sXTitle,
0930 baseAuxilaries[iaux].label);
0931 }
0932
0933 return;
0934 };
0935
0936
0937 #ifdef BOOST_AVAILABLE
0938 std::cout << "*** Bin/Projection Analysis: " << std::endl;
0939 #endif
0940 analyseBins(etaPtResidualPulls, etaPtAuxiliaries, TString("_eta_pt"), etaVals,
0941 ptVals, "#eta", "p_{T} [GeV]");
0942 analyseBins(etaPhiResidualPulls, etaPhiAuxiliaries, TString("_eta_phi"),
0943 etaVals, phiVals, "#eta", "#phi");
0944
0945 output->Close();
0946
0947 return 1;
0948 }