diff --git a/src/leds/core.py b/src/leds/core.py index daa72b0..4c523b1 100644 --- a/src/leds/core.py +++ b/src/leds/core.py @@ -77,7 +77,12 @@ class Waveform_window(QWidget): def __init__(self, browsers, ev): super().__init__() - uic.loadUi(os.path.join(os.path.dirname(__file__,"layouts/legend_waveform_display.ui")), self) + uic.loadUi( + os.path.join( + os.path.dirname(__file__, "layouts/legend_waveform_display.ui") + ), + self, + ) self.browsers = browsers self.ev = ev @@ -148,7 +153,10 @@ class MainWindow(QtWidgets.QMainWindow): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - uic.loadUi(os.path.join(os.path.dirname(__file__,"layouts/legend_event_display2.ui")), self) + uic.loadUi( + os.path.join(os.path.dirname(__file__, "layouts/legend_event_display2.ui")), + self, + ) # Create the maptlotlib FigureCanvas object, # which defines a single set of axes as self.axes. self.canvas = MplCanvas(self, width=10, height=10, dpi=100) diff --git a/src/leds/event_viewer.py b/src/leds/event_viewer.py index 5dc24b5..9466e56 100644 --- a/src/leds/event_viewer.py +++ b/src/leds/event_viewer.py @@ -1,115 +1,138 @@ +from __future__ import annotations + +import glob import math -import os, json +import os + import lgdo.lh5_store as lh5 +import matplotlib as mpl import numpy as np from legendmeta import LegendMetadata from legendmeta.catalog import Props -from matplotlib.colors import LogNorm -import pandas as pd -import glob -import sys -import matplotlib as mpl -mpl.use('Qt5Agg') +mpl.use("Qt5Agg") import matplotlib.pyplot as plt from matplotlib.collections import PatchCollection -import matplotlib.patches as mpatches - from utils import * -sto=lh5.LH5Store() +sto = lh5.LH5Store() + def is_coax(d): - return d['type'] == 'coax' + return d["type"] == "coax" + def is_taper(f): - return f != {'angle_in_deg': 0, 'height_in_mm': 0} and f != {'radius_in_mm': 0, 'height_in_mm': 0} + return f != {"angle_in_deg": 0, "height_in_mm": 0} and f != { + "radius_in_mm": 0, + "height_in_mm": 0, + } + def is_bulletized(f): - return 'bulletization' in f and f['bulletization'] != {'top_radius_in_mm': 0, 'bottom_radius_in_mm': 0, 'borehole_radius_in_mm': 0, 'contact_radius_in_mm': 0} + return "bulletization" in f and f["bulletization"] != { + "top_radius_in_mm": 0, + "bottom_radius_in_mm": 0, + "borehole_radius_in_mm": 0, + "contact_radius_in_mm": 0, + } + def has_groove(f): - return 'groove' in f and f['groove'] != {'outer_radius_in_mm': 0, 'depth_in_mm': 0, 'width_in_mm': 0} + return "groove" in f and f["groove"] != { + "outer_radius_in_mm": 0, + "depth_in_mm": 0, + "width_in_mm": 0, + } + def has_borehole(f): - return 'borehole' in f and f['borehole'] != {'gap_in_mm': 0, 'radius_in_mm': 0} + return "borehole" in f and f["borehole"] != {"gap_in_mm": 0, "radius_in_mm": 0} + def plot_geometry(d, R, H): - coax = is_coax(d) - - g = d['geometry'] - - DH = g['height_in_mm'] - DR = g['radius_in_mm'] + + g = d["geometry"] + + DH = g["height_in_mm"] + DR = g["radius_in_mm"] xbot = [] ybot = [] # botout = g['taper']['bottom']['outer'] - botout = g['taper']['bottom'] + botout = g["taper"]["bottom"] if is_taper(botout): - TH = botout['height_in_mm'] - TR = botout['radius_in_mm'] if 'radius_in_mm' in botout else TH * math.sin(botout['angle_in_deg'] * math.pi/180) - xbot.extend([DR, DR-TR]) - ybot.extend([H-DH+TH,H-DH]) + TH = botout["height_in_mm"] + TR = ( + botout["radius_in_mm"] + if "radius_in_mm" in botout + else TH * math.sin(botout["angle_in_deg"] * math.pi / 180) + ) + xbot.extend([DR, DR - TR]) + ybot.extend([H - DH + TH, H - DH]) else: xbot.append(DR) - ybot.append(H-DH) + ybot.append(H - DH) if has_groove(g): # GR = g['groove']['outer_radius_in_mm'] - GR = g['groove']['radius_in_mm']['outer'] - GH = g['groove']['depth_in_mm'] + GR = g["groove"]["radius_in_mm"]["outer"] + GH = g["groove"]["depth_in_mm"] # GW = g['groove']['width_in_mm'] - GW = g['groove']['radius_in_mm']['outer'] - g['groove']['radius_in_mm']['inner'] - xbot.extend([GR,GR,GR-GW,GR-GW]) - ybot.extend([H-DH,H-DH+GH,H-DH+GH,H-DH]) - + GW = g["groove"]["radius_in_mm"]["outer"] - g["groove"]["radius_in_mm"]["inner"] + xbot.extend([GR, GR, GR - GW, GR - GW]) + ybot.extend([H - DH, H - DH + GH, H - DH + GH, H - DH]) + if coax: - BG = g['borehole']['depth_in_mm'] - BR = g['borehole']['radius_in_mm'] + BG = g["borehole"]["depth_in_mm"] + BR = g["borehole"]["radius_in_mm"] xbot.extend([BR, BR]) - ybot.extend([H-DH, H-DH+BG]) - + ybot.extend([H - DH, H - DH + BG]) xtop = [] ytop = [] # topout = g['taper']['top']['outer'] - topout = g['taper']['top'] + topout = g["taper"]["top"] if is_taper(topout): - TH = topout['height_in_mm'] - TR = TH * math.sin(topout['angle_in_deg'] * math.pi/180) - xtop.extend([DR, DR-TR]) - ytop.extend([H-TH, H]) + TH = topout["height_in_mm"] + TR = TH * math.sin(topout["angle_in_deg"] * math.pi / 180) + xtop.extend([DR, DR - TR]) + ytop.extend([H - TH, H]) else: xtop.append(DR) ytop.append(H) if has_borehole(g) and not coax: - BG = g['borehole']['depth_in_mm'] - BR = g['borehole']['radius_in_mm'] + BG = g["borehole"]["depth_in_mm"] + BR = g["borehole"]["radius_in_mm"] # topin = g['taper']['top']['inner'] - topin = g['taper']['top'] + topin = g["taper"]["top"] if is_taper(topin): - TH = topin['height_in_mm'] - TR = TH * math.sin(topin['angle_in_deg'] * math.pi/180) - xtop.extend([BR+TR,BR,BR]) - ytop.extend([H, H-TH, H-DH+BG]) + TH = topin["height_in_mm"] + TR = TH * math.sin(topin["angle_in_deg"] * math.pi / 180) + xtop.extend([BR + TR, BR, BR]) + ytop.extend([H, H - TH, H - DH + BG]) else: xtop.extend([BR, BR]) - ytop.extend([H, H-DH+BG]) - - - x = np.hstack(([-x+R for x in xbot], [x+R for x in xbot[::-1]],[x + R for x in xtop],[-x+R for x in xtop[::-1]])) - y = np.hstack((ybot, ybot[::-1],ytop,ytop[::-1])) + ytop.extend([H, H - DH + BG]) + + x = np.hstack( + ( + [-x + R for x in xbot], + [x + R for x in xbot[::-1]], + [x + R for x in xtop], + [-x + R for x in xtop[::-1]], + ) + ) + y = np.hstack((ybot, ybot[::-1], ytop, ytop[::-1])) return x, y -def get_plot_source_and_xlabels(chan_dict, channel_map, strings_dict, ΔR = 160, ΔH = 40): - +def get_plot_source_and_xlabels(chan_dict, channel_map, strings_dict, ΔR=160, ΔH=40): xs = [] ys = [] ch = [] @@ -125,181 +148,223 @@ def get_plot_source_and_xlabels(chan_dict, channel_map, strings_dict, ΔR = 160, R = 0 H = 0 - xlabels = dict() - - for (name, string) in strings_dict.items(): + xlabels = {} + for name, string in strings_dict.items(): xlabels[R] = name for channel_no in string: ch.append(channel_no) - status = chan_dict[channel_map[channel_no]['name']] - hw.append(status['usability']) - sw.append(status['processable']) + status = chan_dict[channel_map[channel_no]["name"]] + hw.append(status["usability"]) + sw.append(status["processable"]) channel = channel_map[channel_no] - dn.append(channel['name']) - st.append(channel['location']['string']) - pos.append(channel['location']['position']) - x,y = plot_geometry(channel, R, H) + dn.append(channel["name"]) + st.append(channel["location"]["string"]) + pos.append(channel["location"]["position"]) + x, y = plot_geometry(channel, R, H) xs.append(x) ys.append(y) - H -= channel['geometry']['height_in_mm'] + ΔH + H -= channel["geometry"]["height_in_mm"] + ΔH ax.append(R) - ay.append(H+10) + ay.append(H + 10) R += ΔR maxH = min(H, maxH) H = 0 - return xs, ys + return xs, ys + -def plt_detector_plot(fig, axes, patches, display_dict, - ctitle = "", plot_title = "LEGEND event view" - ): - - minvalue = 25; maxvalue = 6000 +def plt_detector_plot( + fig, axes, patches, display_dict, ctitle="", plot_title="LEGEND event view" +): + minvalue = 25 + maxvalue = 6000 cNorm = mpl.colors.Normalize(vmin=25, vmax=4000) - vir = mpl.colormaps['viridis'] + vir = mpl.colormaps["viridis"] vir.set_under("grey") vir.set_bad("white") - + cNorm = mpl.colors.Normalize(vmin=25, vmax=4000) - - p = PatchCollection(patches, cmap = vir) - p.set_array(np.array(list(map(lambda v : np.nan if v is None or math.isnan(v) else v, display_dict.values())))) + + p = PatchCollection(patches, cmap=vir) + p.set_array( + np.array( + [np.nan if v is None or math.isnan(v) else v for v in display_dict.values()] + ) + ) p.set_ec("black") p.set_norm(cNorm) - + axes.add_collection(p) - axes.spines['top'].set_visible(False) - axes.spines['bottom'].set_visible(False) - axes.spines['right'].set_visible(False) - axes.spines['left'].set_visible(False) - - # if fig.first_call == True: - plt.colorbar(p, ax=axes, label= ctitle) - axes.set_xlim([-100,1500]) - axes.set_ylim([-1200,30]) + axes.spines["top"].set_visible(False) + axes.spines["bottom"].set_visible(False) + axes.spines["right"].set_visible(False) + axes.spines["left"].set_visible(False) + + # if fig.first_call == True: + plt.colorbar(p, ax=axes, label=ctitle) + axes.set_xlim([-100, 1500]) + axes.set_ylim([-1200, 30]) axes.set_title(plot_title) axes.set_yticks([]) axes.set_xticks([]) - - -class event_viewer(): - - +class event_viewer: def __init__(self, fig): - self.fig=fig - self.prod_cycle = f"/data2/public/prodenv/prod-blind/ref/v01.06"#os.cwd() - self.config = Props.read_from(os.path.join(self.prod_cycle,"config.json"), - subst_pathvar={"$":self.prod_cycle})["setups"]["l200"]["paths"] + self.fig = fig + self.prod_cycle = "/data2/public/prodenv/prod-blind/ref/v01.06" # os.cwd() + self.config = Props.read_from( + os.path.join(self.prod_cycle, "config.json"), + subst_pathvar={"$": self.prod_cycle}, + )["setups"]["l200"]["paths"] self.meta = LegendMetadata(self.config["metadata"]) self.raw_file, self.dsp_file, self.hit_file = (None, None, None) self.strings_dict = {} - self.events_per_file_cache={} - self.baseline_channels={} + self.events_per_file_cache = {} + self.baseline_channels = {} - def get_phy_event_position(self, period, run, file_tstamp, idx): - - file_path = os.path.join(self.config["tier_hit"], - f"phy/{period}/{run}/l200-{period}-{run}-phy-{file_tstamp}-tier_hit.lh5") + file_path = os.path.join( + self.config["tier_hit"], + f"phy/{period}/{run}/l200-{period}-{run}-phy-{file_tstamp}-tier_hit.lh5", + ) files = sorted(glob.glob(file_path)) - events_per_file = [] + events_per_file = [] for file in files: if file in list(self.events_per_file_cache): - events_per_file.append(self.events_per_file_cache[file]) + events_per_file.append(self.events_per_file_cache[file]) else: - _,per,_,_,tstamp,_ = os.path.basename(file).split("-") + _, per, _, _, tstamp, _ = os.path.basename(file).split("-") if per not in list(self.baseline_channels): - self.baseline_channels[per] = self.meta.channelmap(tstamp)["BSLN01"].daq.rawid - + self.baseline_channels[per] = self.meta.channelmap(tstamp)[ + "BSLN01" + ].daq.rawid + baseline_channel = self.baseline_channels[per] - n_events = sto.read_n_rows(f"ch{baseline_channel}/raw/baseline", - file.replace(self.config["tier_hit"], - self.config["tier_raw"]).replace("hit", "raw")) + n_events = sto.read_n_rows( + f"ch{baseline_channel}/raw/baseline", + file.replace( + self.config["tier_hit"], self.config["tier_raw"] + ).replace("hit", "raw"), + ) events_per_file.append(n_events) self.events_per_file_cache[file] = n_events - if np.cumsum(events_per_file)[-1]>idx: + if np.cumsum(events_per_file)[-1] > idx: break cum_events = np.cumsum(events_per_file) - file_n = np.argmin(np.where((cum_events-idx)>0, cum_events, np.inf)) - if file_n >0: - start_r = idx-cum_events[file_n-1] - else: - start_r = idx + file_n = np.argmin(np.where((cum_events - idx) > 0, cum_events, np.inf)) + start_r = idx - cum_events[file_n - 1] if file_n > 0 else idx file = files[file_n] - return (file.replace(self.config["tier_hit"], self.config["tier_raw"]).replace("hit", "raw"), - file.replace(self.config["tier_hit"], self.config["tier_dsp"]).replace("hit", "dsp"), - file, start_r) - + return ( + file.replace(self.config["tier_hit"], self.config["tier_raw"]).replace( + "hit", "raw" + ), + file.replace(self.config["tier_hit"], self.config["tier_dsp"]).replace( + "hit", "dsp" + ), + file, + start_r, + ) + def _get_event(self, period, run, file_tstamp, idx): - self.raw_file, self.dsp_file, self.hit_file, self.index = self.get_phy_event_position(period, run, file_tstamp, idx) + ( + self.raw_file, + self.dsp_file, + self.hit_file, + self.index, + ) = self.get_phy_event_position(period, run, file_tstamp, idx) self.chmap = self.meta.channelmap(os.path.basename(self.hit_file).split("-")[4]) self.dets = self.chmap.map("system", unique=False).geds.map("name") - self.working_dets = [det for det in self.dets if self.chmap[det]["analysis"]["processable"] == True] - self.energy_dict = {det : sto.read_object(f'ch{self.chmap[det].daq.rawid}/hit/cuspEmax_ctc_cal', - self.hit_file, start_row = self.index, n_rows=1)[0].nda[0] - if det in self.working_dets else None - for det in self.dets } + self.working_dets = [ + det + for det in self.dets + if self.chmap[det]["analysis"]["processable"] is True + ] + self.energy_dict = { + det: sto.read_object( + f"ch{self.chmap[det].daq.rawid}/hit/cuspEmax_ctc_cal", + self.hit_file, + start_row=self.index, + n_rows=1, + )[0].nda[0] + if det in self.working_dets + else None + for det in self.dets + } for key, item in self.energy_dict.items(): if item is None: pass elif np.isnan(item): - self.energy_dict[key] = 0 + self.energy_dict[key] = 0 def plot_event(self, period, run, file_tstamp, idx): self._get_event(period, run, file_tstamp, idx) - - strings_dict, chan_dict, channel_map = sorter(self.prod_cycle, os.path.basename(self.hit_file).split("-")[4]) + + strings_dict, chan_dict, channel_map = sorter( + self.prod_cycle, os.path.basename(self.hit_file).split("-")[4] + ) if strings_dict == self.strings_dict: - self.p.set_array(np.array(list(map(lambda v : np.nan if v is None or math.isnan(v) else v, self.energy_dict.values())))) - self.axes.set_title(f'file:{os.path.basename(self.hit_file).split("-tier")[0]} idx:{self.index}') + self.p.set_array( + np.array( + [np.nan if v is None or math.isnan(v) else v for v in self.energy_dict.values()] + ) + ) + self.axes.set_title( + f'file:{os.path.basename(self.hit_file).split("-tier")[0]} idx:{self.index}' + ) else: self.strings_dict = strings_dict - xs,ys = get_plot_source_and_xlabels(chan_dict, channel_map, self.strings_dict, ΔR = 160, ΔH = 40) + xs, ys = get_plot_source_and_xlabels( + chan_dict, channel_map, self.strings_dict, ΔR=160, ΔH=40 + ) patches = [] - for x,y in zip(xs,ys): + for x, y in zip(xs, ys): coords = [] for i in range(len(x)): - coords.append([x[i],y[i]]) + coords.append([x[i], y[i]]) polygon = plt.Polygon(coords, True, edgecolor="black") patches.append(polygon) self.fig.clf() self.axes = self.fig.add_subplot(111) - self.plt_detector_plot(patches, ctitle = "energy (keV)", plot_title = f'file:{os.path.basename(self.hit_file).split("-tier")[0]} idx:{self.index}') + self.plt_detector_plot( + patches, + ctitle="energy (keV)", + plot_title=f'file:{os.path.basename(self.hit_file).split("-tier")[0]} idx:{self.index}', + ) self.fig.canvas.draw() - - def plt_detector_plot(self, patches, - ctitle = "", plot_title = "LEGEND event view" - ): - - minvalue = 25; maxvalue = 6000 + + def plt_detector_plot(self, patches, ctitle="", plot_title="LEGEND event view"): + minvalue = 25 + maxvalue = 6000 cNorm = mpl.colors.Normalize(vmin=25, vmax=4000) - vir = mpl.colormaps['viridis'] + vir = mpl.colormaps["viridis"] vir.set_under("grey") vir.set_bad("white") cNorm = mpl.colors.Normalize(vmin=25, vmax=4000) - self.p = PatchCollection(patches, cmap = vir) - self.p.set_array(np.array(list(map(lambda v : np.nan if v is None or math.isnan(v) else v, self.energy_dict.values())))) + self.p = PatchCollection(patches, cmap=vir) + self.p.set_array( + np.array( + [np.nan if v is None or math.isnan(v) else v for v in self.energy_dict.values()] + ) + ) self.p.set_ec("black") self.p.set_norm(cNorm) self.axes.add_collection(self.p) - self.axes.spines['top'].set_visible(False) - self.axes.spines['bottom'].set_visible(False) - self.axes.spines['right'].set_visible(False) - self.axes.spines['left'].set_visible(False) - - # if fig.first_call == True: - self.fig.colorbar(self.p, ax=self.axes, label= ctitle) - self.axes.set_xlim([-100,1500]) - self.axes.set_ylim([-1200,30]) + self.axes.spines["top"].set_visible(False) + self.axes.spines["bottom"].set_visible(False) + self.axes.spines["right"].set_visible(False) + self.axes.spines["left"].set_visible(False) + + # if fig.first_call == True: + self.fig.colorbar(self.p, ax=self.axes, label=ctitle) + self.axes.set_xlim([-100, 1500]) + self.axes.set_ylim([-1200, 30]) self.axes.set_title(plot_title) self.axes.set_yticks([]) self.axes.set_xticks([]) - \ No newline at end of file diff --git a/src/leds/utils.py b/src/leds/utils.py index 4b1d807..ea9a6ca 100644 --- a/src/leds/utils.py +++ b/src/leds/utils.py @@ -1,43 +1,51 @@ -import math -import os, json -import numpy as np +from __future__ import annotations + +import os + from legendmeta import LegendMetadata from legendmeta.catalog import Props -import pandas as pd -import glob -import sys def sorter(path, timestamp, key="String", datatype="cal", spms=False): - prod_config = os.path.join(path,"config.json") + prod_config = os.path.join(path, "config.json") prod_config = Props.read_from(prod_config, subst_pathvar=True)["setups"]["l200"] cfg_file = prod_config["paths"]["metadata"] - configs = LegendMetadata(path = cfg_file) + configs = LegendMetadata(path=cfg_file) chmap = configs.channelmap(timestamp).map("daq.rawid") - + software_config_path = prod_config["paths"]["config"] - software_config_db = LegendMetadata(path = software_config_path) + software_config_db = LegendMetadata(path=software_config_path) software_config = software_config_db.on(timestamp, system=datatype).analysis - - out_dict={} + + out_dict = {} # SiPMs sorting if spms: chmap = chmap.map("system", unique=False)["spms"] if key == "Barrel": mapping = chmap.map("daq.rawid", unique=False) - for pos in ['top', 'bottom']: - for barrel in ['IB', 'OB']: - out_dict[f"{barrel}-{pos}"] = [k for k, entry in sorted(mapping.items()) if barrel in entry["location"]["fiber"] and pos in entry["location"]["position"]] + for pos in ["top", "bottom"]: + for barrel in ["IB", "OB"]: + out_dict[f"{barrel}-{pos}"] = [ + k + for k, entry in sorted(mapping.items()) + if barrel in entry["location"]["fiber"] + and pos in entry["location"]["position"] + ] return out_dict, chmap - + out_key = "{key}:{k:02}" - primary_key= "location.string" + primary_key = "location.string" secondary_key = "location.position" mapping = chmap.map(primary_key, unique=False) - for k,entry in sorted(mapping.items()): - out_dict[out_key.format(key=key,k=k)]=[entry.map(secondary_key)[pos].daq.rawid for pos in sorted(entry.map(secondary_key)) if entry.map(secondary_key)[pos].system=="geds"] - - out_dict = {entry:out_dict[entry] for entry in list(out_dict) if len(out_dict[entry])>0} - return out_dict, software_config, chmap + for k, entry in sorted(mapping.items()): + out_dict[out_key.format(key=key, k=k)] = [ + entry.map(secondary_key)[pos].daq.rawid + for pos in sorted(entry.map(secondary_key)) + if entry.map(secondary_key)[pos].system == "geds" + ] + out_dict = { + entry: out_dict[entry] for entry in list(out_dict) if len(out_dict[entry]) > 0 + } + return out_dict, software_config, chmap diff --git a/src/leds/waveform_browse.py b/src/leds/waveform_browse.py index e036a05..25ed241 100644 --- a/src/leds/waveform_browse.py +++ b/src/leds/waveform_browse.py @@ -1,20 +1,19 @@ +from __future__ import annotations + import math -import os, json +import os + import lgdo.lh5_store as lh5 +import matplotlib as mpl import numpy as np -from legendmeta import LegendMetadata -import sys -import matplotlib as mpl -mpl.use('Qt5Agg') +mpl.use("Qt5Agg") import matplotlib.pyplot as plt - -from PyQt5.QtCore import QThread, QObject, pyqtSignal - from dspeed.vis import WaveformBrowser - +from PyQt5.QtCore import QObject, pyqtSignal from utils import * + def plot_string_compressed(fig, ax, ev, browsers, line_parameter="wf_blsub", string=1): def onpick(event, lined): legline = event.artist @@ -35,13 +34,19 @@ def onpick(event, lined): legline.set_alpha(1.0 if visible else 0.2) line.set_visible(visible) fig.canvas.draw() - - dets = [det_dict["name"] for pos, det_dict in ev.chmap.map("location.string", unique=False)[string].map("location.position").items() if det_dict["analysis"]["processable"]==True] - + + dets = [ + det_dict["name"] + for pos, det_dict in ev.chmap.map("location.string", unique=False)[string] + .map("location.position") + .items() + if det_dict["analysis"]["processable"] is True + ] + det_lines = {} - lines=[] - for i,det in enumerate(dets): - browser=browsers[f"ch{ev.chmap[det].daq.rawid}"] + lines = [] + for i, det in enumerate(dets): + browser = browsers[f"ch{ev.chmap[det].daq.rawid}"] line = browser.lines[line_parameter][0] x_lim = browser.x_lim if browser.x_lim else browser.auto_x_lim y_lim = browser.y_lim @@ -56,36 +61,36 @@ def onpick(event, lined): line.set_transform(browser.ax.transData) det_lines[det] = line - line.set_color(mpl.colormaps["tab20"](i/len(dets))) + line.set_color(mpl.colormaps["tab20"](i / len(dets))) lines.append(line) ax.add_line(line) ax.set_xlabel(browser.x_unit) if browser.x_lim: ax.set_xlim(*browser.x_lim) - plt.plot([], color = mpl.colormaps["tab20"](i/len(dets)), label= det, lw=5) + plt.plot([], color=mpl.colormaps["tab20"](i / len(dets)), label=det, lw=5) - leg = ax.legend(ncol=2, loc = "upper left", - frameon=False) + leg = ax.legend(ncol=2, loc="upper left", frameon=False) lined = {} for legline in leg.get_lines(): legline.set_picker(True) lined[legline] = det_lines[legline.get_label()] - - low, high = ax.yaxis.get_data_interval() - if low>-200: - low=-200 + low, high = ax.yaxis.get_data_interval() + if low > -200: + low = -200 if high < 200: high = 200 - ax.set_ylim([low,high]) + ax.set_ylim([low, high]) ax.set_ylabel("value (adc)") ax.set_xlabel("time (ns)") - fig.canvas.mpl_connect('pick_event', lambda x : onpick(x, lined)) + fig.canvas.mpl_connect("pick_event", lambda x: onpick(x, lined)) # fig.canvas.draw() - - -def plot_above_threshold_compressed(fig, ax, ev, browsers, line_parameter="wf_blsub", string=1): + + +def plot_above_threshold_compressed( + fig, ax, ev, browsers, line_parameter="wf_blsub", string=1 +): def onpick(event, lined): legline = event.artist if event.mouseevent.dblclick: @@ -105,13 +110,17 @@ def onpick(event, lined): legline.set_alpha(1.0 if visible else 0.2) line.set_visible(visible) fig.canvas.draw() - - dets = [det for det, energy in ev.energy_dict.items() if energy is not None and (energy>25)] - + + dets = [ + det + for det, energy in ev.energy_dict.items() + if energy is not None and (energy > 25) + ] + det_lines = {} - lines=[] - for i,det in enumerate(dets): - browser=browsers[f"ch{ev.chmap[det].daq.rawid}"] + lines = [] + for i, det in enumerate(dets): + browser = browsers[f"ch{ev.chmap[det].daq.rawid}"] line = browser.lines[line_parameter][0] x_lim = browser.x_lim if browser.x_lim else browser.auto_x_lim y_lim = browser.y_lim @@ -126,35 +135,34 @@ def onpick(event, lined): line.set_transform(browser.ax.transData) det_lines[det] = line - line.set_color(mpl.colormaps["tab20"](i/len(dets))) + line.set_color(mpl.colormaps["tab20"](i / len(dets))) lines.append(line) ax.add_line(line) ax.set_xlabel(browser.x_unit) if browser.x_lim: ax.set_xlim(*browser.x_lim) - if len(dets)<10: - plt.plot([], color = mpl.colormaps["tab20"](i/len(dets)), label= det, lw=5) - - if len(dets)<10: - leg = ax.legend(ncol=2, loc = "upper left", - frameon=False) + if len(dets) < 10: + plt.plot([], color=mpl.colormaps["tab20"](i / len(dets)), label=det, lw=5) + + if len(dets) < 10: + leg = ax.legend(ncol=2, loc="upper left", frameon=False) lined = {} for legline in leg.get_lines(): legline.set_picker(True) lined[legline] = det_lines[legline.get_label()] - - low, high = ax.yaxis.get_data_interval() - if low>-200: - low=-200 + low, high = ax.yaxis.get_data_interval() + if low > -200: + low = -200 if high < 200: high = 200 - ax.set_ylim([low,high]) + ax.set_ylim([low, high]) ax.set_ylabel("value (adc)") ax.set_xlabel("time (ns)") - if len(dets)<10: - fig.canvas.mpl_connect('pick_event', lambda x : onpick(x, lined)) + if len(dets) < 10: + fig.canvas.mpl_connect("pick_event", lambda x: onpick(x, lined)) + def plot_all_compressed(fig, ax, ev, browsers, line_parameter="wf_blsub"): def onpick(event, lined): @@ -163,10 +171,12 @@ def onpick(event, lined): for entry, lines in lined.items(): if entry is not legline: entry.set_alpha(0.2) - for line in lines: line.set_visible(False) + for line in lines: + line.set_visible(False) else: entry.set_alpha(1) - for line in lines: line.set_visible(True) + for line in lines: + line.set_visible(True) else: lines = lined[legline] # If the label of the legend matches that of the line, then set the alpha to 0 @@ -174,11 +184,13 @@ def onpick(event, lined): # have been toggled. visible = not lines[0].get_visible() legline.set_alpha(1.0 if visible else 0.2) - for line in lines: line.set_visible(visible) + for line in lines: + line.set_visible(visible) fig.canvas.draw() + strings = {} - lines=[] - for chan, browser in browsers.items(): + lines = [] + for chan, browser in browsers.items(): det = ev.chmap.map("daq.rawid")[int(chan[2:])]["name"] line = browser.lines[line_parameter][0] x_lim = browser.x_lim if browser.x_lim else browser.auto_x_lim @@ -198,77 +210,94 @@ def onpick(event, lined): strings[string].append(line) else: strings[string] = [line] - line.set_color(mpl.colormaps["tab20"](string/12)) + line.set_color(mpl.colormaps["tab20"](string / 12)) lines.append(line) ax.add_line(line) ax.set_xlabel(browser.x_unit) if browser.x_lim: ax.set_xlim(*browser.x_lim) - for string in np.unique(list(strings)): - plt.plot([], color = mpl.colormaps["tab20"](string/12), label= f"String:{string:02}", lw=5) + plt.plot( + [], + color=mpl.colormaps["tab20"](string / 12), + label=f"String:{string:02}", + lw=5, + ) - leg = ax.legend(ncol=1, loc = "upper left", - frameon=False)# + leg = ax.legend(ncol=1, loc="upper left", frameon=False) # lined = {} for legline in leg.get_lines(): legline.set_picker(True) lined[legline] = strings[int(legline.get_label()[-2:])] - - low, high = ax.yaxis.get_data_interval() - if low>-200: - low=-200 + low, high = ax.yaxis.get_data_interval() + if low > -200: + low = -200 if high < 200: high = 200 - ax.set_ylim([low,high]) + ax.set_ylim([low, high]) ax.set_ylabel("value (adc)") ax.set_xlabel("time (ns)") - fig.canvas.mpl_connect('pick_event', lambda x : onpick(x,lined)) + fig.canvas.mpl_connect("pick_event", lambda x: onpick(x, lined)) -def plot_event_compressed(ev, fig, browsers, line_parameter="wf_blsub", plot_category="all"): + +def plot_event_compressed( + ev, fig, browsers, line_parameter="wf_blsub", plot_category="all" +): ax = fig.add_subplot(111) - for det, browser in browsers.items(): - browser.set_figure(fig,ax) + for _det, browser in browsers.items(): + browser.set_figure(fig, ax) browser.find_entry(ev.index, append=False) if plot_category == "all": plot_all_compressed(fig, ax, ev, browsers, line_parameter) elif plot_category == "above threshold": plot_above_threshold_compressed(fig, ax, ev, browsers, line_parameter) else: - plot_string_compressed(fig, ax, ev, browsers, line_parameter, string=int(plot_category[-2:])) + plot_string_compressed( + fig, ax, ev, browsers, line_parameter, string=int(plot_category[-2:]) + ) + - def plot_string_exploded(fig, ev, browsers, line_parameter="wf_blsub", string=1): - dets = [det_dict["name"] for pos, det_dict in ev.chmap.map("location.string", unique=False)[string].map("location.position").items() if det_dict["analysis"]["processable"]==True] - - - if len(dets)<6: - det_ax = {dets[0]: plt.subplot(math.ceil(len(dets)/2),2,1)} + dets = [ + det_dict["name"] + for pos, det_dict in ev.chmap.map("location.string", unique=False)[string] + .map("location.position") + .items() + if det_dict["analysis"]["processable"] is True + ] + + if len(dets) < 6: + det_ax = {dets[0]: plt.subplot(math.ceil(len(dets) / 2), 2, 1)} for i, det in enumerate(dets[1:]): - det_ax[det]=plt.subplot(math.ceil(len(dets)/2),2, i+2, - sharex=det_ax[dets[0]], - sharey=det_ax[dets[0]], - ) + det_ax[det] = plt.subplot( + math.ceil(len(dets) / 2), + 2, + i + 2, + sharex=det_ax[dets[0]], + sharey=det_ax[dets[0]], + ) else: - det_ax = {dets[0]: plt.subplot(math.ceil(len(dets)/3),3,1)} + det_ax = {dets[0]: plt.subplot(math.ceil(len(dets) / 3), 3, 1)} for i, det in enumerate(dets[1:]): - det_ax[det]=plt.subplot(math.ceil(len(dets)/3),3, i+2, - sharex=det_ax[dets[0]], - sharey=det_ax[dets[0]], - ) - - + det_ax[det] = plt.subplot( + math.ceil(len(dets) / 3), + 3, + i + 2, + sharex=det_ax[dets[0]], + sharey=det_ax[dets[0]], + ) + low = -200 high = 200 - - for i,det in enumerate(dets): - browser=browsers[f"ch{ev.chmap[det].daq.rawid}"] + + for i, det in enumerate(dets): + browser = browsers[f"ch{ev.chmap[det].daq.rawid}"] ax = det_ax[det] browser.set_figure(fig, ax) - + line = browser.lines[line_parameter][0] x_lim = browser.x_lim if browser.x_lim else browser.auto_x_lim y_lim = browser.y_lim @@ -282,67 +311,74 @@ def plot_string_exploded(fig, ev, browsers, line_parameter="wf_blsub", string=1) browser.ax.set_ylim(*y_lim) line.set_transform(browser.ax.transData) - - line.set_color(mpl.colormaps["tab20"](i/len(dets))) + + line.set_color(mpl.colormaps["tab20"](i / len(dets))) ax.add_line(line) ax.set_xlabel(browser.x_unit) if browser.x_lim: ax.set_xlim(*browser.x_lim) - - current_low, current_high = ax.yaxis.get_data_interval() - if current_lowhigh: - high=current_high - - + current_low, current_high = ax.yaxis.get_data_interval() + if current_low < low: + low = current_low + if current_high > high: + high = current_high for det in list(dets): ax = det_ax[det] - ax.scatter([], [],color = "white", label= det, marker="x", s=0.0001) - ax.legend(ncol=1, loc = "upper left", - frameon=False, markerfirst=False) - ax.set_ylim([low,high]) + ax.scatter([], [], color="white", label=det, marker="x", s=0.0001) + ax.legend(ncol=1, loc="upper left", frameon=False, markerfirst=False) + ax.set_ylim([low, high]) ax.set_ylabel("") ax.set_xlabel("") ax.label_outer() - fig.text(0.5, 0.02, 'time (ns)', ha='center', va='center') - fig.text(0.015, 0.5, 'value (adu)', ha='center', va='center', rotation='vertical') + fig.text(0.5, 0.02, "time (ns)", ha="center", va="center") + fig.text(0.015, 0.5, "value (adu)", ha="center", va="center", rotation="vertical") fig.tight_layout() - -def plot_above_threshold_exploded(fig, ev, browsers, line_parameter="wf_blsub", string=1): - dets = [det for det, energy in ev.energy_dict.items() if energy is not None and (energy>25)] - if len(dets)>12: + + +def plot_above_threshold_exploded( + fig, ev, browsers, line_parameter="wf_blsub", string=1 +): + dets = [ + det + for det, energy in ev.energy_dict.items() + if energy is not None and (energy > 25) + ] + if len(dets) > 12: dets = dets[:12] - if len(dets) ==1: - det_ax = {dets[0] :plt.subplot(111)} - - - elif len(dets)<6: - det_ax = {dets[0]: plt.subplot(math.ceil(len(dets)/2),2,1)} + if len(dets) == 1: + det_ax = {dets[0]: plt.subplot(111)} + + elif len(dets) < 6: + det_ax = {dets[0]: plt.subplot(math.ceil(len(dets) / 2), 2, 1)} for i, det in enumerate(dets[1:]): - det_ax[det]=plt.subplot(math.ceil(len(dets)/2),2, i+2, - sharex=det_ax[dets[0]], - sharey=det_ax[dets[0]], - ) + det_ax[det] = plt.subplot( + math.ceil(len(dets) / 2), + 2, + i + 2, + sharex=det_ax[dets[0]], + sharey=det_ax[dets[0]], + ) else: - det_ax = {dets[0]: plt.subplot(math.ceil(len(dets)/3),3,1)} + det_ax = {dets[0]: plt.subplot(math.ceil(len(dets) / 3), 3, 1)} for i, det in enumerate(dets[1:]): - det_ax[det]=plt.subplot(math.ceil(len(dets)/3),3, i+2, - sharex=det_ax[dets[0]], - sharey=det_ax[dets[0]], - ) - - + det_ax[det] = plt.subplot( + math.ceil(len(dets) / 3), + 3, + i + 2, + sharex=det_ax[dets[0]], + sharey=det_ax[dets[0]], + ) + low = -200 high = 200 - - for i,det in enumerate(dets): - browser=browsers[f"ch{ev.chmap[det].daq.rawid}"] + + for i, det in enumerate(dets): + browser = browsers[f"ch{ev.chmap[det].daq.rawid}"] ax = det_ax[det] browser.set_figure(fig, ax) - + line = browser.lines[line_parameter][0] x_lim = browser.x_lim if browser.x_lim else browser.auto_x_lim y_lim = browser.y_lim @@ -356,52 +392,54 @@ def plot_above_threshold_exploded(fig, ev, browsers, line_parameter="wf_blsub", browser.ax.set_ylim(*y_lim) line.set_transform(browser.ax.transData) - - line.set_color(mpl.colormaps["tab20"](i/len(dets))) + + line.set_color(mpl.colormaps["tab20"](i / len(dets))) ax.add_line(line) ax.set_xlabel(browser.x_unit) if browser.x_lim: ax.set_xlim(*browser.x_lim) - - current_low, current_high = ax.yaxis.get_data_interval() - if current_lowhigh: - high=current_high - - + current_low, current_high = ax.yaxis.get_data_interval() + if current_low < low: + low = current_low + if current_high > high: + high = current_high for det in list(dets): ax = det_ax[det] - ax.scatter([], [],color = "white", label= det, marker="x", s=0.0001) - ax.legend(ncol=1, loc = "upper left", - frameon=False, markerfirst=False) - ax.set_ylim([low,high]) + ax.scatter([], [], color="white", label=det, marker="x", s=0.0001) + ax.legend(ncol=1, loc="upper left", frameon=False, markerfirst=False) + ax.set_ylim([low, high]) ax.set_ylabel("") ax.set_xlabel("") ax.label_outer() - fig.text(0.5, 0.02, 'time (ns)', ha='center', va='center') - fig.text(0.015, 0.5, 'value (adu)', ha='center', va='center', rotation='vertical') + fig.text(0.5, 0.02, "time (ns)", ha="center", va="center") + fig.text(0.015, 0.5, "value (adu)", ha="center", va="center", rotation="vertical") fig.tight_layout() + def plot_all_exploded(fig, ev, browsers, line_parameter="wf_blsub"): string_list = np.unique(list(ev.chmap.map("location.string", unique=False))) - strings = {sorted(string_list)[0]:plt.subplot(4,3,1)} - for i,string in enumerate(sorted(string_list)[1:]): - strings[string]= plt.subplot(4,3,i+2,sharex=strings[sorted(string_list)[0]], - sharey=strings[sorted(string_list)[0]]) - + strings = {sorted(string_list)[0]: plt.subplot(4, 3, 1)} + for i, string in enumerate(sorted(string_list)[1:]): + strings[string] = plt.subplot( + 4, + 3, + i + 2, + sharex=strings[sorted(string_list)[0]], + sharey=strings[sorted(string_list)[0]], + ) + low = -200 high = 200 - lines=[] - for chan, browser in browsers.items(): + lines = [] + for chan, browser in browsers.items(): det = ev.chmap.map("daq.rawid")[int(chan[2:])]["name"] string = ev.chmap[det]["location"]["string"] ax = strings[string] browser.set_figure(fig, ax) - + line = browser.lines[line_parameter][0] x_lim = browser.x_lim if browser.x_lim else browser.auto_x_lim y_lim = browser.y_lim @@ -415,137 +453,183 @@ def plot_all_exploded(fig, ev, browsers, line_parameter="wf_blsub"): browser.ax.set_ylim(*y_lim) line.set_transform(browser.ax.transData) - - line.set_color(mpl.colormaps["tab20"](string/12)) + + line.set_color(mpl.colormaps["tab20"](string / 12)) lines.append(line) ax.add_line(line) ax.set_xlabel(browser.x_unit) if browser.x_lim: ax.set_xlim(*browser.x_lim) - - current_low, current_high = ax.yaxis.get_data_interval() - if current_lowhigh: - high=current_high - + current_low, current_high = ax.yaxis.get_data_interval() + if current_low < low: + low = current_low + if current_high > high: + high = current_high for string in list(strings): ax = strings[string] - ax.scatter([], [],color = "white", label= f"String:{string:02}", marker="x", s=0.0001) - ax.legend(ncol=1, loc = "upper left", - frameon=False, markerfirst=False)# + ax.scatter( + [], [], color="white", label=f"String:{string:02}", marker="x", s=0.0001 + ) + ax.legend(ncol=1, loc="upper left", frameon=False, markerfirst=False) # - ax.set_ylim([low,high]) + ax.set_ylim([low, high]) ax.set_ylabel("") ax.set_xlabel("") ax.label_outer() - fig.text(0.5, 0.02, 'time (ns)', ha='center', va='center') - fig.text(0.015, 0.5, 'value (adu)', ha='center', va='center', rotation='vertical') + fig.text(0.5, 0.02, "time (ns)", ha="center", va="center") + fig.text(0.015, 0.5, "value (adu)", ha="center", va="center", rotation="vertical") fig.tight_layout() -def plot_event_exploded(ev, fig, browsers, line_parameter="wf_blsub", plot_category="all"): - for det, browser in browsers.items(): + +def plot_event_exploded( + ev, fig, browsers, line_parameter="wf_blsub", plot_category="all" +): + for _det, browser in browsers.items(): browser.find_entry(ev.index, append=False) if plot_category == "all": plot_all_exploded(fig, ev, browsers, line_parameter) elif plot_category == "above threshold": plot_above_threshold_exploded(fig, ev, browsers, line_parameter) else: - plot_string_exploded(fig, ev, browsers, line_parameter, string=int(plot_category[-2:])) + plot_string_exploded( + fig, ev, browsers, line_parameter, string=int(plot_category[-2:]) + ) -class spoof_iterator(): - sto=lh5.LH5Store() - +class spoof_iterator: + sto = lh5.LH5Store() + def __init__(self, ev, channel): - self.ev=ev - self.channel= channel + self.ev = ev + self.channel = channel f = self.ev.raw_file - g = f'{self.channel}/raw' + g = f"{self.channel}/raw" self.lh5_buffer = self.sto.get_buffer( - g, - f, - size=1, - ) + g, + f, + size=1, + ) self.current_entry = np.nan self.n_rows = 1 - + def read(self, entry): - self.lh5_buffer, n_rows = self.sto.read_object(f'{self.channel}/raw', - self.ev.raw_file, start_row = self.ev.index, n_rows=1) + self.lh5_buffer, n_rows = self.sto.read_object( + f"{self.channel}/raw", self.ev.raw_file, start_row=self.ev.index, n_rows=1 + ) return (self.lh5_buffer, self.n_rows) -class event_waveform_browser(): +class event_waveform_browser: def __init__(self, ev): self.cached_browsers = {} self.ev = ev self.ev._get_event("*", "*", "*", 0) self.file = self.ev.raw_file - self.browsers={} - self.current_dsp_configs={} - - + self.browsers = {} + self.current_dsp_configs = {} + def _get_browser(self, channel, dsp_config): - browser = WaveformBrowser(self.ev.raw_file, - f"{channel}/raw", - dsp_config = dsp_config, - lines=["wf_blsub", "wf_pz", "wf_trap", "curr"], #change this to use config - buffer_len=1) + browser = WaveformBrowser( + self.ev.raw_file, + f"{channel}/raw", + dsp_config=dsp_config, + lines=["wf_blsub", "wf_pz", "wf_trap", "curr"], # change this to use config + buffer_len=1, + ) spoof = spoof_iterator(self.ev, channel) browser.lh5_it = spoof - # need to replace browsers lh5_its + # need to replace browsers lh5_its return browser - - + def get_browsers(self): channels = [f"ch{self.ev.chmap[det].daq.rawid}" for det in self.ev.working_dets] - dataprod_config = self.ev.meta.dataprod.config.on(os.path.basename(self.file).split("-")[4]) - dsp_configs = dataprod_config["snakemake_rules"]["tier_dsp"]["inputs"]["processing_chain"] - # check if channels are same + dataprod_config = self.ev.meta.dataprod.config.on( + os.path.basename(self.file).split("-")[4] + ) + dsp_configs = dataprod_config["snakemake_rules"]["tier_dsp"]["inputs"][ + "processing_chain" + ] + # check if channels are same if channels == list(self.browsers): # check dsp configs are same for channel in channels: if dsp_configs[f"{channel}/raw"] != self.current_dsp_configs[channel]: if channel in list(self.cached_browsers): - self.cached_browsers[channel].update({self.current_dsp_configs[channel]:self.browsers.pop(channel)}) + self.cached_browsers[channel].update( + { + self.current_dsp_configs[channel]: self.browsers.pop( + channel + ) + } + ) if dsp_configs[channel] in list(self.cached_browsers[channel]): - self.browsers[channel] = self.cached_browsers[channel].pop(dsp_configs[f"{channel}/raw"]) + self.browsers[channel] = self.cached_browsers[channel].pop( + dsp_configs[f"{channel}/raw"] + ) else: - self.browsers[channel] = self._get_browser(channel, dsp_configs[f"{channel}/raw"]) + self.browsers[channel] = self._get_browser( + channel, dsp_configs[f"{channel}/raw"] + ) else: - self.cached_browsers[channel] = {self.current_dsp_configs[channel]:self.browsers.pop(channel)} - self.browsers[channel] = self._get_browser(channel, dsp_configs[f"{channel}/raw"]) - + self.cached_browsers[channel] = { + self.current_dsp_configs[channel]: self.browsers.pop( + channel + ) + } + self.browsers[channel] = self._get_browser( + channel, dsp_configs[f"{channel}/raw"] + ) + else: # check for channels missing for channel in channels: if channel not in list(self.browsers): if channel in list(self.cached_browsers): - if dsp_configs[f"{channel}/raw"] in list(self.cached_browsers[channel]): - self.browsers[channel] = self.cached_browsers[channel][dsp_configs[f"{channel}/raw"]].pop() + if dsp_configs[f"{channel}/raw"] in list( + self.cached_browsers[channel] + ): + self.browsers[channel] = self.cached_browsers[channel][ + dsp_configs[f"{channel}/raw"] + ].pop() else: - self.browsers[channel] = self._get_browser(channel, dsp_configs[f"{channel}/raw"]) + self.browsers[channel] = self._get_browser( + channel, dsp_configs[f"{channel}/raw"] + ) else: - self.browsers[channel] = self._get_browser(channel, dsp_configs[f"{channel}/raw"]) + self.browsers[channel] = self._get_browser( + channel, dsp_configs[f"{channel}/raw"] + ) # check for extra channels - for channel, browser in self.browsers.items(): + for channel, _browser in self.browsers.items(): if channel not in channels: if channel in list(self.cached_browsers): - self.cached_browsers[channel].update({self.current_dsp_configs[channel]:self.browsers.pop(channel)}) + self.cached_browsers[channel].update( + { + self.current_dsp_configs[channel]: self.browsers.pop( + channel + ) + } + ) else: - self.cached_browsers[channel] = {self.current_dsp_configs[channel]:self.browsers.pop(channel)} - self.current_dsp_configs = {name.split("/")[0]:item for name, item in dsp_configs.items() } - + self.cached_browsers[channel] = { + self.current_dsp_configs[channel]: self.browsers.pop( + channel + ) + } + self.current_dsp_configs = { + name.split("/")[0]: item for name, item in dsp_configs.items() + } + + class getBrowsers(QObject): finished = pyqtSignal() def __init__(self, browsers): - self.browsers=browsers + self.browsers = browsers super().__init__() def run(self): self.browsers.get_browsers() - self.finished.emit() \ No newline at end of file + self.finished.emit()