246 def compute_roc(self, sig, bkg):
247 n_bins = sig.GetNbinsX()
248 total_sig = sig.Integral()
249 total_bkg = bkg.Integral()
250
251 x_vals, y_vals = [], []
252 if total_sig == 0 or total_bkg == 0:
253 logging.error("Zero total signal or background counts; cannot compute ROC.")
254 return None
255
256 for cut_bin in range(1, n_bins + 1):
257 sig_pass = sig.Integral(cut_bin, n_bins)
258 bkg_pass = bkg.Integral(cut_bin, n_bins)
259
260 eff = sig_pass / total_sig
261
262 if bkg_pass <= 0:
263
264 continue
265
266 rej = total_bkg / bkg_pass
267
268 x_vals.append(eff)
269 y_vals.append(rej)
270
271 if not x_vals:
272 return None
273
274 graph = ROOT.TGraphErrors(len(x_vals))
275 for i, (x, y) in enumerate(zip(x_vals, y_vals)):
276 graph.SetPoint(i, x, y)
277
278 return graph
279