Skip to content

Commit e6940e9

Browse files
author
miranov25
committed
make diff of time series
1 parent 47abb77 commit e6940e9

File tree

1 file changed

+164
-0
lines changed

1 file changed

+164
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
"""timeseries_diff.py
2+
import sys,os; sys.path.insert(1, os.environ[f"O2DPG"]+"/UTILS/TimeSeries");
3+
from timeseries_diff import *
4+
5+
Utility helpers for time‑series comparison scripts.
6+
keeping their ROOT files alive.
7+
"""
8+
9+
import os
10+
import pathlib
11+
from typing import List, Tuple, Optional
12+
13+
import ROOT # PyROOT
14+
15+
# ---------------------------------------------------------------------------
16+
# Helper: open many ROOT files and keep them alive
17+
# ---------------------------------------------------------------------------
18+
19+
def read_time_series(listfile: str = "o2_timeseries_tpc.list",treename: str = "timeSeries",) -> List[Tuple[ROOT.TFile, Optional[ROOT.TTree]]]:
20+
"""Read *listfile* containing one ROOT path per line and return a list
21+
of ``(TFile, TTree | None)`` tuples.
22+
The TFile objects are **kept open** (and returned) so the TTrees remain
23+
valid for the caller. Blank lines and lines starting with "#" are
24+
ignored. Environment variables in paths are expanded.
25+
Parameters
26+
----------
27+
listfile : str
28+
Text file with ROOT filenames.
29+
treename : str, default "timeSeries"
30+
Name of the tree to retrieve from each file.
31+
Returns
32+
-------
33+
list of tuples
34+
``[(f1, tree1), (f2, tree2), ...]`` where *tree* is ``None`` if
35+
the file or tree could not be opened.
36+
"""
37+
files_and_trees: List[Tuple[ROOT.TFile, Optional[ROOT.TTree]]] = []
38+
39+
with open(listfile, "r") as fh:
40+
paths = [ln.strip() for ln in fh if ln.strip() and not ln.startswith("#")]
41+
42+
for raw_path in paths:
43+
path = os.path.expandvars(raw_path)
44+
if not pathlib.Path(path).is_file():
45+
print(f"[read_time_series] warning: file not found -> {path}")
46+
files_and_trees.append((None, None))
47+
continue
48+
try:
49+
froot = ROOT.TFile.Open(path)
50+
if not froot or froot.IsZombie():
51+
raise RuntimeError("file could not be opened")
52+
tree = froot.Get(treename)
53+
if not tree:
54+
print(f"[read_time_series] warning: tree '{treename}' missing in {path}")
55+
files_and_trees.append((froot, tree))
56+
except Exception as e:
57+
print(f"[read_time_series] error: cannot open {path}: {e}")
58+
files_and_trees.append((None, None))
59+
60+
return files_and_trees
61+
62+
def makeAliases(trees):
63+
for tree in trees: tree[1].AddFriend(trees[0][1],"F")
64+
65+
66+
def setStyle():
67+
ROOT.gStyle.SetOptStat(0)
68+
ROOT.gStyle.SetOptTitle(0)
69+
ROOT.gStyle.SetPalette(ROOT.kRainBow)
70+
ROOT.gStyle.SetPaintTextFormat(".2f")
71+
ROOT.gStyle.SetTextFont(42)
72+
ROOT.gStyle.SetTextSize(0.04)
73+
ROOT.gROOT.ForceStyle()
74+
ROOT.gROOT.SetBatch(True)
75+
76+
77+
78+
79+
80+
81+
# ---------------------------------------------------------------------------
82+
# make_ratios ----------------------------------------------------------------
83+
# ---------------------------------------------------------------------------
84+
85+
def make_ratios(trees: list, outdir: str = "fig", pdf_name: str = "ratios.pdf") -> ROOT.TCanvas:
86+
"""Create ratio plots *log(var/F.var) vs Iteration$* for each input tree.
87+
* A PNG for every variable / tree is saved to *outdir*
88+
* All canvases are also appended to a multi‑page PDF *pdf_name*
89+
* Vertical guide‑lines mark the logical regions (isector, itgl, iqpt, occu)
90+
91+
"""
92+
outdir = pathlib.Path(outdir)
93+
outdir.mkdir(parents=True, exist_ok=True)
94+
pdf_path = outdir / pdf_name
95+
96+
# ------- style / helpers ----------------------------------------------
97+
ROOT.gStyle.SetOptTitle(1)
98+
canvas = ROOT.TCanvas("c_ratio", "ratio plots", 1200, 600)
99+
lab = ROOT.TLatex()
100+
lab.SetTextSize(0.04)
101+
102+
# vertical guides in **user** x‑coordinates (Iteration$ axis: 0–128)
103+
vlines = [0, 54, 84, 104, 127]
104+
vnames = ["isector", "itgl", "iqpt", "occupancy"]
105+
vcolors = [ROOT.kRed+1, ROOT.kBlue+1, ROOT.kGreen+2, ROOT.kMagenta+1]
106+
setups=["ref","apass2_closure-test-zAcc.GausSmooth_test3_streamer","apass2_closure-test-zAcc.GausSmooth_test4_streamer","apass2_closure-test-zAcc.GausSmooth_test2_streamer"]
107+
# variables to compare ---------------------------------------------------
108+
vars_ = [
109+
"mTSITSTPC.mTPCChi2A", "mTSITSTPC.mTPCChi2C",
110+
"mTSTPC.mDCAr_A_NTracks", "mTSTPC.mDCAr_C_NTracks",
111+
"mTSTPC.mTPCNClA", "mTSTPC.mTPCNClC",
112+
"mITSTPCAll.mITSTPC_A_MatchEff", "mITSTPCAll.mITSTPC_C_MatchEff",
113+
"mdEdxQMax.mLogdEdx_A_RMS","mdEdxQMax.mLogdEdx_C_RMS",
114+
"mdEdxQMax.mLogdEdx_A_IROC_RMS","mdEdxQMax.mLogdEdx_C_IROC_RMS"
115+
]
116+
cut = "mTSITSTPC.mDCAr_A_NTracks > 200"
117+
118+
# open PDF ---------------------------------------------------------------
119+
canvas.Print(f"{pdf_path}[") # begin multipage
120+
121+
for setup_index, (_, tree) in enumerate(trees[1:], start=1):
122+
if not tree:
123+
continue
124+
for var in vars_:
125+
expr = f"log({var}/F.{var}):Iteration$"
126+
# 2‑D density histogram
127+
tree.Draw(f"{expr}>>his(128,0,128,50,-0.05,0.05)", cut, "colz")
128+
# profile overlay
129+
tree.Draw(f"{expr}>>hp(128,0,128)", cut, "profsame")
130+
pad = ROOT.gPad
131+
ymin, ymax = -0.05, 0.05
132+
# keep references so ROOT does not garbage‑collect the guides
133+
guides: list[ROOT.TLine] = []
134+
for x, txt, col in zip(vlines, vnames, vcolors):
135+
# skip lines outside current x‑range (safety when reusing canvas)
136+
if x < 0 or x > 128:continue
137+
# 1) vertical line in **user** coordinates
138+
ln = ROOT.TLine(x, ymin, x, ymax)
139+
ln.SetLineColor(col)
140+
ln.SetLineStyle(2)
141+
ln.SetLineWidth(5)
142+
ln.Draw()
143+
guides.append(ln)
144+
# 2) text in NDC (pad‑relative) for stable position
145+
x_ndc = pad.XtoPad(x) # already NDC 0‑1
146+
lab.SetTextColor(col)
147+
lab.DrawLatex(x + 0.02, 0.03, txt)
148+
149+
# label of the setup on top‑left
150+
lab.SetTextColor(ROOT.kMagenta+2)
151+
lab.DrawLatex(0.15, 0.05, f"Setup {setups[setup_index]}")
152+
canvas.Modified(); canvas.Update()
153+
154+
# ----------------------------------------------------------------
155+
tag = var.split('.')[-1]
156+
canvas.SaveAs(str(outdir / f"ratio_{setup_index}_{tag}.png"))
157+
canvas.Print(str(pdf_path)) # add page
158+
159+
# prevent ROOT from deleting the guides before next Draw()
160+
for ln in guides:
161+
pad.GetListOfPrimitives().Remove(ln)
162+
163+
canvas.Print(f"{pdf_path}]") # close multipage
164+
return canvas

0 commit comments

Comments
 (0)