File indexing completed on 2025-01-30 09:14:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <cmath>
0010 #include <iostream>
0011 #include <map>
0012 #include <numbers>
0013 #include <string>
0014 #include <tuple>
0015
0016 #include <TCanvas.h>
0017 #include <TDirectory.h>
0018 #include <TFile.h>
0019 #include <TH1F.h>
0020 #include <TProfile.h>
0021 #include <TTree.h>
0022
0023 struct MaterialHistograms {
0024 TProfile* x0_vs_eta = nullptr;
0025 TProfile* l0_vs_eta = nullptr;
0026
0027 TProfile* x0_vs_phi = nullptr;
0028 TProfile* l0_vs_phi = nullptr;
0029
0030 float s_x0 = 0.;
0031 float s_l0 = 0.;
0032
0033 MaterialHistograms() = default;
0034
0035
0036
0037
0038 MaterialHistograms(const std::string& name, unsigned int iA,
0039 unsigned int bins, float eta) {
0040 std::string x0NameEta =
0041 (iA == 0) ? name + std::string("_x0_vs_eta_all")
0042 : name + std::string("_x0_vs_eta_A") + std::to_string(iA);
0043 std::string l0NameEta =
0044 (iA == 0) ? name + std::string("_l0_vs_eta_all")
0045 : name + std::string("_l0_vs_eta_A") + std::to_string(iA);
0046
0047 x0_vs_eta =
0048 new TProfile(x0NameEta.c_str(), "X_{0} vs. #eta", bins, -eta, eta);
0049 l0_vs_eta =
0050 new TProfile(l0NameEta.c_str(), "L_{0} vs. #eta", bins, -eta, eta);
0051
0052 std::string x0NamePhi =
0053 (iA == 0) ? name + std::string("_x0_vs_phi_all")
0054 : name + std::string("_x0_vs_phi_A") + std::to_string(iA);
0055 std::string l0NamePhi =
0056 (iA == 0) ? name + std::string("_l0_vs_phi_all")
0057 : name + std::string("_l0_vs_phi_A") + std::to_string(iA);
0058
0059 x0_vs_phi =
0060 new TProfile(x0NamePhi.c_str(), "X_{0} vs. #phi", bins, -std::numbers::pi, std::numbers::pi);
0061 l0_vs_phi =
0062 new TProfile(l0NamePhi.c_str(), "L_{0} vs. #phi", bins, -std::numbers::pi, std::numbers::pi);
0063 }
0064
0065
0066
0067
0068
0069
0070
0071 void fillAndClear(float eta, float phi) {
0072 x0_vs_eta->Fill(eta, s_x0);
0073 l0_vs_eta->Fill(eta, s_l0);
0074
0075 x0_vs_phi->Fill(phi, s_x0);
0076 l0_vs_phi->Fill(phi, s_l0);
0077
0078 s_x0 = 0.;
0079 s_l0 = 0.;
0080 }
0081
0082
0083
0084
0085
0086
0087 void write() {
0088 if (x0_vs_eta->GetMaximum() > 0.) {
0089 x0_vs_eta->Write();
0090 l0_vs_eta->Write();
0091
0092 x0_vs_phi->Write();
0093 l0_vs_phi->Write();
0094 }
0095 }
0096 };
0097
0098 struct Region {
0099 std::string name;
0100 std::vector<std::tuple<float, float, float, float>> boxes;
0101
0102 bool inside(float r, float z) const {
0103 for (const auto& [minR, maxR, minZ, maxZ] : boxes) {
0104 if (minR <= r && r < maxR && minZ <= z && z < maxZ) {
0105 return true;
0106 }
0107 }
0108 return false;
0109 }
0110 };
0111
0112
0113
0114
0115
0116
0117
0118
0119 void materialComposition(const std::string& inFile, const std::string& treeName,
0120 const std::string& outFile, unsigned int bins,
0121 float eta, const std::vector<Region>& regions) {
0122
0123 auto inputFile = TFile::Open(inFile.c_str());
0124 auto inputTree = dynamic_cast<TTree*>(inputFile->Get(treeName.c_str()));
0125 if (inputTree == nullptr) {
0126 return;
0127 }
0128
0129
0130 TCanvas* materialCanvas =
0131 new TCanvas("materialCanvas", "Materials", 100, 100, 620, 400);
0132 materialCanvas->cd();
0133
0134 inputTree->Draw("mat_A>>hA(200,0.5,200.5)");
0135 TH1F* histA = dynamic_cast<TH1F*>(gDirectory->Get("hA"));
0136 if (histA == nullptr) {
0137 throw std::runtime_error{"Could not get the histogram"};
0138 }
0139
0140 histA->Draw();
0141
0142 auto outputFile = TFile::Open(outFile.c_str(), "recreate");
0143
0144 float v_eta = 0;
0145 float v_phi = 0;
0146 std::vector<float>* stepLength = new std::vector<float>;
0147 std::vector<float>* stepX0 = new std::vector<float>;
0148 std::vector<float>* stepL0 = new std::vector<float>;
0149 std::vector<float>* stepA = new std::vector<float>;
0150
0151 std::vector<float>* stepX = new std::vector<float>;
0152 std::vector<float>* stepY = new std::vector<float>;
0153 std::vector<float>* stepZ = new std::vector<float>;
0154
0155 inputTree->SetBranchAddress("v_eta", &v_eta);
0156 inputTree->SetBranchAddress("v_phi", &v_phi);
0157 inputTree->SetBranchAddress("mat_step_length", &stepLength);
0158
0159 inputTree->SetBranchAddress("mat_X0", &stepX0);
0160 inputTree->SetBranchAddress("mat_L0", &stepL0);
0161 inputTree->SetBranchAddress("mat_A", &stepA);
0162
0163 inputTree->SetBranchAddress("mat_x", &stepX);
0164 inputTree->SetBranchAddress("mat_y", &stepY);
0165 inputTree->SetBranchAddress("mat_z", &stepZ);
0166
0167
0168 unsigned int entries = inputTree->GetEntries();
0169
0170 #ifdef BOOST_AVAILABLE
0171 std::cout << "*** Event Loop: " << std::endl;
0172 progress_display event_loop_progress(entries * regions.size());
0173 #endif
0174
0175
0176 for (auto& region : regions) {
0177 const auto rName = region.name;
0178
0179
0180 std::map<unsigned int, MaterialHistograms> mCache;
0181
0182
0183 mCache[0] = MaterialHistograms(rName, 0, bins, eta);
0184 for (unsigned int ib = 1; ib <= 200; ++ib) {
0185 if (histA->GetBinContent(ib) > 0.) {
0186 mCache[ib] = MaterialHistograms(rName, ib, bins, eta);
0187 }
0188 }
0189
0190 for (unsigned int ie = 0; ie < entries; ++ie) {
0191
0192 inputTree->GetEntry(ie);
0193
0194 #ifdef BOOST_AVAILABLE
0195 ++event_loop_progress;
0196 #endif
0197
0198
0199 std::size_t steps = stepLength->size();
0200 for (unsigned int is = 0; is < steps; ++is) {
0201 float x = stepX->at(is);
0202 float y = stepY->at(is);
0203 float z = stepZ->at(is);
0204 float r = std::hypot(x, y);
0205
0206 if (!region.inside(r, z)) {
0207 continue;
0208 }
0209
0210 float step = stepLength->at(is);
0211 float X0 = stepX0->at(is);
0212 float L0 = stepL0->at(is);
0213
0214
0215 auto& all = mCache[0];
0216 all.s_x0 += step / X0;
0217 all.s_l0 += step / L0;
0218
0219 unsigned int sA = histA->FindBin(stepA->at(is));
0220
0221 auto currentIt = mCache.find(sA);
0222 if (currentIt == mCache.end()) {
0223 throw std::runtime_error{"Unknown atomic number " +
0224 std::to_string(sA)};
0225 }
0226 auto& current = currentIt->second;
0227 current.s_x0 += step / X0;
0228 current.s_l0 += step / L0;
0229 }
0230
0231 for (auto& [key, cache] : mCache) {
0232 cache.fillAndClear(v_eta, v_phi);
0233 }
0234 }
0235
0236
0237 for (auto [key, cache] : mCache) {
0238 cache.write();
0239 }
0240 }
0241
0242 outputFile->Close();
0243
0244 delete stepLength;
0245 delete stepX0;
0246 delete stepL0;
0247 delete stepA;
0248
0249 delete stepX;
0250 delete stepY;
0251 delete stepZ;
0252
0253 delete materialCanvas;
0254 }