File indexing completed on 2026-09-20 08:25:50
0001
0002
0003
0004
0005
0006 #include "ROOT/RDataFrame.hxx"
0007 #include <iostream>
0008
0009 #include "edm4hep/MCParticleCollection.h"
0010 #include "edm4hep/SimCalorimeterHitCollection.h"
0011
0012 R__LOAD_LIBRARY(libfmt.so)
0013 #include "fmt/core.h"
0014
0015 #include "TCanvas.h"
0016 #include "TStyle.h"
0017 #include "TMath.h"
0018 #include "TH1.h"
0019 #include "TF1.h"
0020 #include "TH1D.h"
0021 #include "TFitResult.h"
0022 #include <nlohmann/json.hpp>
0023 #include <fstream>
0024
0025 using ROOT::RDataFrame;
0026 using namespace ROOT::VecOps;
0027
0028 void emcal_barrel_pi0_analysis(
0029 const char* input_fname = "sim_output/sim_emcal_barrel_pi0.edm4hep.root"
0030
0031 )
0032 {
0033
0034 gROOT->SetStyle("Plain");
0035 gStyle->SetOptFit(1);
0036 gStyle->SetLineWidth(2);
0037 gStyle->SetPadTickX(1);
0038 gStyle->SetPadTickY(1);
0039 gStyle->SetPadGridX(1);
0040 gStyle->SetPadGridY(1);
0041 gStyle->SetPadLeftMargin(0.14);
0042 gStyle->SetPadRightMargin(0.14);
0043
0044 ROOT::EnableImplicitMT();
0045 ROOT::RDataFrame d0("events", input_fname);
0046
0047
0048 nlohmann::json j;
0049 std::ifstream prev_steps_ifstream("results/emcal_barrel_electron_calibration.json");
0050 prev_steps_ifstream >> j;
0051 double samp_frac = j["electron"]["sampling_fraction"];
0052
0053
0054 auto Ethr = [](std::vector<edm4hep::MCParticleData> const& input) {
0055 return TMath::Sqrt(input[2].momentum.x*input[2].momentum.x + input[2].momentum.y*input[2].momentum.y + input[2].momentum.z*input[2].momentum.z + input[2].mass*input[2].mass);
0056 };
0057
0058
0059 auto nhits = [] (const std::vector<edm4hep::SimCalorimeterHitData>& evt) {return (int) evt.size(); };
0060
0061
0062 auto Esim = [](const std::vector<edm4hep::SimCalorimeterHitData>& evt) {
0063 auto total_edep = 0.0;
0064 for (const auto& i: evt){
0065 total_edep += i.energy;
0066 }
0067 return total_edep;
0068 };
0069
0070
0071 auto fsam = [](const double& sampled, const double& thrown) {
0072 return sampled / thrown;
0073 };
0074
0075
0076 auto eResol = [&](const double& sampled, const double& thrown){
0077 return sampled / samp_frac - thrown;
0078 };
0079
0080
0081 auto eResol_rel = [&](const double& sampled, const double& thrown){
0082 return (sampled / samp_frac - thrown) / thrown;
0083 };
0084
0085
0086 auto getpid = [](std::vector<edm4hep::MCParticleData> const& input) {
0087 return input[2].PDG;
0088 };
0089
0090
0091 auto getdau = [](std::vector<edm4hep::MCParticleData> const& input) {
0092 return input[2].daughters_begin;
0093 };
0094
0095
0096 auto d1 = ROOT::RDF::RNode(
0097 d0.Define("Ethr", Ethr, {"MCParticles"})
0098 .Define("pid", getpid, {"MCParticles"})
0099 .Define("dau", getdau, {"MCParticles"})
0100 );
0101
0102 auto Ethr_max = 7.5;
0103 auto fsam_est = 1.0;
0104 if (d1.HasColumn("EcalBarrelScFiHits")) {
0105 d1 = d1.Define("nhits", nhits, {"EcalBarrelImagingHits"})
0106 .Define("EsimImg", Esim, {"EcalBarrelImagingHits"})
0107 .Define("EsimScFi", Esim, {"EcalBarrelScFiHits"})
0108 .Define("Esim", "EsimImg+EsimScFi")
0109 .Define("fsamImg", fsam, {"EsimImg", "Ethr"})
0110 .Define("fsamScFi", fsam, {"EsimScFi", "Ethr"})
0111 .Define("fsam", fsam, {"Esim", "Ethr"});
0112 fsam_est = 1.2*samp_frac;
0113 } else {
0114 d1 = d1.Define("nhits", nhits, {"EcalBarrelSciGlassHits"})
0115 .Define("Esim", Esim, {"EcalBarrelSciGlassHits"})
0116 .Define("fsam", fsam, {"Esim", "Ethr"});
0117 fsam_est = 1.0;
0118 }
0119 d1 = d1.Define("dE", eResol, {"Esim","Ethr"})
0120 .Define("dE_rel", eResol_rel, {"Esim","Ethr"});
0121
0122
0123 std::vector <std::string> titleStr = {
0124 "Thrown Energy; Thrown Energy [GeV]; Events",
0125 "Number of hits per events; Number of hits; Events",
0126 "Energy Deposit; Energy Deposit [GeV]; Events",
0127 "dE Relative; dE Relative; Events"
0128 };
0129
0130 std::vector<std::vector<double>> range = {{0, Ethr_max}, {0, 2000}, {0, fsam_est * Ethr_max}, {-3, 3}};
0131 std::vector<std::string> col = {"Ethr", "nhits", "Esim", "dE_rel"};
0132
0133 double meanE = 5;
0134 int nCol = range.size();
0135 for (int i = 0; i < nCol; i++){
0136 int binNum = 100;
0137 auto h = d1.Histo1D({"hist", titleStr[i].c_str(), binNum, range[i][0], range[i][1]}, col[i].c_str());
0138 if (col[i] == "Ethr"){
0139 meanE = h->GetMean();
0140 }
0141 auto *c = new TCanvas("c", "c", 700, 500);
0142 c->SetLogy(1);
0143 auto h1 = h->DrawCopy();
0144 h1->GetYaxis()->SetTitleOffset(1.4);
0145 h1->SetLineWidth(2);
0146 h1->SetLineColor(kBlue);
0147 c->SaveAs((fmt::format("results/emcal_barrel_pi0_{}.png", col[i])).c_str());
0148 c->SaveAs((fmt::format("results/emcal_barrel_pi0_{}.pdf", col[i])).c_str());
0149
0150 }
0151
0152
0153 titleStr = {
0154 "Sampling Fraction; Sampling Fraction; Events",
0155 "dE; dE[GeV]; Events"
0156 };
0157 range = {{0,fsam_est}, {-3, 3}};
0158 col = {"fsam", "dE"};
0159 nCol = range.size();
0160 std::printf("Here %d\n", 10);
0161 std::vector<std::vector<double>> fitRange = {{0.005, fsam_est}, {-3, 3}};
0162 double sigmaOverE = 0;
0163
0164 auto hr = d1.Histo1D({"histr", titleStr[0].c_str(), 150, range[0][0], range[0][1]}, col[0].c_str());
0165 auto *c = new TCanvas("c", "c", 700, 500);
0166 c->SetLogy(1);
0167 auto h2 = hr->DrawCopy();
0168 h2->GetYaxis()->SetTitleOffset(1.4);
0169 h2->SetLineWidth(2);
0170 h2->SetLineColor(kBlue);
0171 h2->Fit("gaus","","", fitRange[0][0], fitRange[0][1]);
0172 h2->GetFunction("gaus")->SetLineWidth(2);
0173 h2->GetFunction("gaus")->SetLineColor(kRed);
0174
0175 c->SaveAs((fmt::format("results/emcal_barrel_pi0_{}.png", col[0])).c_str());
0176 c->SaveAs((fmt::format("results/emcal_barrel_pi0_{}.pdf", col[0])).c_str());
0177 std::printf("Resolution %d\n", 0);
0178
0179
0180 auto hs = d1.Histo1D({"hists", titleStr[1].c_str(), 100, range[1][0], range[1][1]}, col[1].c_str());
0181 auto *c1 = new TCanvas("c1", "c1", 700, 500);
0182 c1->SetLogy(1);
0183 auto h3 = hs->DrawCopy();
0184 h3->GetYaxis()->SetTitleOffset(1.4);
0185 h3->SetLineWidth(2);
0186 h3->SetLineColor(kBlue);
0187 auto fit = h3->Fit("gaus","","", fitRange[1][0], fitRange[1][1]);
0188 if (fit == 0) {
0189 double* res = h3->GetFunction("gaus")->GetParameters();
0190 sigmaOverE = res[2] / meanE;
0191 } else {
0192 std::printf("Fit failed\n");
0193 sigmaOverE = h3->GetStdDev() / h3->GetMean();
0194 }
0195 c1->SaveAs((fmt::format("results/emcal_barrel_pi0_{}.png", col[1])).c_str());
0196 c1->SaveAs((fmt::format("results/emcal_barrel_pi0_{}.pdf", col[1])).c_str());
0197 std::printf("Resolution %d\n", 1);
0198
0199
0200 std::string test_tag = "Barrel_emcal_pi0";
0201 std::string detEle = "Barrel_emcal";
0202
0203
0204
0205
0206
0207 double resolutionTarget = TMath::Sqrt(0.12 * 0.12 / meanE + 0.02 * 0.02);
0208
0209 std::cout << fmt::format("Pi0 energy resolution: {} (target: {})\n", sigmaOverE, resolutionTarget);
0210 }