Coverage for polars_analysis / plotting / frame_plotting.py: 58%

170 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-13 13:37 -0400

1import logging 

2from pathlib import Path 

3 

4import matplotlib 

5 

6matplotlib.use("agg") 

7import matplotlib.pyplot as plt 

8import numpy as np 

9 

10from polars_analysis.analysis import constants 

11from polars_analysis.plotting import helper 

12 

13# Instantiate logger 

14log = logging.getLogger(__name__) 

15 

16""" 

17Functions for frame analysis plotting. 

18""" 

19 

20 

21def plot_mean_v_time( 

22 x, 

23 y, 

24 plot_dir, 

25 info, 

26): 

27 # Mean v time 

28 plt.figure(figsize=(15, 4)) 

29 plt.plot(x, y.T) 

30 plt.title(helper.plot_summary_string(name="Pedestal Mean vs Time", info=info)) 

31 plt.xlabel("Time [s]") 

32 plt.ylabel("Mean ADC Counts") 

33 plt.tight_layout() 

34 plt.savefig(Path(plot_dir / f"mean_v_time_{info.gain}.png")) 

35 plt.cla() 

36 plt.clf() 

37 plt.close() 

38 

39 

40def plot_60hz_power( 

41 freq, 

42 psd, 

43 plot_dir, 

44 info, 

45 channels, 

46): 

47 # Power in 60 Hz 

48 plt.figure(figsize=(15, 4)) 

49 min = np.where(freq > 59)[0][0] 

50 max = np.where(freq < 61)[0][-1] 

51 if np.abs(max - min) < 2: 

52 log.error("60 Hz not found") 

53 return 

54 sixtyhz = psd[:, min:max].max(axis=1) 

55 

56 arr = np.zeros(128) 

57 for index, channel in enumerate(channels): 

58 arr[channel] = sixtyhz[index] 

59 

60 plt.xticks(np.arange(0, 128, 4), rotation=70) 

61 plt.bar(np.arange(128), arr, fill=False) 

62 plt.xlabel("Channel") 

63 plt.ylabel("Power [ADC Counts ^ 2 / Hz]") 

64 plt.title(helper.plot_summary_string(name="60 Hz Power", info=info)) 

65 plt.grid() 

66 plt.tight_layout() 

67 plt.yscale("log") 

68 plt.savefig(plot_dir / f"fft_60hz_{info.gain}.png") 

69 plt.cla() 

70 plt.clf() 

71 plt.close() 

72 

73 

74def plot_adc_full_bcid( 

75 channel, 

76 h_bcid, 

77 plot_dir, 

78 info, 

79): 

80 # vs BCID plot 

81 plt.figure(figsize=(15, 4)) 

82 

83 plt.plot(np.arange(constants.N_BCID), h_bcid[0], ".") 

84 plt.title(helper.plot_summary_string(name="Histogram of ADC BCIDs", info=info)) 

85 plt.xlabel("BCID") 

86 plt.ylabel("Count") 

87 # plt.xlim(0, 64) 

88 plt.grid() 

89 plt.tight_layout() 

90 plt.savefig(Path(plot_dir / f"adc_bcid_histo_ch{channel}_{info.gain}.png")) 

91 plt.cla() 

92 plt.clf() 

93 plt.close() 

94 

95 

96def plot_mean_v_bcid( 

97 channel, 

98 x_bcid, 

99 h_bcid, 

100 h_weighted, 

101 plot_dir, 

102 info, 

103): 

104 # mean vs bcid 

105 plt.figure(figsize=(15, 4)) 

106 

107 plt.plot(x_bcid, h_weighted / h_bcid) 

108 plt.title(helper.plot_summary_string(name="Pedestal mean vs ADC BCID", info=info)) 

109 plt.xlabel("BCID") 

110 plt.ylabel("Mean ADC Counts") 

111 plt.tight_layout() 

112 plt.savefig(Path(plot_dir / f"mean_v_bcid_ch{channel}_{info.gain}.png")) 

113 plt.cla() 

114 plt.clf() 

115 plt.close() 

116 

117 

118def plot_fft_mean_v_bcid( 

119 channel, 

120 freq_bcid, 

121 psd_bcid, 

122 plot_dir, 

123 info, 

124): 

125 # FFT of mean vs bcid 

126 plt.figure(figsize=(15, 4)) 

127 

128 plt.plot(freq_bcid, psd_bcid) 

129 plt.title(helper.plot_summary_string(name="FFT of pedestal mean vs ADC BCID", info=info)) 

130 plt.xlabel("Freq. [1/BCID]") 

131 plt.ylabel("Power") 

132 plt.tight_layout() 

133 plt.savefig(Path(plot_dir / f"fft_bcid_ch{channel}_{info.gain}.png")) 

134 plt.cla() 

135 plt.clf() 

136 plt.close() 

137 

138 

139def plot_mean_v_time_ch( 

140 channel, 

141 x, 

142 y, 

143 plot_dir, 

144 info, 

145): 

146 # mean v time 

147 plt.figure(figsize=(15, 4)) 

148 plt.plot(x, y) 

149 plt.title(helper.plot_summary_string(name="Pedestal mean vs time", info=info)) 

150 plt.xlabel("Time [s]") 

151 plt.ylabel("Mean ADC Counts") 

152 plt.tight_layout() 

153 plt.savefig(Path(plot_dir / f"mean_v_time_ch{channel}_{info.gain}.png")) 

154 plt.cla() 

155 plt.clf() 

156 plt.close() 

157 

158 

159def plot_mean_v_time_ch_zoom( 

160 channel, 

161 x, 

162 y, 

163 plot_dir, 

164 info, 

165 time_window=5, # seconds 

166): 

167 cutoff = int(np.abs(time_window - x).argmin()) 

168 # mean v time zoom to first Ns 

169 plt.figure(figsize=(15, 4)) 

170 plt.plot(x[:cutoff], y[:cutoff]) 

171 plt.title(helper.plot_summary_string(name=f"Pedestal mean vs time: {time_window}s", info=info)) 

172 plt.xlabel("Time [s]") 

173 plt.ylabel("Mean ADC Counts") 

174 plt.tight_layout() 

175 plt.savefig(Path(plot_dir / f"mean_v_time_ch{channel}_{info.gain}_zoom{time_window}s.png")) 

176 plt.cla() 

177 plt.clf() 

178 plt.close() 

179 

180 

181def plot_std_v_time_ch( 

182 channel, 

183 x, 

184 y, 

185 plot_dir, 

186 info, 

187): 

188 # std v time 

189 plt.figure(figsize=(15, 4)) 

190 plt.plot(x, y) 

191 plt.title(helper.plot_summary_string(name="Pedestal std vs time", info=info)) 

192 plt.xlabel("Time [s]") 

193 plt.ylabel("Mean ADC Counts") 

194 plt.tight_layout() 

195 plt.savefig(Path(plot_dir / f"std_v_time_ch{channel}_{info.gain}.png")) 

196 plt.cla() 

197 plt.clf() 

198 plt.close() 

199 

200 

201def plot_std_v_time_ch_zoom( 

202 channel, 

203 x, 

204 y, 

205 plot_dir, 

206 info, 

207 time_window=5, # seconds 

208): 

209 cutoff = int(np.abs(time_window - x).argmin()) 

210 

211 # std v time zoom to first 5s 

212 plt.figure(figsize=(15, 4)) 

213 plt.plot(x[:cutoff], y[:cutoff]) 

214 plt.title(helper.plot_summary_string(name=f"Pedestal std vs time: {time_window}s", info=info)) 

215 plt.xlabel("Time [s]") 

216 plt.ylabel("Mean ADC Counts") 

217 plt.tight_layout() 

218 plt.savefig(Path(plot_dir / f"std_v_time_ch{channel}_{info.gain}_zoom{time_window}s.png")) 

219 plt.cla() 

220 plt.clf() 

221 plt.close() 

222 

223 

224def plot_fft_mean_v_time( 

225 channel, 

226 freq, 

227 psd, 

228 plot_dir, 

229 info, 

230): 

231 # FFT 

232 plt.figure(figsize=(15, 4)) 

233 plt.plot(freq, psd) 

234 # plt.ylim(1e-5, 15) 

235 plt.yscale("log") 

236 plt.title(helper.plot_summary_string(name="FFT of mean vs time", info=info)) 

237 plt.xlabel("Freq. [Hz]") 

238 plt.ylabel("Power") 

239 plt.tight_layout() 

240 plt.savefig(Path(plot_dir / f"fft_mean_v_time_ch{channel}_{info.gain}.png")) 

241 plt.cla() 

242 plt.clf() 

243 plt.close() 

244 

245 

246def plot_window_stds(channel, plot_dir, stds, samples_rms, info): 

247 plt.figure(figsize=(15, 4)) 

248 plt.title(helper.plot_summary_string(name="Window STD vs Total STD", info=info)) 

249 

250 bins = np.arange(0, 20, 1) 

251 _ = plt.hist(stds, bins=bins.tolist(), align="mid", edgecolor="black", label="Window STDs") 

252 

253 plt.text(0.8, 0.8, f"Window STD mu={np.mean(stds)}\nSamples STD={samples_rms}", transform=plt.gca().transAxes) 

254 

255 plt.xlabel("ADC Counts") 

256 plt.ylabel("Bin Count") 

257 

258 plt.tight_layout() 

259 plt.savefig(Path(plot_dir / f"window_std_total_std_ch{channel}_{info.gain}.png")) 

260 plt.cla() 

261 plt.clf() 

262 plt.close() 

263 

264 

265def plot_window_means(channel, plot_dir, window_means, stds, samples_rms, trigger_window, info): 

266 plt.figure(figsize=(10, 4)) 

267 plt.title(helper.plot_summary_string(name="Window Means - Global Mean", info=info)) 

268 

269 mean_of_stds = np.mean(stds) 

270 mean_of_means = np.mean(window_means) 

271 window_means -= mean_of_means 

272 

273 bins = np.arange(-10, 10, 0.2) 

274 _ = plt.hist(window_means, bins=bins.tolist(), align="mid", edgecolor="black", label="Window Means - Global Mean") 

275 

276 plt.text( 

277 0.7, 

278 0.6, 

279 f"""N Windows = {len(window_means)} 

280Window size = {trigger_window} 

281[1]: STD(Window Means) = {np.std(window_means):.2f} 

282[2]: STD(Samples) = {samples_rms:.2f} 

283[3]: Mean(Indiv. Window STD) = {mean_of_stds:.2f} 

284√([2]²-[3]²)={np.sqrt(samples_rms**2 - mean_of_stds**2):.2f} 

285""", 

286 transform=plt.gca().transAxes, 

287 ) 

288 

289 # with open("baseline_variation.csv", "a") as f: 

290 # f.write(f"{channel},{info.gain},{np.sqrt(samples_rms**2 - mean_of_stds**2):.2f}\n") 

291 

292 bin_centers = 0.5 * (bins[1:] + bins[:-1]) 

293 fit_pars = helper.calc_gaussian(window_means, bins) 

294 gauss_fit = helper.gauss(bin_centers, mu=fit_pars[0], sigma=fit_pars[2], N=fit_pars[4]) 

295 

296 plt.plot( 

297 bin_centers, 

298 gauss_fit, 

299 color="r", 

300 label=rf"""$\mu$ = {fit_pars[0]:.03f} $\pm$ {fit_pars[1]:.03f}, 

301$\sigma$ = {fit_pars[2]:.03f} $\pm$ {fit_pars[3]:.03f}""", 

302 ) 

303 plt.legend(loc="upper left") 

304 

305 plt.xlabel("ADC Counts") 

306 plt.ylabel("Bin Count") 

307 

308 plt.tight_layout() 

309 plt.savefig(Path(plot_dir / f"window_means_ch{channel}_{info.gain}.png")) 

310 plt.cla() 

311 plt.clf() 

312 plt.close()