10Implements cosgain correction
14import matplotlib.pyplot
as plt
15import matplotlib.ticker
as ticker
16from ROOT.Belle2
import CDCDedxValidationAlgorithm
17from matplotlib.backends.backend_pdf
import PdfPages
20def hist(y_min=None, y_max=None, x_min=None, x_max=None,
21 xlabel="", ylabel="", space=None, fx=1, fy=1,
22 fs1=20, fs2=8, font=18, rota=30, ax=None):
24 Configure histogram-style plot appearance.
26 If `ax` is None, applies to the current pyplot figure.
27 If `ax` is provided, applies to that axis (for subplots).
30 fig, ax = plt.subplots(fx, fy, figsize=(fs1, fs2))
34 if y_min
is not None or y_max
is not None:
35 ax.set_ylim(y_min, y_max)
36 if x_min
is not None or x_max
is not None:
37 ax.set_xlim(x_min, x_max)
39 ax.set_xlabel(xlabel, fontsize=font)
40 ax.set_ylabel(ylabel, fontsize=font)
41 ax.tick_params(axis=
'x', labelsize=font, rotation=rota)
42 ax.tick_params(axis=
'y', labelsize=font)
45 ax.xaxis.set_major_locator(ticker.MultipleLocator(space))
47 ax.yaxis.set_major_formatter(ticker.FormatStrFormatter(
'%.3f'))
53def parse_database(database_file, calib_key):
54 """Parse the database file and return exp -> [runs] mapping."""
58 with open(database_file)
as f:
60 if line.startswith(calib_key):
62 _, _, iov_str = line.strip().split(
' ')
63 exp, run =
map(int, iov_str.split(
',')[:2])
64 if exp != previous_exp:
65 exp_run_dict[exp] = [run]
68 exp_run_dict[exp].append(run)
69 except Exception
as e:
70 print(f
"[WARNING] Skipping line: {line.strip()} due to error: {e}")
76 """Main function to process cosine gain data and generate plots."""
78 os.makedirs(
'plots/constant', exist_ok=
True)
80 database_file = f
'{ccpath}/database.txt'
83 exp_run_dict = parse_database(database_file,
'dbstore/CDCDedxCosineCor')
85 group_labels = [
"SL0",
"SL1",
"SL2-8"]
88 for exp, run_list
in exp_run_dict.items():
90 print(f
"[INFO] Processing exp={exp}, run={run}")
92 cal = CDCDedxValidationAlgorithm()
94 prev_data = cal.getcosgain(exp, run)
97 cal.setTestingPayload(database_file)
98 new_data = cal.getcosgain(exp, run)
99 cal.setTestingPayload(
"")
102 prev_cc = prev_data.cosgain
if prev_data
else [[], [], []]
103 new_cc = new_data.cosgain
if new_data
else [[], [], []]
104 costh = new_data.costh
if new_data
else []
108 print(f
"[WARNING] Empty cos(theta) bins for exp={exp}, run={run}. Skipping.")
111 costh = list(costh)
if costh
is not None else []
112 df_costh = pd.DataFrame(costh, columns=[
'costh'])
114 pdf_path = f
'plots/constant/cosgain_e{exp}_r{run}.pdf'
115 with PdfPages(pdf_path)
as pdf:
116 fig, axes = plt.subplots(3, 2, figsize=(18, 16))
118 for igroup, glabel
in enumerate(group_labels):
119 prev_vals = list(prev_cc[igroup])
if len(prev_cc) > igroup
else []
120 new_vals = list(new_cc[igroup])
if len(new_cc) > igroup
else []
122 if len(prev_vals) == 0
or len(new_vals) == 0:
123 print(f
"[WARNING] Empty cosgain data for {glabel}, exp={exp}, run={run}.")
126 df_prev = pd.DataFrame([[x]
for x
in prev_vals], columns=[
'cosgain'])
127 df_new = pd.DataFrame([[x]
for x
in new_vals], columns=[
'cosgain'])
131 xlabel=
r"$\cos\theta$",
132 ylabel=f
"{glabel} dE/dx mean",
134 axes[igroup, 0].
plot(df_costh[
'costh'], df_new[
'cosgain'],
'*', label=
'new')
135 axes[igroup, 0].
plot(df_costh[
'costh'], df_prev[
'cosgain'],
'*', label=
'prev')
136 axes[igroup, 0].legend()
140 xlabel=
r"$\cos\theta$",
141 ylabel=
"Gain Ratio (new/prev)",
143 ratio = df_new[
'cosgain'] / df_prev[
'cosgain']
144 axes[igroup, 1].
plot(df_costh[
'costh'], ratio,
'*', label=
'ratio')
145 axes[igroup, 1].legend()
147 fig.suptitle(f
"CosGain Calibration - Experiment {exp}, Run {run}", fontsize=20)