Skip to content

Commit

Permalink
Merge pull request #35 from sofia-calgaro/main
Browse files Browse the repository at this point in the history
added std for 'per channel' style
  • Loading branch information
sofia-calgaro authored Apr 27, 2023
2 parents 95f69ae + 6c9dd08 commit a20a858
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 64 deletions.
69 changes: 54 additions & 15 deletions notebook/L200-plotting-widgets.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@
"outputs": [],
"source": [
"# ------------------------------------------------------------------------------------------ which data do you want to read? CHANGE ME!\n",
"run = \"r002\" # r000, r001, ...\n",
"run = \"r005\" # r000, r001, ...\n",
"subsystem = \"geds\" # KEEP 'geds' for the moment\n",
"folder = \"prod-ref\" # you can change me\n",
"folder = \"prod-ref-temp\" # you can change me\n",
"period = \"p03\"\n",
"version = \"\" # leave an empty string if you're looking at p03 data\n",
"\n",
Expand All @@ -51,7 +51,7 @@
"import ipywidgets as widgets\n",
"from IPython.display import display\n",
"from matplotlib import pyplot as plt\n",
"from legend_data_monitor import plot_styles, plotting\n",
"from legend_data_monitor import plot_styles, plotting, utils\n",
"\n",
"%matplotlib widget\n",
"\n",
Expand Down Expand Up @@ -122,8 +122,8 @@
"\n",
"# ------------------------------------------------------------------------------------------ get params (based on event type)\n",
"evt_type = evt_type_widget.value\n",
"params = list(shelf[\"monitoring\"][evt_type].keys())\n",
"param_widget.options = params\n",
"#params = list(shelf[\"monitoring\"][evt_type].keys())\n",
"param_widget.options = [\"cuspEmax\"]\n",
"\n",
"print(\"\\033[91mIf you change me, then RUN AGAIN the next cell!!!\\033[0m\")"
]
Expand Down Expand Up @@ -154,6 +154,19 @@
"print(f\"...data have beeng loaded!\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b836b69d-b7f5-4131-b6d5-26b637aed57b",
"metadata": {},
"outputs": [],
"source": [
"# ------------------------------------------------------------------------------------------ remove problematic dets in cal data\n",
"#df_param = df_param.set_index(\"name\")\n",
"#df_param = df_param.drop(['V01406A', 'V01415A', 'V01387A', 'P00665C', 'P00748B', 'P00748A', 'B00089D'])\n",
"#df_param = df_param.reset_index()"
]
},
{
"cell_type": "markdown",
"id": "f1c10c0f-9bed-400f-8174-c6d7e185648b",
Expand Down Expand Up @@ -190,25 +203,32 @@
"cell_type": "code",
"execution_count": null,
"id": "2122008e-2a6c-49b6-8a81-d351c1bfd57e",
"metadata": {
"tags": []
},
"metadata": {},
"outputs": [],
"source": [
"# set plotting options\n",
"plot_info[\"plot_style\"] = plot_styles_widget.value\n",
"plot_info[\"plot_structure\"] = plot_structures_widget.value\n",
"plot_info[\"resampled\"] = resampled_widget.value\n",
"plot_info[\"title\"] = \"\" # for plotting purposes\n",
"plot_info[\"subsystem\"] = \"\" # for plotting purposes\n",
"plot_info[\"std\"] = False\n",
"\n",
"df_to_plot = df_param\n",
"\n",
"# turn on the std when plotting individual channels together\n",
"if plot_info[\"plot_structure\"] == \"per channel\":\n",
" plot_info[\"std\"] = True\n",
"\n",
"if data_format_widget.value == \"absolute values\":\n",
" plot_info[\"parameter\"] = (\n",
" plot_info[\"parameter\"].split(\"_var\")[0]\n",
" if \"_var\" in plot_info[\"parameter\"]\n",
" else plot_info[\"parameter\"]\n",
" )\n",
" plot_info[\"limits\"] = utils.PLOT_INFO[plot_info[\"parameter\"]][\"limits\"][subsystem][\"absolute\"]\n",
" plot_info[\"unit_label\"] = plot_info[\"unit\"]\n",
" if plot_info[\"parameter\"] not in df_param:\n",
" if plot_info[\"parameter\"] not in df_to_plot:\n",
" print(\"There is no\", plot_info[\"parameter\"])\n",
" sys.exit(\"Stopping notebook.\")\n",
"if data_format_widget.value == \"% values\":\n",
Expand All @@ -217,8 +237,9 @@
" if \"_var\" in plot_info[\"parameter\"]\n",
" else plot_info[\"parameter\"] + \"_var\"\n",
" )\n",
" plot_info[\"limits\"] = utils.PLOT_INFO[plot_info[\"parameter\"].split(\"_var\")[0]][\"limits\"][subsystem][\"variation\"]\n",
" plot_info[\"unit_label\"] = \"%\"\n",
" if plot_info[\"parameter\"] not in df_param:\n",
" if plot_info[\"parameter\"] not in df_to_plot:\n",
" print(\"There is no\", plot_info[\"parameter\"])\n",
" sys.exit(\"Stopping notebook.\")\n",
"\n",
Expand All @@ -227,20 +248,20 @@
" for string in [1, 2, 3, 4, 5, 7, 8, 9, 10, 11]:\n",
" if plot_structures_widget.value == \"per channel\":\n",
" plotting.plot_per_ch(\n",
" df_param[df_param[\"location\"] == string], plot_info, \"\"\n",
" df_to_plot[df_to_plot[\"location\"] == string], plot_info, \"\"\n",
" ) # plot one canvas per channel\n",
" elif plot_structures_widget.value == \"per string\":\n",
" plotting.plot_per_string(\n",
" df_param[df_param[\"location\"] == string], plot_info, \"\"\n",
" df_to_plot[df_to_plot[\"location\"] == string], plot_info, \"\"\n",
" ) # plot one canvas per string\n",
"else: # let's get one string in output\n",
" if plot_structures_widget.value == \"per channel\":\n",
" plotting.plot_per_ch(\n",
" df_param[df_param[\"location\"] == strings_widget.value], plot_info, \"\"\n",
" df_to_plot[df_to_plot[\"location\"] == strings_widget.value], plot_info, \"\"\n",
" ) # plot one canvas per channel\n",
" elif plot_structures_widget.value == \"per string\":\n",
" plotting.plot_per_string(\n",
" df_param[df_param[\"location\"] == strings_widget.value], plot_info, \"\"\n",
" df_to_plot[df_to_plot[\"location\"] == strings_widget.value], plot_info, \"\"\n",
" ) # plot one canvas per string"
]
},
Expand Down Expand Up @@ -279,7 +300,25 @@
]
}
],
"metadata": {},
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
27 changes: 25 additions & 2 deletions src/legend_data_monitor/plot_styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from matplotlib.axes import Axes
from matplotlib.dates import DateFormatter, date2num, num2date
from matplotlib.figure import Figure
from pandas import DataFrame, Timedelta
from pandas import DataFrame, Timedelta, concat

from . import utils

Expand Down Expand Up @@ -39,6 +39,7 @@ def plot_vs_time(
data_channel[plot_info["parameter"]],
zorder=0,
color=all_col,
linewidth=1,
)

# -------------------------------------------------------------------------
Expand All @@ -48,6 +49,7 @@ def plot_vs_time(
if plot_info["resampled"] != "no":
# unless event rate - already resampled and counted in some time window
if not plot_info["parameter"] == "event_rate":
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1 - resampling
# resample in given time window, as start pick the first timestamp in table
resampled = (
data_channel.set_index("datetime")
Expand All @@ -67,10 +69,26 @@ def plot_vs_time(
resampled[plot_info["parameter"]],
color=res_col,
zorder=1,
marker="o",
#marker="o",
linestyle="-",
)

# evaluation of std bands, if enabled
if plot_info["std"] is True:
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 2 - std evaluation
std_data = (
data_channel.set_index("datetime")
.resample(plot_info["time_window"], origin="start")
.std(numeric_only=True)
)
std_data = std_data.reset_index()

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 3 - appending std to the resampled dataframe
std_data = std_data.rename(columns={plot_info["parameter"] : "std"})
new_dataframe = concat([resampled, std_data[['std']]], ignore_index=False, axis=1)

ax.fill_between(resampled["datetime"].dt.to_pydatetime(), resampled[plot_info["parameter"]] - new_dataframe['std'], resampled[plot_info["parameter"]] + new_dataframe['std'], alpha=0.25, color=res_col)

# -------------------------------------------------------------------------
# beautification
# -------------------------------------------------------------------------
Expand Down Expand Up @@ -222,6 +240,11 @@ def plot_scatter(
)
fig.supylabel(y_label)

# plot the position of the two K lines
if plot_info["parameter"] == "K_events":
ax.axhline(y=1460.822, color="gray", linestyle="--")
ax.axhline(y=1524.6, color="gray", linestyle="--")

# saving x,y data into output files
ch_dict = {
"values": {"all": data_channel[plot_info["parameter"]], "resampled": []},
Expand Down
78 changes: 39 additions & 39 deletions src/legend_data_monitor/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ def make_subsystem_plots(
plot_settings["resampled"] if "resampled" in plot_settings else ""
)

# information for shifting the channels or not (not needed only for the 'per channel' structure option) when plotting the std
plot_info["std"] = True if plot_settings["plot_structure"] == "per channel" else False

if plot_settings["plot_style"] == "vs time":
if plot_info["resampled"] == "":
plot_info["resampled"] = "also"
Expand Down Expand Up @@ -312,9 +315,8 @@ def plot_per_ch(data_analysis: DataFrame, plot_info: dict, pdf: PdfPages):
# remove automatic y label since there will be a shared one
axes[ax_idx].set_ylabel("")

# plot line at 0% for variation
if plot_info["unit_label"] == "%":
axes[ax_idx].axhline(y=0, color="gray", linestyle="--")
# plot limits
plot_limits(axes[ax_idx], plot_info["limits"])

ax_idx += 1

Expand All @@ -327,10 +329,7 @@ def plot_per_ch(data_analysis: DataFrame, plot_info: dict, pdf: PdfPages):
axes[0].set_title(f"{plot_info['locname']} {location}")
fig.suptitle(f"{plot_info['subsystem']} - {plot_info['title']}", y=y_title)

if pdf:
plt.savefig(pdf, format="pdf", bbox_inches="tight")
# figures are retained until explicitly closed; close to not consume too much memory
plt.close()
save_pdf(plt, pdf)

return fig

Expand Down Expand Up @@ -403,28 +402,20 @@ def plot_per_cc4(data_analysis: DataFrame, plot_info: dict, pdf: PdfPages):
axes[ax_idx].set_ylabel("")
axes[ax_idx].legend(labels=labels, loc="center left", bbox_to_anchor=(1, 0.5))

# plot the position of the two K lines
if plot_info["parameter"] == "K_events":
axes[ax_idx].axhline(y=1460.822, color="gray", linestyle="--")
axes[ax_idx].axhline(y=1524.6, color="gray", linestyle="--")
# plot limits
plot_limits(axes[ax_idx], plot_info["limits"])

# plot line at 0% for variation
if plot_info["unit_label"] == "%":
axes[ax_idx].axhline(y=0, color="gray", linestyle="--")
ax_idx += 1

# -------------------------------------------------------------------------------
y_title = 1.05 if plot_info["subsystem"] == "pulser" else 1.01
fig.suptitle(f"{plot_info['subsystem']} - {plot_info['title']}", y=y_title)
# if no pdf is specified, then the function is not being called by make_subsystem_plots()
if pdf:
plt.savefig(pdf, format="pdf", bbox_inches="tight")
# figures are retained until explicitly closed; close to not consume too much memory
plt.close()
save_pdf(plt, pdf)

return fig


import numpy as np
def plot_per_string(data_analysis: DataFrame, plot_info: dict, pdf: PdfPages):
# --- choose plot function based on user requested style e.g. vs time or histogram
plot_style = plot_styles.PLOT_STYLE[plot_info["plot_style"]]
Expand Down Expand Up @@ -481,8 +472,13 @@ def plot_per_string(data_analysis: DataFrame, plot_info: dict, pdf: PdfPages):
col_idx = 0
labels = []
for label, data_channel in data_location.groupby("label"):
entries = data_channel[plot_info["parameter"]]
entries_avg = np.mean(entries)
rms_ch = np.sqrt(np.mean(np.square(entries - entries_avg)))
FWHM_ch = 2.355*rms_ch

_ = plot_style(data_channel, fig, axes[ax_idx], plot_info, COLORS[col_idx])
labels.append(label)
labels.append(label+f" - FWHM: {round(FWHM_ch, 2)}")
col_idx += 1

# add grid
Expand All @@ -493,25 +489,16 @@ def plot_per_string(data_analysis: DataFrame, plot_info: dict, pdf: PdfPages):
axes[ax_idx].set_ylabel("")
axes[ax_idx].legend(labels=labels, loc="center left", bbox_to_anchor=(1, 0.5))

# plot the position of the two K lines
if plot_info["parameter"] == "K_events":
axes[ax_idx].axhline(y=1460.822, color="gray", linestyle="--")
axes[ax_idx].axhline(y=1524.6, color="gray", linestyle="--")
# plot limits
plot_limits(axes[ax_idx], plot_info["limits"])

# plot line at 0% for variation
if plot_info["unit_label"] == "%":
axes[ax_idx].axhline(y=0, color="gray", linestyle="--")
ax_idx += 1

# -------------------------------------------------------------------------------
y_title = 1.05 if plot_info["subsystem"] == "pulser" else 1.01
fig.suptitle(f"{plot_info['subsystem']} - {plot_info['title']}", y=y_title)

# if no pdf is specified, then the function is not being called by make_subsystem_plots()
if pdf:
plt.savefig(pdf, format="pdf", bbox_inches="tight")
# figures are retained until explicitly closed; close to not consume too much memory
plt.close()
save_pdf(plt, pdf)

return fig

Expand Down Expand Up @@ -637,14 +624,9 @@ def plot_array(data_analysis: DataFrame, plot_info: dict, pdf: PdfPages):
fig.supxlabel("")
fig.suptitle(f"{plot_info['subsystem']} - {plot_info['title']}", y=1.05)

# -------------------------------------------------------------------------------
# if no pdf is specified, then the function is not being called by make_subsystem_plots()
if pdf:
plt.savefig(pdf, format="pdf", bbox_inches="tight")
# figures are retained until explicitly closed; close to not consume too much memory
plt.close()
save_pdf(plt, pdf)

# return fig
return fig


# -------------------------------------------------------------------------------
Expand Down Expand Up @@ -803,6 +785,24 @@ def plot_per_barrel_and_position(

return par_dict

# -------------------------------------------------------------------------------
# plotting functions
# -------------------------------------------------------------------------------

def plot_limits(ax: plt.Axes, limits: dict):
"""Plot limits (if present) on the plot."""
if not all([x is None for x in limits]):
if limits[0] is not None:
ax.axhline(y=limits[0], color="red", linestyle="--")
if limits[1] is not None:
ax.axhline(y=limits[1], color="red", linestyle="--")

def save_pdf(plt, pdf: PdfPages):
"""Save the plot to a PDF file. The plot is closed after saving."""
if pdf:
plt.savefig(pdf, format="pdf", bbox_inches="tight")
plt.close()


# -------------------------------------------------------------------------------
# mapping user keywords to plot style functions
Expand Down
Loading

0 comments on commit a20a858

Please sign in to comment.