ATLAS Offline Software
Loading...
Searching...
No Matches
combine_L1TopoRates_grid_matrices.cxx
Go to the documentation of this file.
1#include <TFile.h>
2#include <TH1.h>
3#include <TH2.h>
4#include <TSystemDirectory.h>
5#include <TSystemFile.h>
6#include <TList.h>
7#include <TMath.h>
8#include <iostream>
9#include <vector>
10#include <string>
11
12void combine_all(const char* inputDir,
13 const char* outputFile,
14 const std::vector<std::string>& matrixNames,
15 const char* eventHistName = "bcid") {
16 // Get all files in the directory
17 TSystemDirectory dir(inputDir, inputDir);
18 TList* filesList = dir.GetListOfFiles();
19 if (!filesList) {
20 std::cerr << "Error: cannot open directory " << inputDir << "\n";
21 return;
22 }
23
24 std::vector<std::string> inputFiles;
25 TIter next(filesList);
26 while (TSystemFile* f = (TSystemFile*) next()) {
27 TString fname = f->GetName();
28 if (!f->IsDirectory() && fname.EndsWith(".root") && fname.BeginsWith("RatesHistograms_data24_13p6TeV.")) {
29 inputFiles.push_back(std::string(inputDir) + "/" + fname.Data());
30 }
31 }
32
33 if (inputFiles.size() < 2) {
34 std::cerr << "Error: no valid files found in " << inputDir << "\n";
35 return;
36 }
37
38 std::cout << "Input files to be combined:\n";
39 for (const auto& f : inputFiles) {
40 std::cout << " " << f << "\n";
41 }
42 std::cout << "Found " << inputFiles.size() << " files to combine.\n";
43
44 // Open files and count events
45 std::vector<TFile*> files;
46 std::vector<double> nEvents;
47 double totalEvents = 0.0;
48
49 for (const auto& filename : inputFiles) {
50 TFile* f = TFile::Open(("file:" + std::string(filename)).c_str());
51 if (!f || f->IsZombie()) {
52 std::cerr << "Error: cannot open " << filename << "\n";
53 return;
54 }
55 files.push_back(f);
56
57 TH1* h_event = dynamic_cast<TH1*>(f->Get(eventHistName));
58 if (!h_event) {
59 std::cerr << "Error: histogram \"" << eventHistName << "\" not found in " << filename << "\n";
60 return;
61 }
62
63 double nev = h_event->GetEntries();
64 if (nev <= 0) {
65 std::cerr << "Error: zero events in " << filename << "\n";
66 return;
67 }
68
69 nEvents.push_back(nev);
70 totalEvents += nev;
71 }
72
73 // Print total number of events processed
74 std::cout << "Total number of events processed (bcid sum): " << totalEvents << "\n";
75
76 // Create output file
77 TFile* fout = TFile::Open(outputFile, "RECREATE");
78
79 // Process each matrix
80 for (const auto& matrixName : matrixNames) {
81 std::vector<TH2D*> matrices;
82
83 // Retrieve the matrix from each file
84 for (size_t i = 0; i < files.size(); ++i) {
85 TH2D* h_matrix = dynamic_cast<TH2D*>(files[i]->Get(matrixName.c_str()));
86 if (!h_matrix) {
87 std::cerr << "Error: matrix \"" << matrixName << "\" not found in "
88 << files[i]->GetName() << "\n";
89 return;
90 }
91 matrices.push_back(h_matrix);
92 }
93
94 // Create empty combined matrix
95 TH2D* h_combined = (TH2D*)matrices[0]->Clone((matrixName + "_combined").c_str());
96 h_combined->Reset();
97 h_combined->SetDirectory(0);
98
99 int nbx = h_combined->GetNbinsX();
100 int nby = h_combined->GetNbinsY();
101
102 bool isCounts = (matrixName == "counts_matrix");
103 // Combine bin by bin
104 for (int x = 1; x <= nbx; ++x) {
105 for (int y = 1; y <= nby; ++y) {
106 double sum = 0.0;
107 double sumErr2 = 0.0;
108 for (size_t i = 0; i < matrices.size(); ++i) {
109 double val = matrices[i]->GetBinContent(x, y);
110 double err = matrices[i]->GetBinError(x, y);
111
112 if (isCounts) {
113 sum += val; // sum counts directly
114 sumErr2 += err * err; // errors in quadrature
115 } else {
116 double w = nEvents[i] / totalEvents; // weighted average for rates
117 sum += w * val;
118 sumErr2 += w * w * err * err;
119 }
120 }
121 h_combined->SetBinContent(x, y, sum);
122 h_combined->SetBinError(x, y, std::sqrt(sumErr2));
123 }
124 }
125
126 // Save combined matrix
127 h_combined->Write();
128 std::cout << "Combined matrix \"" << matrixName << "\" written.\n";
129 }
130
131 fout->Close();
132 for (auto* f : files) f->Close();
133 std::cout << "Output file written to: " << outputFile << "\n";
134}
135
137 // Directory containing all .root files
138 const char* inputDir = "./athena24/run_grid/user.$.l1topoRates.EB_fullRun_00482596_1Oct25_RatesHistograms_XYZ.root.tgz/";
139 // Output file
140 const char* outputFile = "CombinedMatrices.root";
141
142 // Matrices to combine
143 std::vector<std::string> matrices = {
144 "rates_matrix",
145 "counts_matrix",
146 };
147
148 combine_all(inputDir, outputFile, matrices);
149
150 // ---- Calculate TopoScore matrix ----
151 TFile* fout = TFile::Open(outputFile, "UPDATE");
152 if (!fout || fout->IsZombie()) {
153 std::cerr << "Error: cannot open combined file to add L1TopoScore_matrix.\n";
154 return;
155 }
156
157 TH2D* h_rates = (TH2D*) fout->Get("rates_matrix_combined");
158 if (!h_rates) {
159 std::cerr << "Error: rates_matrix_combined not found!\n";
160 fout->Close();
161 return;
162 }
163
164 int nbx = h_rates->GetNbinsX();
165 int nby = h_rates->GetNbinsY();
166
167 TH2D* h_topo = (TH2D*)h_rates->Clone("L1TopoScore_matrix_combined");
168 h_topo->Reset();
169
170 // Loop over bins and compute TS and its error by propagation
171 for (int ix = 1; ix <= nbx; ++ix) {
172 for (int jy = 1; jy <= nby; ++jy) {
173 // Diagonal treatment: TS(i,i) = 1 (A==B and O==A typically), set error 0
174 if (ix == jy) {
175 h_topo->SetBinContent(ix, jy, 1.0);
176 h_topo->SetBinError(ix, jy, 0.0);
177 continue;
178 }
179
180 double A = h_rates->GetBinContent(ix, ix); // diagonal A
181 double sigmaA = h_rates->GetBinError(ix, ix);
182 double B = h_rates->GetBinContent(jy, jy); // diagonal B
183 double sigmaB = h_rates->GetBinError(jy, jy);
184 double O = h_rates->GetBinContent(ix, jy); // overlap
185 double sigmaO = h_rates->GetBinError(ix, jy);
186
187 // Safety checks
188 if (O <= 0.0) {
189 h_topo->SetBinContent(ix, jy, 0.0);
190 h_topo->SetBinError(ix, jy, 0.0);
191 continue;
192 }
193 double denom = O * (A + B - O);
194 if (denom <= 0.0) {
195 h_topo->SetBinContent(ix, jy, 0.0);
196 h_topo->SetBinError(ix, jy, 0.0);
197 continue;
198 }
199
200 double TS = (A * B) / denom;
201
202 // Derivatives
203 // D = denom
204 double D = denom;
205 double dD_dA = O;
206 double dD_dB = O;
207 double dD_dO = (A + B - 2.0 * O); // derivative of O*(A+B-O) w.r.t O
208
209 // Using TS = N / D, with N = A*B
210 double N = A * B;
211
212 // dTS/dA = (dN/dA * D - N * dD/dA) / D^2 = (B*D - N*O)/D^2
213 double dTS_dA = (B * D - N * dD_dA) / (D * D);
214 // dTS/dB = (A*D - N*O)/D^2
215 double dTS_dB = (A * D - N * dD_dB) / (D * D);
216 // dTS/dO = - N * dD/dO / D^2
217 double dTS_dO = - N * dD_dO / (D * D);
218
219 // Propagate errors (assume A,B,O independent)
220 double varTS = 0.0;
221 if (sigmaA > 0.0) varTS += (dTS_dA * dTS_dA) * (sigmaA * sigmaA);
222 if (sigmaB > 0.0) varTS += (dTS_dB * dTS_dB) * (sigmaB * sigmaB);
223 if (sigmaO > 0.0) varTS += (dTS_dO * dTS_dO) * (sigmaO * sigmaO);
224
225 double sigmaTS = (varTS > 0.0) ? std::sqrt(varTS) : 0.0;
226
227 h_topo->SetBinContent(ix, jy, TS);
228 h_topo->SetBinError(ix, jy, sigmaTS);
229 }
230 }
231
232 fout->cd();
233 h_topo->Write();
234 fout->Close();
235 std::cout << "L1TopoScore_matrix_combined written successfully.\n";
236}
237
#define y
#define x
void combine_all(const char *inputDir, const char *outputFile, const std::vector< std::string > &matrixNames, const char *eventHistName="bcid")
const int nEvents
std::vector< std::string > files
file names and file pointers
Definition hcg.cxx:50
static TFile * fout
Definition listroot.cxx:40
hold the test vectors and ease the comparison