ATLAS Offline Software
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 
12 void 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 
nEvents
const int nEvents
Definition: fbtTestBasics.cxx:78
JTC::TS
TS
Definition: IJetTileCorrectionTool.h:27
combine_all
void combine_all(const char *inputDir, const char *outputFile, const std::vector< std::string > &matrixNames, const char *eventHistName="bcid")
Definition: combine_L1TopoRates_grid_matrices.cxx:12
Epos_Base_Fragment.inputFiles
string inputFiles
Definition: Epos_Base_Fragment.py:18
readDataHeader.totalEvents
int totalEvents
Definition: readDataHeader.py:73
JetTiledMap::N
@ N
Definition: TiledEtaPhiMap.h:44
x
#define x
compareGeometries.outputFile
string outputFile
Definition: compareGeometries.py:25
A
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:183
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
lumiFormat.i
int i
Definition: lumiFormat.py:85
dqt_zlumi_alleff_HIST.fout
fout
Definition: dqt_zlumi_alleff_HIST.py:59
generateReferenceFile.files
files
Definition: generateReferenceFile.py:12
hist_file_dump.f
f
Definition: hist_file_dump.py:140
TestSUSYToolsAlg.inputDir
string inputDir
Definition: TestSUSYToolsAlg.py:74
compute_lumi.denom
denom
Definition: compute_lumi.py:76
beamspotman.dir
string dir
Definition: beamspotman.py:619
dqt_zlumi_alleff_HIST.B
B
Definition: dqt_zlumi_alleff_HIST.py:110
combine_RCmatrices
void combine_RCmatrices()
Definition: combine_L1TopoRates_grid_matrices.cxx:136
python.AthDsoLogger.fname
string fname
Definition: AthDsoLogger.py:66
y
#define y
LArCellNtuple.nev
int nev
Definition: LArCellNtuple.py:135
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:23
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:198