From c5e89bbe633a9a09f7cdf729baa44564a692febe Mon Sep 17 00:00:00 2001 From: jorana Date: Tue, 13 Feb 2024 15:28:22 +0000 Subject: [PATCH 1/4] Add online_veto_intervals plugin --- straxen/plugins/veto_intervals/__init__.py | 3 + .../veto_intervals/online_veto_intervals.py | 112 ++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 straxen/plugins/veto_intervals/online_veto_intervals.py diff --git a/straxen/plugins/veto_intervals/__init__.py b/straxen/plugins/veto_intervals/__init__.py index 8bd04b8cc..6047adb8b 100644 --- a/straxen/plugins/veto_intervals/__init__.py +++ b/straxen/plugins/veto_intervals/__init__.py @@ -1,2 +1,5 @@ from . import veto_intervals from .veto_intervals import * + +from . import online_veto_intervals +from .online_veto_intervals import * diff --git a/straxen/plugins/veto_intervals/online_veto_intervals.py b/straxen/plugins/veto_intervals/online_veto_intervals.py new file mode 100644 index 000000000..1c470b7bf --- /dev/null +++ b/straxen/plugins/veto_intervals/online_veto_intervals.py @@ -0,0 +1,112 @@ +import typing +import numpy as np +import strax +import straxen + +from straxen.plugins.aqmon_hits.aqmon_hits import AqmonChannels + +export, __all__ = strax.exporter() + + +# ### Veto hardware ###: +# V1495 busy veto module: +# Generates a 25 ns NIM pulse whenever a veto begins and a 25 ns NIM signal when it ends. +# A new start signal can occur only after the previous busy instance ended. +# 1ms (1e6 ns) - minimum busy veto length, or until the board clears its memory + +# DDC10 High Energy Veto: +# 10ms (1e7 ns) - fixed HE veto length in XENON1T DDC10, +# in XENONnT it will be calibrated based on the length of large S2 SE tails +# The start/stop signals for the HEV are generated by the V1495 board + + +@export +class OnlineVetoIntervals(strax.OverlapWindowPlugin): + """Find pairs of veto start and veto stop signals and the veto. + + duration between them: + - busy_* <= V1495 busy veto for tpc channels + - busy_he_* <= V1495 busy veto for high energy tpc channels + - hev_* <= DDC10 hardware high energy veto + - straxen_deadtime <= special case of deadtime introduced by the + DAQReader-plugin + + """ + + __version__ = "0.0.1" + depends_on = "veto_intervals" + provides = "online_veto_intervals" + data_kind = "veto_intervals" + + # Save the data only when it is requested explicitly + save_when = strax.SaveWhen.EXPLICIT + + # This option is just showing where the OverlapWindowPlugin fails. + # We need to buffer the entire run in order not to run into chunking + # issues. A better solution would be using + # github.com/AxFoundation/strax/pull/654 + max_veto_window = straxen.URLConfig( + default=int(7.2e12), + track=True, + type=int, + help=( + "Maximum separation between veto stop and start pulses [ns]. " + "Set to be >> than the max duration of the run to be able to " + "fully store one run into buffer since aqmon-hits are not " + "sorted by endtime" + ), + ) + + online_max_bytes = straxen.URLConfig( + default=6e6, track=True, help="Maximum amount of bytes of data for MongoDB document" + ) + + def infer_dtype(self): + dtype = [ + (("veto interval [ns]", "veto_interval"), np.int64), + (("veto signal type", "veto_type"), np.str_("U30")), + (("cumulative time of the veto interval [ns]", "cumulative_deadtime"), np.float64), + ] + dtype += strax.time_fields + return dtype + + def compute(self, veto_intervals, start, end): + + # Calculate the cumulative deadtime for the entire chunk + cumulative_deadtime = self._data_to_ms_cumsum(veto_intervals) + + if veto_intervals.nbytes > self.online_max_bytes: + + # Calculate fraction of the data that can be kept, + # to reduce datasize. Randomly keep a fraction of the data + new_len = int(len(veto_intervals) / veto_intervals.nbytes * self.online_max_bytes) + idx = np.random.choice(np.arange(len(veto_intervals)), replace=False, size=new_len) + veto_intervals = veto_intervals[np.sort(idx)] + + # Only keep the cumulative deadtime for the kept data indices + cumulative_deadtime = cumulative_deadtime[np.sort(idx)] + + result = np.zeros(len(veto_intervals), dtype=self.dtype) + result["veto_interval"] = veto_intervals["veto_interval"] + result["veto_type"] = veto_intervals["veto_type"] + result["cumulative_deadtime"] = cumulative_deadtime + result["time"] = veto_intervals["time"] + result["endtime"] = veto_intervals["endtime"] + + # If the final data array is still too large, we randomly sample again + # up to 10MB + if result.nbytes > self.online_max_bytes and result.nbytes < 10e6: + new_len = int(len(result) / result.nbytes * self.online_max_bytes) + idx = np.random.choice(np.arange(len(result)), replace=False, size=new_len) + result = result[np.sort(idx)] + + return result + + def get_window_size(self): + # Give a very wide window + return self.max_veto_window + + @staticmethod + def _data_to_ms_cumsum(data): + return np.cumsum(data['veto_interval']) / 1e6 + From 646d88c1d23fe3d02014a109322574f74dc2a51d Mon Sep 17 00:00:00 2001 From: mflierm Date: Tue, 13 Feb 2024 15:49:04 +0000 Subject: [PATCH 2/4] Add online_veto_intervals to olmo plugins --- straxen/contexts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/straxen/contexts.py b/straxen/contexts.py index a8bca2833..fa8496c43 100644 --- a/straxen/contexts.py +++ b/straxen/contexts.py @@ -289,7 +289,7 @@ def xenonnt_online( straxen.OnlineMonitor( readonly=not we_are_the_daq, take_only=( - "veto_intervals", + "online_veto_intervals", "online_peak_monitor", "event_basics", "online_monitor_nv", From f678308634b422f0351e24697fb75125c4ccc8cc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:57:22 +0000 Subject: [PATCH 3/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../plugins/veto_intervals/online_veto_intervals.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/straxen/plugins/veto_intervals/online_veto_intervals.py b/straxen/plugins/veto_intervals/online_veto_intervals.py index 1c470b7bf..a7d57b3e9 100644 --- a/straxen/plugins/veto_intervals/online_veto_intervals.py +++ b/straxen/plugins/veto_intervals/online_veto_intervals.py @@ -71,12 +71,12 @@ def infer_dtype(self): return dtype def compute(self, veto_intervals, start, end): - + # Calculate the cumulative deadtime for the entire chunk cumulative_deadtime = self._data_to_ms_cumsum(veto_intervals) if veto_intervals.nbytes > self.online_max_bytes: - + # Calculate fraction of the data that can be kept, # to reduce datasize. Randomly keep a fraction of the data new_len = int(len(veto_intervals) / veto_intervals.nbytes * self.online_max_bytes) @@ -86,7 +86,7 @@ def compute(self, veto_intervals, start, end): # Only keep the cumulative deadtime for the kept data indices cumulative_deadtime = cumulative_deadtime[np.sort(idx)] - result = np.zeros(len(veto_intervals), dtype=self.dtype) + result = np.zeros(len(veto_intervals), dtype=self.dtype) result["veto_interval"] = veto_intervals["veto_interval"] result["veto_type"] = veto_intervals["veto_type"] result["cumulative_deadtime"] = cumulative_deadtime @@ -105,8 +105,7 @@ def compute(self, veto_intervals, start, end): def get_window_size(self): # Give a very wide window return self.max_veto_window - + @staticmethod def _data_to_ms_cumsum(data): - return np.cumsum(data['veto_interval']) / 1e6 - + return np.cumsum(data["veto_interval"]) / 1e6 From 7073632644200575cb390fbdbef4f9f73a99769c Mon Sep 17 00:00:00 2001 From: mflierm Date: Tue, 13 Feb 2024 16:34:08 +0000 Subject: [PATCH 4/4] Unused imports --- straxen/plugins/veto_intervals/online_veto_intervals.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/straxen/plugins/veto_intervals/online_veto_intervals.py b/straxen/plugins/veto_intervals/online_veto_intervals.py index a7d57b3e9..68280fdb5 100644 --- a/straxen/plugins/veto_intervals/online_veto_intervals.py +++ b/straxen/plugins/veto_intervals/online_veto_intervals.py @@ -1,10 +1,7 @@ -import typing import numpy as np import strax import straxen -from straxen.plugins.aqmon_hits.aqmon_hits import AqmonChannels - export, __all__ = strax.exporter()