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