Skip to content
Snippets Groups Projects

Speed-up plotting routines

Merged Laurent Petre requested to merge bugfix/speed-up-plotting-routines into main
Files
2
"""DAC scan routines"""
"""
 
@file dac_scan_analysis.py
 
@author Antonello Pellecchia (antonello.pallecchia@cern.ch)
 
@brief DAC scan routines
 
@date 2022-12-06
 
"""
 
__author__ = "Antonello Pellecchia"
 
__maintainer__ = ["Camilla Galloni, Laurent Petre", "Daniel Estrada"]
from enum import Enum
import os
 
import os
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
 
import gc
import mplhep
import mplhep
import numpy as np
import pandas as pd
import pandas as pd
 
from numpy import ceil, argmin
 
from enum import Enum
 
from multiprocessing import cpu_count, Pool
from gemos.analysis.vfat_calibrations import add_parameters
from gemos.analysis.vfat_calibrations import add_parameters
@@ -96,7 +105,7 @@ def analyze_scan(input_df):
@@ -96,7 +105,7 @@ def analyze_scan(input_df):
nominal_value = NOMINAL_DAC_VALUES[dac_name][0]
nominal_value = NOMINAL_DAC_VALUES[dac_name][0]
# Calculate chosen ADC value as closest to nominal DAC value
# Calculate chosen ADC value as closest to nominal DAC value
chosen_index = np.argmin(abs(adc_values - nominal_value))
chosen_index = argmin(abs(adc_values - nominal_value))
chosen_dac = dac_values[chosen_index]
chosen_dac = dac_values[chosen_index]
# Issue warnings
# Issue warnings
@@ -129,57 +138,50 @@ def analyze_scan(input_df):
@@ -129,57 +138,50 @@ def analyze_scan(input_df):
return pd.DataFrame.from_records(output_list).astype(int, errors="ignore")
return pd.DataFrame.from_records(output_list).astype(int, errors="ignore")
def plot_scan(input_df, output_df, output_dir):
def plot_scan(vfat_group, output_df, output_dir):
"""Plot all DAC rate scans"""
"""Plot all DAC rate scans"""
 
(fed, slot, oh, vfat), vfat_df = vfat_group
output_df = output_df.set_index(["fed", "slot", "oh", "vfat", "dac-name"]).sort_index()
dac_group = vfat_df.groupby("dac-name")
vfat_group = input_df.groupby(["fed", "slot", "oh", "vfat"])
for (fed, slot, oh, vfat), vfat_df in vfat_group:
# Prepare figure for plotting
dac_group = vfat_df.groupby("dac-name")
nrows, ncols = 3, int(ceil(len(dac_group) / 3))
 
dac_scan_fig, dac_scan_axs = plt.subplots(nrows, ncols, figsize=(55, 25))
 
dac_scan_axs = dac_scan_axs.flat
# Prepare figure for plotting
# Plot all DAC
nrows, ncols = 3, int(np.ceil(len(dac_group) / 3))
for group_index, (dac_name, dac_df) in enumerate(dac_group):
dac_scan_fig, dac_scan_axs = plt.subplots(nrows, ncols, figsize=(55, 25))
# Plot DAC scan for current VFAT and register
dac_scan_axs = dac_scan_axs.flat
dac_scan_axs[group_index].set_xlabel("DAC units")
 
dac_scan_axs[group_index].set_ylabel(f"{dac_name} ({NOMINAL_DAC_VALUES[dac_name][1]})")
# Plot all DAC
dac_scan_axs[group_index].plot(dac_df["dac-value"], dac_df["adc-value"], ".", color="black")
for group_index, (dac_name, dac_df) in enumerate(dac_group):
# Plot DAC scan for current VFAT and register
dac_scan_axs[group_index].set_xlabel("DAC units")
dac_scan_axs[group_index].set_ylabel(f"{dac_name} ({NOMINAL_DAC_VALUES[dac_name][1]})")
dac_scan_axs[group_index].plot(
# Draw line pointing to set DAC value
dac_df["dac-value"], dac_df["adc-value"], ".", color="black"
nominal_value = NOMINAL_DAC_VALUES[dac_name][0]
)
chosen_dac = output_df.loc[(fed, slot, oh, vfat, dac_name), "dac-value"]
# Draw line pointing to set DAC value
nominal_value = NOMINAL_DAC_VALUES[dac_name][0]
chosen_dac = output_df.loc[(fed, slot, oh, vfat, dac_name), "dac-value"]
dac_scan_axs[group_index].plot(
dac_scan_axs[group_index].plot(
[chosen_dac, chosen_dac],
[chosen_dac, chosen_dac],
[min(dac_df["adc-value"]), nominal_value],
[min(dac_df["adc-value"]), nominal_value],
"--",
"--",
color="blue",
color="blue",
)
)
dac_scan_axs[group_index].plot(
dac_scan_axs[group_index].plot(
[min(dac_df["dac-value"]), chosen_dac],
[min(dac_df["dac-value"]), chosen_dac],
[nominal_value, nominal_value],
[nominal_value, nominal_value],
"--",
"--",
color="blue",
color="blue",
)
)
# Save the figure
# Save the figure
output_figure = "{}/fed{}-slot{}-oh{}-vfat{}.png".format(output_dir, fed, slot, oh, vfat)
output_figure = "{}/fed{}-slot{}-oh{}-vfat{}.png".format(output_dir, fed, slot, oh, vfat)
dac_scan_fig.savefig(output_figure)
dac_scan_fig.savefig(output_figure)
print("Scan plot saved to {}".format(output_figure))
print("Scan plot saved to {}".format(output_figure))
# Delete the figure
# Make sure to keep the memory usage reasonable
# FIXME: Reuse the figure
plt.close(dac_scan_fig)
plt.close(dac_scan_fig)
gc.collect()
del dac_scan_fig
def create_configuration(
def create_configuration(
@@ -225,6 +227,23 @@ def create_configuration(
@@ -225,6 +227,23 @@ def create_configuration(
# Plot!
# Plot!
os.makedirs("{}/plots".format(output_dir), exist_ok=True)
os.makedirs("{}/plots".format(output_dir), exist_ok=True)
plot_scan(input_df, output_df, output_dir / "plots")
 
output_df = output_df.set_index(["fed", "slot", "oh", "vfat", "dac-name"]).sort_index()
 
 
pool = Pool(cpu_count())
 
 
for vfat_group in input_df.groupby(["fed", "slot", "oh", "vfat"]):
 
# one image per vfat
 
pool.apply_async(
 
plot_scan,
 
args=(
 
vfat_group,
 
output_df,
 
output_dir / "plots",
 
),
 
)
 
 
pool.close()
 
pool.join()
return output_filename
return output_filename
Loading