File indexing completed on 2025-03-23 23:39:49
0001 #include <ROOT/RDataFrame.hxx>
0002 #include <ROOT/RVec.hxx>
0003 #include <TCanvas.h>
0004 #include <TF1.h>
0005 #include <TFile.h>
0006 #include <TH1D.h>
0007 #include <TH1F.h>
0008 #include <TH2F.h>
0009 #include <TLorentzVector.h>
0010 #include <TMath.h>
0011 #include <TProfile.h>
0012 #include <TRegexp.h>
0013 #include <TStopwatch.h>
0014 #include <TString.h>
0015 #include <TTree.h>
0016 #include <algorithm>
0017 #include <cmath>
0018 #include <iomanip> // Include the header for setw
0019 #include <iostream>
0020 #include <map>
0021 #include <string>
0022
0023
0024 enum anaKind { sagitta_t = 0, d0_t = 1, dz_t = 2 };
0025
0026
0027 unsigned int k_NBINS = 48;
0028
0029
0030 int k_MAXITERATIONS = 30;
0031
0032 static constexpr const char* const analysis_types[] = {
0033 "sagitta",
0034 "d0",
0035 "dz",
0036 };
0037
0038
0039 static constexpr double k_muMass = 0.105658;
0040 static constexpr double MZ_PDG = 91.1876;
0041
0042
0043
0044 double pTcorrector(const double& unCorrPt, const double& delta, const float& charge) {
0045 return unCorrPt / (1 - charge * delta * unCorrPt);
0046 }
0047
0048
0049 float calcDeltaSagitta(float charge, float frac, float avgSagitta, float thisTrackPt) {
0050 return (-charge * 0.5 * frac * ((1 + charge * thisTrackPt * avgSagitta) / thisTrackPt));
0051 }
0052
0053
0054 std::pair<int, int> findEtaPhiBin(const TH2* h2, const float& eta, const float& phi) {
0055 const auto& etaBin = h2->GetXaxis()->FindBin(eta) - 1;
0056 const auto& phiBin = h2->GetYaxis()->FindBin(phi) - 1;
0057
0058 if (etaBin < 0 || etaBin > int(k_NBINS - 1)) {
0059 std::cout << "etaBin: " << etaBin << " eta: " << eta << std::endl;
0060 return {-1., -1.};
0061 }
0062
0063 if (phiBin < 0 || phiBin > int(k_NBINS - 1)) {
0064 std::cout << "phiBin: " << phiBin << " phi: " << phi << std::endl;
0065 return {-1., -1.};
0066 }
0067 return std::make_pair(etaBin, phiBin);
0068 }
0069
0070
0071 float updateSagittaMap(TTree* tree,
0072 std::map<std::pair<int, int>, float>& theMap,
0073 TH2F*& hSagitta,
0074 const int iteration,
0075 float oldMaxCorrection);
0076
0077
0078 float updateSagittaMapFast(TTree* tree,
0079 std::map<std::pair<int, int>, float>& theMap,
0080 TH2F*& hSagitta,
0081 const int iteration,
0082 float oldMaxCorrection);
0083
0084
0085 float updateIPMap(
0086 TTree* tree, std::map<std::pair<int, int>, float>& theMap, TH2F*& hIP, const int iteration, anaKind type);
0087
0088
0089 float updateIPMapFast(
0090 TTree* tree, std::map<std::pair<int, int>, float>& theMap, TH2F*& hIP, const int iteration, anaKind type);
0091
0092
0093 enum TitleFormatType { MEAN, RMS };
0094
0095
0096 TString updateTitle(const TString& title, TitleFormatType formatType) {
0097
0098 TRegexp re("\\[.*\\]");
0099 TString units;
0100 TString cleanTitle = title;
0101
0102
0103 if (cleanTitle.Index(re) != kNPOS) {
0104 units = cleanTitle(re);
0105 cleanTitle(re) = "";
0106 cleanTitle = cleanTitle.Strip(TString::kBoth);
0107 }
0108
0109
0110 TString newTitle;
0111 switch (formatType) {
0112 case MEAN:
0113 if (!units.IsNull()) {
0114 newTitle = TString::Format("#LT%s#GT %s", cleanTitle.Data(), units.Data());
0115 } else {
0116 newTitle = TString::Format("#LT%s#GT", cleanTitle.Data());
0117 }
0118 break;
0119 case RMS:
0120 if (!units.IsNull()) {
0121 newTitle = TString::Format("RMS (%s) %s", cleanTitle.Data(), units.Data());
0122 } else {
0123 newTitle = TString::Format("RMS (%s)", cleanTitle.Data());
0124 }
0125 break;
0126 }
0127
0128
0129 return newTitle;
0130 }
0131
0132
0133 std::pair<TH1F*, TH1F*> makeProfileVsEta(TH2F* h2) {
0134 const auto& nBinsX = h2->GetNbinsX();
0135 const auto& nBinsY = h2->GetNbinsY();
0136
0137 float xmin = h2->GetXaxis()->GetXmin();
0138 float xmax = h2->GetXaxis()->GetXmax();
0139
0140 std::vector<float> average;
0141 std::vector<float> RMS;
0142 std::vector<float> errorOnRMS;
0143
0144 for (int i = 1; i <= nBinsX; i++) {
0145 float avgInY{0.};
0146 for (int j = 1; j <= nBinsY; j++) {
0147 avgInY += h2->GetBinContent(i, j);
0148 }
0149 avgInY /= nBinsY;
0150 average.push_back(avgInY);
0151 }
0152
0153 for (int i = 1; i <= nBinsX; i++) {
0154 float RMSInY{0.};
0155 for (int j = 1; j <= nBinsY; j++) {
0156 RMSInY += std::pow((h2->GetBinContent(i, j) - average[i - 1]), 2);
0157 }
0158 RMSInY /= nBinsY;
0159 RMS.push_back(std::sqrt(RMSInY));
0160 }
0161
0162 TH1F* h_prof = new TH1F("avgInEta", "profile vs #eta", nBinsX, xmin, xmax);
0163 h_prof->GetXaxis()->SetTitle(h2->GetXaxis()->GetTitle());
0164 h_prof->GetYaxis()->SetTitle(updateTitle(h2->GetZaxis()->GetTitle(), TitleFormatType::MEAN));
0165 for (int i = 1; i <= nBinsX; i++) {
0166 std::cout << i << " = " << average[i - 1] << std::endl;
0167 h_prof->SetBinContent(i, average[i - 1]);
0168 h_prof->SetBinError(i, RMS[i - 1] / nBinsY);
0169 }
0170
0171 TH1F* h_RMS = new TH1F("RMSInEta", "RMS vs #eta", nBinsX, xmin, xmax);
0172 h_RMS->GetXaxis()->SetTitle(h2->GetXaxis()->GetTitle());
0173 h_RMS->GetYaxis()->SetTitle(updateTitle(h2->GetZaxis()->GetTitle(), TitleFormatType::RMS));
0174 for (int i = 1; i <= nBinsX; i++) {
0175 std::cout << i << " = " << average[i - 1] << std::endl;
0176 h_RMS->SetBinContent(i, RMS[i - 1]);
0177 h_RMS->SetBinError(i, RMS[i - 1] / std::sqrt(2 * (nBinsY - 1)));
0178 }
0179
0180 return std::make_pair(h_prof, h_RMS);
0181 }
0182
0183
0184 std::pair<TH1F*, TH1F*> makeProfileVsPhi(TH2F* h2) {
0185 const auto& nBinsX = h2->GetNbinsX();
0186 const auto& nBinsY = h2->GetNbinsY();
0187
0188 float ymin = h2->GetYaxis()->GetXmin();
0189 float ymax = h2->GetYaxis()->GetXmax();
0190
0191 std::vector<float> average;
0192 std::vector<float> RMS;
0193
0194 for (int j = 1; j <= nBinsY; j++) {
0195 float avgInX{0.};
0196 for (int i = 1; i <= nBinsX; i++) {
0197 avgInX += h2->GetBinContent(i, j);
0198 }
0199 avgInX /= nBinsX;
0200 average.push_back(avgInX);
0201 }
0202
0203 for (int j = 1; j <= nBinsY; j++) {
0204 float RMSInX{0.};
0205 for (int i = 1; i <= nBinsX; i++) {
0206 RMSInX += std::pow((h2->GetBinContent(i, j) - average[j - 1]), 2);
0207 }
0208 RMSInX /= nBinsX;
0209 RMS.push_back(std::sqrt(RMSInX));
0210 }
0211
0212 TH1F* h_prof = new TH1F("avgInPhi", "profile vs #phi", nBinsY, ymin, ymax);
0213 h_prof->GetXaxis()->SetTitle(h2->GetYaxis()->GetTitle());
0214 h_prof->GetYaxis()->SetTitle(updateTitle(h2->GetZaxis()->GetTitle(), TitleFormatType::MEAN));
0215 for (int i = 1; i <= nBinsY; i++) {
0216 std::cout << i << " = " << average[i - 1] << std::endl;
0217 h_prof->SetBinContent(i, average[i - 1]);
0218 h_prof->SetBinError(i, RMS[i - 1] / nBinsX);
0219 }
0220
0221 TH1F* h_RMS = new TH1F("RMSInPhi", "RMS vs #phi", nBinsY, ymin, ymax);
0222 h_RMS->GetXaxis()->SetTitle(h2->GetYaxis()->GetTitle());
0223 h_RMS->GetYaxis()->SetTitle(updateTitle(h2->GetZaxis()->GetTitle(), TitleFormatType::RMS));
0224 for (int i = 1; i <= nBinsY; i++) {
0225 std::cout << i << " = " << average[i - 1] << std::endl;
0226 h_RMS->SetBinContent(i, RMS[i - 1]);
0227 h_RMS->SetBinError(i, RMS[i - 1] / std::sqrt(2 * (nBinsX - 1)));
0228 }
0229
0230 return std::make_pair(h_prof, h_RMS);
0231 }
0232
0233
0234 void analyzeDiMuonBiases_fast(const char* inputFile, anaKind type) {
0235 TStopwatch timer;
0236 timer.Start();
0237
0238 std::cout << "I AM GOING TO PERFORM THE " << analysis_types[type] << " analysis!" << std::endl;
0239
0240 ROOT::EnableImplicitMT();
0241
0242 TFile* file = TFile::Open(inputFile);
0243
0244 TTree* tree = dynamic_cast<TTree*>(file->Get("ZtoMMNtuple/tree"));
0245
0246 if (tree) {
0247 tree->ls();
0248 } else {
0249 std::cout << "could not open the input tree from file.\n exiting";
0250 exit(EXIT_FAILURE);
0251 }
0252
0253 std::string outputString(inputFile);
0254 std::string oldSubstring = "ZmmNtuple_";
0255 std::string newSubstring = "histos_";
0256 outputString.replace(outputString.find(oldSubstring), oldSubstring.length(), newSubstring);
0257 std::size_t pos = outputString.find(".root");
0258
0259
0260 TString toInject = TString::Format("__%s", analysis_types[type]);
0261 if (pos != std::string::npos) {
0262 outputString.insert(pos, toInject.Data());
0263 }
0264
0265
0266
0267 TFile* outputFile = TFile::Open(outputString.c_str(), "RECREATE");
0268 TH1F* hMass = new TH1F("hMass", "mass;m_{#mu#mu} [GeV];events", 80, 70., 110.);
0269 TH1F* hPt = new TH1F("hPt", ";muon p_{T} [GeV];events", 100, 0., 200.);
0270 TH1F* hZPt = new TH1F("hZPt", ";di-muon system p_{T} [GeV];events", 100, 0., 200.);
0271
0272 TH1F* hPtPlus = new TH1F("hPtPlus", ";positive muon p_{T} [GeV];events", 100, 0., 200.);
0273 TH1F* hPtMinus = new TH1F("hPtMinus", ";negative muon p_{T} [GeV];events", 100, 0., 200.);
0274
0275 TH1F* hPtCorr = new TH1F("hPtCorr", ";corrected muon p_{T} [GeV];events", 100, 0., 200.);
0276 TH1F* hPtPlusCorr = new TH1F("hPtPlusCorr", ";corrected positive muon p_{T} [GeV];events", 100, 0., 200.);
0277 TH1F* hPtMinusCorr = new TH1F("hPtMinusCorr", ";corrected negative muon p_{T} [GeV];events", 100, 0., 200.);
0278
0279 TH1F* hMassCorr = new TH1F("hMassCorr", "corrected mass;corrected m_{#mu#mu} [GeV];events", 80, 70., 110.);
0280 TH1F* hDeltaMassCorr = new TH1F(
0281 "hDeltaMassCorr",
0282 "#Delta Mass (corrected - corrected) ;#Delta m_{#mu#mu} (m^{corr}_{#mu#mu} - m^{uncorr}_{#mu#mu}) [GeV];events",
0283 100,
0284 -10.,
0285 10.);
0286 TH1F* hDeltaPtCorr =
0287 new TH1F("hDeltaPtCorr", "#Delta p_{T};#Delta p_{T} (p^{corr}_{T}-p^{uncorr}_{T}) [GeV];events", 100, -10., 10.);
0288
0289 TH1F* hEta = new TH1F("hEta", ";muon #eta;events", 100, -3.0, 3.0);
0290
0291 TH1F* hDeltaD0 = new TH1F("hDeltaD0", ";#Deltad_{0} [cm];events", 100, -0.01, 0.01);
0292 TH1F* hDeltaDz = new TH1F("hDeltaDz", ";#Deltad_{z} [cm];events", 100, -0.1, 0.1);
0293
0294 TH1F* hPhi = new TH1F("hPhi", ";muon #phi;events", 100, -TMath::Pi(), TMath::Pi());
0295 TH1F* hCorrection = new TH1F(
0296 "hCorrection",
0297 TString::Format("largest correction vs iteration;iteration number; #delta_{%s} correction ", analysis_types[type])
0298 .Data(),
0299 k_MAXITERATIONS,
0300 0.,
0301 k_MAXITERATIONS);
0302
0303 TH2F* hSagitta = new TH2F("hSagitta",
0304 "#delta_{sagitta};muon #eta;muon #phi;#delta_{sagitta} [TeV^{-1}]",
0305 k_NBINS,
0306 -2.5,
0307 2.5,
0308 k_NBINS,
0309 -TMath::Pi(),
0310 TMath::Pi());
0311
0312 const char* IPtype = (type == anaKind::d0_t) ? "d_{0}" : "d_{z}";
0313 TH2F* hIP = new TH2F("hIP",
0314 TString::Format("#delta_{%s};muon #eta;muon #phi;#delta_{%s} [#mum]", IPtype, IPtype).Data(),
0315 k_NBINS,
0316 -2.47,
0317 2.47,
0318 k_NBINS,
0319 -TMath::Pi(),
0320 TMath::Pi());
0321
0322 std::map<std::pair<int, int>, float> sagittaCorrections;
0323 std::map<std::pair<int, int>, float> IPCorrections;
0324
0325
0326
0327 for (unsigned int i = 0; i < k_NBINS; i++) {
0328 for (unsigned int j = 0; j < k_NBINS; j++) {
0329 const auto& index = std::make_pair(i, j);
0330
0331 sagittaCorrections[index] = 0.f;
0332 IPCorrections[index] = 0.f;
0333 }
0334 }
0335
0336 float maxCorrection{1.f};
0337 int iteration = 0;
0338 float threshold = (type == sagitta_t) ? 1e-10 : 1e-10;
0339
0340 while ((std::abs(maxCorrection) > threshold) && iteration < k_MAXITERATIONS) {
0341 float oldMaxCorrection = maxCorrection;
0342 if (type == sagitta_t) {
0343 maxCorrection = updateSagittaMapFast(tree, sagittaCorrections, hSagitta, iteration, oldMaxCorrection);
0344 } else {
0345 maxCorrection = updateIPMapFast(tree, IPCorrections, hIP, iteration, type);
0346 }
0347
0348 std::cout << "iteration: " << iteration << " maxCorrection: " << maxCorrection << std::endl;
0349 hCorrection->SetBinContent(iteration, maxCorrection);
0350 iteration++;
0351 }
0352
0353 Float_t posTrackEta, negTrackEta, posTrackPhi, negTrackPhi, posTrackPt, negTrackPt;
0354 Float_t posTrackDz, negTrackDz, posTrackD0, negTrackD0;
0355
0356 tree->SetBranchAddress("posTrackEta", &posTrackEta);
0357 tree->SetBranchAddress("negTrackEta", &negTrackEta);
0358 tree->SetBranchAddress("posTrackPhi", &posTrackPhi);
0359 tree->SetBranchAddress("negTrackPhi", &negTrackPhi);
0360 tree->SetBranchAddress("posTrackPt", &posTrackPt);
0361 tree->SetBranchAddress("negTrackPt", &negTrackPt);
0362 tree->SetBranchAddress("posTrackDz", &posTrackDz);
0363 tree->SetBranchAddress("negTrackDz", &negTrackDz);
0364 tree->SetBranchAddress("posTrackD0", &posTrackD0);
0365 tree->SetBranchAddress("negTrackD0", &negTrackD0);
0366
0367 Float_t invMass;
0368
0369
0370 for (Long64_t i = 0; i < tree->GetEntries(); i++) {
0371 tree->GetEntry(i);
0372
0373 TLorentzVector posTrack, negTrack, mother;
0374 posTrack.SetPtEtaPhiM(posTrackPt, posTrackEta, posTrackPhi, k_muMass);
0375 negTrack.SetPtEtaPhiM(negTrackPt, negTrackEta, negTrackPhi, k_muMass);
0376 mother = posTrack + negTrack;
0377
0378 hDeltaD0->Fill(posTrackD0 - negTrackD0);
0379 hDeltaDz->Fill(posTrackDz - negTrackDz);
0380
0381 hPt->Fill(posTrackPt);
0382 hPt->Fill(negTrackPt);
0383
0384 hPtPlus->Fill(posTrackPt);
0385 hPtMinus->Fill(negTrackPt);
0386
0387 hEta->Fill(posTrackEta);
0388 hEta->Fill(negTrackEta);
0389
0390 hPhi->Fill(posTrackPhi);
0391 hPhi->Fill(negTrackPhi);
0392
0393 invMass = mother.M();
0394 hMass->Fill(invMass);
0395 hZPt->Fill(mother.Pt());
0396
0397 const auto& indexPlus = findEtaPhiBin(hSagitta, posTrackEta, posTrackPhi);
0398 float deltaPlus = sagittaCorrections[indexPlus];
0399
0400 const auto& indexMinus = findEtaPhiBin(hSagitta, negTrackEta, negTrackPhi);
0401 float deltaMinus = sagittaCorrections[indexMinus];
0402
0403 TLorentzVector posTrackCorr, negTrackCorr, motherCorr;
0404
0405
0406
0407 posTrackCorr.SetPtEtaPhiM(
0408 pTcorrector(posTrackPt, deltaPlus, 1.), posTrackEta, posTrackPhi, k_muMass);
0409 negTrackCorr.SetPtEtaPhiM(pTcorrector(negTrackPt, deltaMinus, -1.), negTrackEta, negTrackPhi, k_muMass);
0410
0411 hPtPlusCorr->Fill(posTrackCorr.Pt());
0412 hPtMinusCorr->Fill(negTrackCorr.Pt());
0413
0414 hDeltaPtCorr->Fill(posTrackCorr.Pt() - posTrackPt);
0415 hDeltaPtCorr->Fill(negTrackCorr.Pt() - negTrackPt);
0416
0417
0418
0419
0420 motherCorr = posTrackCorr + negTrackCorr;
0421
0422 hMassCorr->Fill(motherCorr.M());
0423 hDeltaMassCorr->Fill(mother.M() - motherCorr.M());
0424 hPtCorr->Fill(posTrackCorr.Pt());
0425 hPtCorr->Fill(negTrackCorr.Pt());
0426 }
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 for (unsigned int i = 0; i < k_NBINS; i++) {
0437 for (unsigned int j = 0; j < k_NBINS; j++) {
0438 const auto& index = std::make_pair(i, j);
0439 if (type == sagitta_t) {
0440 hSagitta->SetBinContent(i + 1, j + 1, sagittaCorrections[index] * 10e3);
0441 } else {
0442 hIP->SetBinContent(i + 1, j + 1, IPCorrections[index] * 10e4);
0443 }
0444 }
0445 }
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462 std::pair<TH1F*, TH1F*> momVsEta = std::make_pair(nullptr, nullptr);
0463 std::pair<TH1F*, TH1F*> momVsPhi = std::make_pair(nullptr, nullptr);
0464 if (type == sagitta_t) {
0465 momVsEta = makeProfileVsEta(hSagitta);
0466 momVsPhi = makeProfileVsPhi(hSagitta);
0467 } else {
0468 momVsEta = makeProfileVsEta(hIP);
0469 momVsPhi = makeProfileVsPhi(hIP);
0470 }
0471
0472 hDeltaD0->Write();
0473 hDeltaDz->Write();
0474
0475 hMass->Write();
0476 hPt->Write();
0477 hPtPlus->Write();
0478 hPtMinus->Write();
0479
0480 hZPt->Write();
0481
0482 hEta->Write();
0483 hPhi->Write();
0484
0485 if (type == sagitta_t) {
0486 hMassCorr->Write();
0487 hPtCorr->Write();
0488 hPtPlusCorr->Write();
0489 hPtMinusCorr->Write();
0490 hDeltaMassCorr->Write();
0491 hDeltaPtCorr->Write();
0492 }
0493
0494 hCorrection->Write();
0495 if (type == sagitta_t) {
0496 hSagitta->SetOption("colz");
0497 hSagitta->Write();
0498 } else {
0499 hIP->SetOption("colz");
0500 hIP->Write();
0501 }
0502
0503 momVsEta.first->Write();
0504 momVsPhi.first->Write();
0505 momVsEta.second->Write();
0506 momVsPhi.second->Write();
0507
0508
0509
0510
0511
0512
0513 outputFile->Close();
0514 file->Close();
0515
0516 timer.Stop();
0517 timer.Print();
0518 }
0519
0520
0521 float fitResiduals(TH1* histogram) {
0522 TF1* gaussianFunc = new TF1("gaussianFunc", "gaus", 0, 100);
0523
0524 histogram->Fit(gaussianFunc, "Q");
0525
0526 double prevMean = gaussianFunc->GetParameter(1);
0527 double prevSigma = gaussianFunc->GetParameter(2);
0528
0529 int maxIterations = 10;
0530 double tolerance = 0.001;
0531
0532 for (int iteration = 0; iteration < maxIterations; ++iteration) {
0533
0534 double lowerLimit = prevMean - 1.5 * prevSigma;
0535 double upperLimit = prevMean + 1.5 * prevSigma;
0536 gaussianFunc->SetRange(lowerLimit, upperLimit);
0537
0538
0539 histogram->Fit(gaussianFunc, "Q");
0540
0541
0542 double currentMean = gaussianFunc->GetParameter(1);
0543 double currentSigma = gaussianFunc->GetParameter(2);
0544
0545
0546 if (abs(currentMean - prevMean) < tolerance && abs(currentSigma - prevSigma) < tolerance) {
0547
0548 break;
0549 }
0550
0551 prevMean = currentMean;
0552 prevSigma = currentSigma;
0553 }
0554
0555 return prevMean;
0556 }
0557
0558
0559 float updateSagittaMap(TTree* tree,
0560 std::map<std::pair<int, int>, float>& theMap,
0561 TH2F*& hSagitta,
0562 const int iteration,
0563 float oldMaxCorrection) {
0564 std::cout << "calling the updateSagittaMap" << std::endl;
0565
0566 std::map<std::pair<int, int>, float> deltaCorrection;
0567
0568 std::map<std::pair<int, int>, float> countsPerBin;
0569
0570 std::map<std::pair<int, int>, TH1F*> deltaInBin;
0571
0572
0573 float maxRange = 0.01;
0574
0575 for (unsigned int i = 0; i < k_NBINS; i++) {
0576 for (unsigned int j = 0; j < k_NBINS; j++) {
0577 const auto& index = std::make_pair(i, j);
0578 deltaCorrection[index] = 0.f;
0579 countsPerBin[index] = 0.f;
0580 deltaInBin[index] = new TH1F(
0581 Form("delta_iter_%i_%i_%i", iteration, i, j),
0582 Form("iteration %i : #delta_%i_%i;estimated #delta_{s} -true #delta_{s} [GeV^{-1}];n.muons", iteration, i, j),
0583 100,
0584 -maxRange,
0585 maxRange);
0586
0587 }
0588 }
0589
0590 Float_t posTrackEta, negTrackEta, posTrackPhi, negTrackPhi, posTrackPt, negTrackPt, invMass;
0591 Float_t genPosMuonEta, genNegMuonEta, genPosMuonPhi, genNegMuonPhi, genPosMuonPt, genNegMuonPt;
0592
0593 tree->SetBranchAddress("posTrackEta", &posTrackEta);
0594 tree->SetBranchAddress("negTrackEta", &negTrackEta);
0595 tree->SetBranchAddress("posTrackPhi", &posTrackPhi);
0596 tree->SetBranchAddress("negTrackPhi", &negTrackPhi);
0597 tree->SetBranchAddress("posTrackPt", &posTrackPt);
0598 tree->SetBranchAddress("negTrackPt", &negTrackPt);
0599
0600
0601 tree->SetBranchAddress("genPosMuonEta", &genPosMuonEta);
0602 tree->SetBranchAddress("genNegMuonEta", &genNegMuonEta);
0603 tree->SetBranchAddress("genPosMuonPhi", &genPosMuonPhi);
0604 tree->SetBranchAddress("genNegMuonPhi", &genNegMuonPhi);
0605 tree->SetBranchAddress("genPosMuonPt", &genPosMuonPt);
0606 tree->SetBranchAddress("genNegMuonPt", &genNegMuonPt);
0607
0608 for (Long64_t i = 0; i < tree->GetEntries(); i++) {
0609 tree->GetEntry(i);
0610 TLorentzVector posTrack, negTrack, mother;
0611 posTrack.SetPtEtaPhiM(posTrackPt, posTrackEta, posTrackPhi, k_muMass);
0612 negTrack.SetPtEtaPhiM(negTrackPt, negTrackEta, negTrackPhi, k_muMass);
0613 mother = posTrack + negTrack;
0614 invMass = mother.M();
0615
0616
0617
0618
0619 const auto& indexPlus = findEtaPhiBin(hSagitta, posTrackEta, posTrackPhi);
0620 float deltaSagittaPlus = theMap[indexPlus];
0621
0622
0623 const auto& indexMinus = findEtaPhiBin(hSagitta, negTrackEta, negTrackPhi);
0624 float deltaSagittaMinus = theMap[indexMinus];
0625
0626 if (indexPlus == std::make_pair(-1, -1) || indexMinus == std::make_pair(-1, -1)) {
0627 continue;
0628 }
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642
0643
0644
0645 float frac;
0646 if (iteration != 0) {
0647 frac = (posTrackPt * deltaSagittaPlus - negTrackPt * deltaSagittaMinus);
0648 } else {
0649 frac = (invMass - MZ_PDG) / MZ_PDG;
0650 }
0651
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661 float deltaDeltaSagittaPlus = calcDeltaSagitta(1., frac, deltaSagittaPlus, posTrackPt);
0662 float deltaDeltaSagittaMinus = calcDeltaSagitta(-1., frac, deltaSagittaMinus, negTrackPt);
0663
0664
0665 double trueDeltaSagittaPlus = (genPosMuonPt - posTrackPt) / (genPosMuonPt * posTrackPt);
0666 double trueDeltaSagittaMinus = (negTrackPt - genNegMuonPt) / (genNegMuonPt * negTrackPt);
0667
0668
0669
0670
0671
0672 deltaCorrection[indexPlus] += deltaDeltaSagittaPlus;
0673 deltaCorrection[indexMinus] += deltaDeltaSagittaMinus;
0674
0675 deltaInBin[indexPlus]->Fill((deltaSagittaPlus + deltaDeltaSagittaPlus) - trueDeltaSagittaPlus);
0676 deltaInBin[indexMinus]->Fill((deltaSagittaMinus + deltaDeltaSagittaMinus) - trueDeltaSagittaMinus);
0677
0678 countsPerBin[indexPlus] += 1.;
0679 countsPerBin[indexMinus] += 1.;
0680 }
0681
0682
0683
0684 for (unsigned int i = 0; i < k_NBINS; i++) {
0685 for (unsigned int j = 0; j < k_NBINS; j++) {
0686 const auto& index = std::make_pair(i, j);
0687
0688 deltaCorrection[index] /= countsPerBin[index];
0689
0690 deltaInBin[index]->Write();
0691
0692 }
0693 }
0694
0695
0696
0697 std::cout << " ================================ iteration: " << iteration << std::endl;
0698 for (unsigned int i = 0; i < k_NBINS; i++) {
0699 for (unsigned int j = 0; j < k_NBINS; j++) {
0700 const auto& index = std::make_pair(i, j);
0701
0702
0703 theMap[index] += deltaCorrection[index];
0704 }
0705 }
0706
0707
0708 auto maxIter = std::max_element(deltaCorrection.begin(), deltaCorrection.end(), [](const auto& a, const auto& b) {
0709 return std::abs(a.second) < std::abs(b.second);
0710 });
0711
0712 return maxIter->second;
0713 }
0714
0715 float updateSagittaMapFast(TTree* tree,
0716 std::map<std::pair<int, int>, float>& theMap,
0717 TH2F*& hSagitta,
0718 const int iteration,
0719 float oldMaxCorrection) {
0720 std::cout << "Calling updateSagittaMap with RDataFrame" << std::endl;
0721
0722 ROOT::RDataFrame df(*tree);
0723
0724
0725 std::map<std::pair<int, int>, float> deltaCorrection;
0726 std::map<std::pair<int, int>, float> countsPerBin;
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748 const double mZfromPDG = 91.1876;
0749
0750
0751 auto df2 =
0752 df.Define("posTrack",
0753 [](float pt, float eta, float phi) -> TLorentzVector {
0754 TLorentzVector v;
0755 v.SetPtEtaPhiM(pt, eta, phi, k_muMass);
0756 return v;
0757 },
0758 {"posTrackPt", "posTrackEta", "posTrackPhi"})
0759 .Define("negTrack",
0760 [](float pt, float eta, float phi) -> TLorentzVector {
0761 TLorentzVector v;
0762 v.SetPtEtaPhiM(pt, eta, phi, k_muMass);
0763 return v;
0764 },
0765 {"negTrackPt", "negTrackEta", "negTrackPhi"})
0766 .Define("mother",
0767 [](const TLorentzVector& posTrack, const TLorentzVector& negTrack) -> TLorentzVector {
0768 return posTrack + negTrack;
0769 },
0770 {"posTrack", "negTrack"})
0771 .Define("invMass", [](const TLorentzVector& mother) -> float { return mother.M(); }, {"mother"})
0772 .Define("indexPlus",
0773 [hSagitta](float eta, float phi) -> std::pair<int, int> { return findEtaPhiBin(hSagitta, eta, phi); },
0774 {"posTrackEta", "posTrackPhi"})
0775 .Define("indexMinus",
0776 [hSagitta](float eta, float phi) -> std::pair<int, int> { return findEtaPhiBin(hSagitta, eta, phi); },
0777 {"negTrackEta", "negTrackPhi"})
0778 .Define("deltaSagittaPlus",
0779 [&theMap](const std::pair<int, int>& index) -> float { return theMap.at(index); },
0780 {"indexPlus"})
0781 .Define("deltaSagittaMinus",
0782 [&theMap](const std::pair<int, int>& index) -> float { return theMap.at(index); },
0783 {"indexMinus"});
0784
0785 auto df3 = df2.Filter(
0786 [](const std::pair<int, int>& indexPlus, const std::pair<int, int>& indexMinus) {
0787 return indexPlus != std::make_pair(-1, -1) && indexMinus != std::make_pair(-1, -1);
0788 },
0789 {"indexPlus", "indexMinus"})
0790 .Define("frac",
0791 [iteration, mZfromPDG](float invMass,
0792 float posTrackPt,
0793 float deltaSagittaPlus,
0794 float negTrackPt,
0795 float deltaSagittaMinus) -> float {
0796 return (iteration != 0) ? (posTrackPt * deltaSagittaPlus - negTrackPt * deltaSagittaMinus)
0797 : (invMass - mZfromPDG) / mZfromPDG;
0798 },
0799 {"invMass", "posTrackPt", "deltaSagittaPlus", "negTrackPt", "deltaSagittaMinus"})
0800 .Define("deltaDeltaSagittaPlus",
0801 [](float frac, float deltaSagittaPlus, float posTrackPt) -> float {
0802 return calcDeltaSagitta(1.f, frac, deltaSagittaPlus, posTrackPt);
0803 },
0804 {"frac", "deltaSagittaPlus", "posTrackPt"})
0805 .Define("deltaDeltaSagittaMinus",
0806 [](float frac, float deltaSagittaMinus, float negTrackPt) -> float {
0807 return calcDeltaSagitta(-1.f, frac, deltaSagittaMinus, negTrackPt);
0808 },
0809 {"frac", "deltaSagittaMinus", "negTrackPt"});
0810
0811
0812
0813
0814
0815
0816
0817
0818 df3.Foreach(
0819 [&](const std::pair<int, int>& indexPlus,
0820 float deltaDeltaSagittaPlus,
0821 float deltaSagittaPlus,
0822 const std::pair<int, int>& indexMinus,
0823 float deltaDeltaSagittaMinus,
0824 float deltaSagittaMinus) {
0825 #pragma omp critical
0826 {
0827 deltaCorrection[indexPlus] += deltaDeltaSagittaPlus;
0828 deltaCorrection[indexMinus] += deltaDeltaSagittaMinus;
0829
0830
0831 countsPerBin[indexPlus] += 1.f;
0832 countsPerBin[indexMinus] += 1.f;
0833 }
0834 },
0835 {"indexPlus",
0836 "deltaDeltaSagittaPlus",
0837 "deltaSagittaPlus",
0838 "indexMinus",
0839 "deltaDeltaSagittaMinus",
0840 "deltaSagittaMinus"});
0841
0842
0843 for (unsigned int i = 0; i < k_NBINS; i++) {
0844 for (unsigned int j = 0; j < k_NBINS; j++) {
0845 const auto& index = std::make_pair(i, j);
0846 deltaCorrection[index] /= countsPerBin[index];
0847
0848 }
0849 }
0850
0851 std::cout << " ================================ iteration: " << iteration << std::endl;
0852 for (unsigned int i = 0; i < k_NBINS; i++) {
0853 for (unsigned int j = 0; j < k_NBINS; j++) {
0854 const auto& index = std::make_pair(i, j);
0855 theMap[index] += deltaCorrection[index];
0856 }
0857 }
0858
0859
0860 auto maxIter = std::max_element(deltaCorrection.begin(), deltaCorrection.end(), [](const auto& a, const auto& b) {
0861 return std::abs(a.second) < std::abs(b.second);
0862 });
0863
0864 return maxIter->second;
0865 }
0866
0867
0868 float updateIPMap(
0869 TTree* tree, std::map<std::pair<int, int>, float>& theMap, TH2F*& hIP, const int iteration, anaKind type) {
0870 std::cout << "calling the updateIPMap" << std::endl;
0871
0872 std::map<std::pair<int, int>, float> deltaCorrection;
0873
0874 std::map<std::pair<int, int>, float> countsPerBin;
0875
0876
0877 for (unsigned int i = 0; i < k_NBINS; i++) {
0878 for (unsigned int j = 0; j < k_NBINS; j++) {
0879 const auto& index = std::make_pair(i, j);
0880 deltaCorrection[index] = 0.f;
0881 countsPerBin[index] = 0.f;
0882 }
0883 }
0884
0885 float posTrackEta, negTrackEta, posTrackPhi, negTrackPhi, posTrackIP, negTrackIP, invMass;
0886 tree->SetBranchAddress("posTrackEta", &posTrackEta);
0887 tree->SetBranchAddress("negTrackEta", &negTrackEta);
0888 tree->SetBranchAddress("posTrackPhi", &posTrackPhi);
0889 tree->SetBranchAddress("negTrackPhi", &negTrackPhi);
0890 if (type == d0_t) {
0891 tree->SetBranchAddress("posTrackD0", &posTrackIP);
0892 tree->SetBranchAddress("negTrackD0", &negTrackIP);
0893 } else if (type == dz_t) {
0894 tree->SetBranchAddress("posTrackDz", &posTrackIP);
0895 tree->SetBranchAddress("negTrackDz", &negTrackIP);
0896 } else {
0897 std::cout << "error, you have been calling this script with the wrong settings!";
0898 exit(EXIT_FAILURE);
0899 }
0900
0901 for (Long64_t i = 0; i < tree->GetEntries(); i++) {
0902 tree->GetEntry(i);
0903
0904
0905 const auto& indexPlus = findEtaPhiBin(hIP, posTrackEta, posTrackPhi);
0906 float deltaIPPlus = theMap[indexPlus];
0907
0908
0909 const auto& indexMinus = findEtaPhiBin(hIP, negTrackEta, negTrackPhi);
0910 float deltaIPMinus = theMap[indexMinus];
0911
0912 float IPdistance = std::abs(((posTrackIP + deltaIPPlus) - (negTrackIP + deltaIPMinus)));
0913
0914
0915 float deltaDeltaIPPlus =
0916 (posTrackIP + deltaIPPlus) < (negTrackIP + deltaIPMinus) ? IPdistance / 2. : -IPdistance / 2.;
0917 float deltaDeltaIPMinus =
0918 (posTrackIP + deltaIPPlus) < (negTrackIP + deltaIPMinus) ? -IPdistance / 2. : IPdistance / 2.;
0919
0920
0921
0922 deltaCorrection[indexPlus] += deltaDeltaIPPlus;
0923 deltaCorrection[indexMinus] += deltaDeltaIPMinus;
0924
0925 countsPerBin[indexPlus] += 1.;
0926 countsPerBin[indexMinus] += 1.;
0927 }
0928
0929 for (unsigned int i = 0; i < k_NBINS; i++) {
0930 for (unsigned int j = 0; j < k_NBINS; j++) {
0931 const auto& index = std::make_pair(i, j);
0932
0933 deltaCorrection[index] /= countsPerBin[index];
0934
0935 }
0936 }
0937
0938 std::cout << " ================================ iteration: " << iteration << std::endl;
0939 for (unsigned int i = 0; i < k_NBINS; i++) {
0940 for (unsigned int j = 0; j < k_NBINS; j++) {
0941 const auto& index = std::make_pair(i, j);
0942
0943
0944 theMap[index] += deltaCorrection[index];
0945 }
0946 }
0947
0948
0949 auto maxIter = std::max_element(deltaCorrection.begin(), deltaCorrection.end(), [](const auto& a, const auto& b) {
0950 return std::abs(a.second) < std::abs(b.second);
0951 });
0952
0953 return maxIter->second;
0954 }
0955
0956 float updateIPMapFast(
0957 TTree* tree, std::map<std::pair<int, int>, float>& theMap, TH2F*& hIP, const int iteration, anaKind type) {
0958 std::cout << "Calling updateIPMap with RDataFrame" << std::endl;
0959
0960 ROOT::RDataFrame df(*tree);
0961
0962 std::map<std::pair<int, int>, float> deltaCorrection;
0963 std::map<std::pair<int, int>, float> countsPerBin;
0964 for (unsigned int i = 0; i < k_NBINS; i++) {
0965 for (unsigned int j = 0; j < k_NBINS; j++) {
0966 const auto& index = std::make_pair(i, j);
0967 deltaCorrection[index] = 0.f;
0968 countsPerBin[index] = 0.f;
0969 }
0970 }
0971
0972
0973 auto columns = type == d0_t ? df.Define("posTrackIP", [](float d0) -> float { return d0; }, {"posTrackD0"})
0974 .Define("negTrackIP", [](float d0) -> float { return d0; }, {"negTrackD0"})
0975 : df.Define("posTrackIP", [](float dz) -> float { return dz; }, {"posTrackDz"})
0976 .Define("negTrackIP", [](float dz) -> float { return dz; }, {"negTrackDz"});
0977
0978 auto result =
0979 columns
0980 .Define("indexPlus",
0981 [hIP](float posTrackEta, float posTrackPhi) -> std::pair<int, int> {
0982 return findEtaPhiBin(hIP, posTrackEta, posTrackPhi);
0983 },
0984 {"posTrackEta", "posTrackPhi"})
0985 .Define("indexMinus",
0986 [hIP](float negTrackEta, float negTrackPhi) -> std::pair<int, int> {
0987 return findEtaPhiBin(hIP, negTrackEta, negTrackPhi);
0988 },
0989 {"negTrackEta", "negTrackPhi"})
0990 .Define("deltaIPPlus",
0991 [theMap](const std::pair<int, int>& indexPlus) -> float { return theMap.at(indexPlus); },
0992 {"indexPlus"})
0993 .Define("deltaIPMinus",
0994 [theMap](const std::pair<int, int>& indexMinus) -> float { return theMap.at(indexMinus); },
0995 {"indexMinus"})
0996 .Define("IPdistance",
0997 [](float posTrackIP, float deltaIPPlus, float negTrackIP, float deltaIPMinus) -> float {
0998 return std::abs((posTrackIP + deltaIPPlus) - (negTrackIP + deltaIPMinus));
0999 },
1000 {"posTrackIP", "deltaIPPlus", "negTrackIP", "deltaIPMinus"})
1001 .Define(
1002 "deltaDeltaIPPlus",
1003 [](float posTrackIP, float deltaIPPlus, float negTrackIP, float deltaIPMinus, float IPdistance) -> float {
1004 return (posTrackIP + deltaIPPlus) < (negTrackIP + deltaIPMinus) ? IPdistance / 2. : -IPdistance / 2.;
1005 },
1006 {"posTrackIP", "deltaIPPlus", "negTrackIP", "deltaIPMinus", "IPdistance"})
1007 .Define(
1008 "deltaDeltaIPMinus",
1009 [](float posTrackIP, float deltaIPPlus, float negTrackIP, float deltaIPMinus, float IPdistance) -> float {
1010 return (posTrackIP + deltaIPPlus) < (negTrackIP + deltaIPMinus) ? -IPdistance / 2. : IPdistance / 2.;
1011 },
1012 {"posTrackIP", "deltaIPPlus", "negTrackIP", "deltaIPMinus", "IPdistance"});
1013
1014
1015 result.Foreach(
1016 [&](const std::pair<int, int>& indexPlus,
1017 float deltaDeltaIPPlus,
1018 const std::pair<int, int>& indexMinus,
1019 float deltaDeltaIPMinus) {
1020 #pragma omp critical
1021 {
1022 deltaCorrection[indexPlus] += deltaDeltaIPPlus;
1023 deltaCorrection[indexMinus] += deltaDeltaIPMinus;
1024 countsPerBin[indexPlus] += 1.f;
1025 countsPerBin[indexMinus] += 1.f;
1026 }
1027 },
1028 {"indexPlus", "deltaDeltaIPPlus", "indexMinus", "deltaDeltaIPMinus"});
1029
1030
1031 for (unsigned int i = 0; i < k_NBINS; i++) {
1032 for (unsigned int j = 0; j < k_NBINS; j++) {
1033 const auto& index = std::make_pair(i, j);
1034 deltaCorrection[index] /= countsPerBin[index];
1035 }
1036 }
1037
1038
1039 std::cout << " ================================ iteration: " << iteration << std::endl;
1040 for (unsigned int i = 0; i < k_NBINS; i++) {
1041 for (unsigned int j = 0; j < k_NBINS; j++) {
1042 const auto& index = std::make_pair(i, j);
1043 theMap[index] += deltaCorrection[index];
1044 }
1045 }
1046
1047
1048 auto maxIter = std::max_element(deltaCorrection.begin(), deltaCorrection.end(), [](const auto& a, const auto& b) {
1049 return std::abs(a.second) < std::abs(b.second);
1050 });
1051
1052 return maxIter->second;
1053 }