Module pmt_analysis.processing.basics
Expand source code
import numpy as np
import pandas as pd
import warnings
from typing import Tuple, List, Optional
class FixedWindow:
"""Basic processing functions using a fixed window for baseline / peak calculations.
Applicable for (externally) triggered data taking, such as during LED calibrations.
Attributes:
bounds_baseline: Lower (included) and upper (excluded) index of window for baseline calculations.
Unbound if element(s) `None`.
bounds_peak: Lower (included) and upper (excluded) index of window for peak calculations.
Unbound if element(s) `None`.
"""
def __init__(self, bounds_baseline: Tuple[Optional[int], Optional[int]],
bounds_peak: Tuple[Optional[int], Optional[int]]):
"""Init of the FixedWindow class.
Defines baseline and peak window boundaries.
Args:
bounds_baseline: Lower (included) and upper (excluded) index of window for baseline calculations.
bounds_peak: Lower (included) and upper (excluded) index of window for peak calculations.
"""
self.bounds_baseline = self.set_bounds(bounds_baseline, 'bounds_baseline')
self.bounds_peak = self.set_bounds(bounds_peak, 'bounds_peak')
def set_bounds(self, input_tuple: Tuple[Optional[int], Optional[int]],
input_tuple_name: str) -> Tuple[Optional[int], Optional[int]]:
"""Check and convert boundary tuples.
Used for `bounds_baseline` and `bounds_peak`. Assert that tuple of length 2 with integers.
Args:
input_tuple: Tuple to check and convert.
input_tuple_name: Name of the tuple, used in error messages.
Returns:
output_tuple: Tuple of length 2 with integers.
"""
# Check that iterable is passed.
if not hasattr(input_tuple, '__iter__'):
raise TypeError('Expected iterable (ideally tuple) for {}.'.format(input_tuple_name))
# Check length of passed iterable.
if len(input_tuple) != 2:
raise ValueError('Expected tuple of length 2 for {}.'.format(input_tuple_name))
# Convert to list to make mutable.
output_list = list(input_tuple)
# Try to convert values to int if necessary.
for i, el in enumerate(output_list):
if (type(el) not in [int, np.int64]) and (el is not None):
try:
output_list[i] = int(el)
warnings.warn('Converted element {} in {} to int. This may lead to unwanted behavior. '
'Recommended to directly pass tuples of integers.'.format(i, input_tuple_name))
except Exception:
raise TypeError('Expected tuple of integers / Nones for {}.'.format(input_tuple_name))
# Convert to tuple to make immutable.
output_tuple = tuple(output_list)
# Assert that tuple elements of ascending order.
if np.all([el is not None for el in output_tuple]) and output_tuple[0] >= output_tuple[1]:
raise ValueError('Elements in {} must be of ascending order or None.format(input_tuple_name)')
return output_tuple
def get_baseline(self, input_data: np.ndarray) -> np.ndarray:
"""Calculate baselines of individual waveforms.
Args:
input_data: Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns:
bsl: Array with baseline values of shape (number of waveforms, ).
"""
bsl = np.median(input_data[:, self.bounds_baseline[0]:self.bounds_baseline[-1]], axis=1)
return bsl
def get_baseline_std(self, input_data: np.ndarray) -> np.ndarray:
"""Calculate baseline standard deviations of individual waveforms.
Args:
input_data: Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns:
bsl: Array with baseline standard deviation values of shape (number of waveforms, ).
"""
bsl_std = np.std(input_data[:, self.bounds_baseline[0]:self.bounds_baseline[-1]], axis=1, ddof=1)
return bsl_std
def get_amplitude(self, input_data: np.ndarray) -> np.ndarray:
"""Calculate naive peak amplitudes as baseline subtracted maximum outlier in window of individual waveforms.
Args:
input_data: Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns:
amp_val: Array with amplitude values of shape (number of waveforms, ).
"""
bsl_val = self.get_baseline(input_data)
min_val = np.min(input_data[:, self.bounds_peak[0]:self.bounds_peak[-1]], axis=1)
amp_val = bsl_val - min_val
return amp_val
def get_peak_position(self, input_data: np.ndarray) -> np.ndarray:
"""Calculate naive peak position index as maximum outlier in window of individual waveforms.
Args:
input_data: Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns:
amp_val: Array with peak position index values of shape (number of waveforms, ).
"""
min_pos = np.argmin(input_data[:, self.bounds_peak[0]:self.bounds_peak[-1]], axis=1)
# Correct for lower peak window boundary.
# Zero offset if lower boundary None (defined to falsify in boolean or).
min_pos_corrected = min_pos + (self.bounds_peak[0] or 0)
return min_pos_corrected
def get_area(self, input_data: np.ndarray) -> np.ndarray:
"""Calculate naive baseline subtracted peak areas.
Args:
input_data: Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns:
area_val: Array with peak area values of shape (number of waveforms, ).
"""
gross_area = np.sum(input_data[:, self.bounds_peak[0]:self.bounds_peak[-1]], axis=1)
window_width_peak = np.sum(np.ones(input_data.shape[1])[self.bounds_peak[0]:self.bounds_peak[-1]])
bsl_val = self.get_baseline(input_data)
bsl_area = window_width_peak * bsl_val
area_val = bsl_area - gross_area
return area_val
def get_basic_properties(self, input_data: np.ndarray,
parameters: List[str] = ['baseline', 'amplitude', 'area']) -> pd.DataFrame:
"""Calculate basic waveform properties, such as baseline, peak amplitude and area,...
Args:
input_data: Array with ADC data of shape (number of waveforms, time bins per waveform).
parameters: List of names of the parameters to be calculated.
Returns:
df_out: Pandas data frame with parameters of interest as columns.
"""
if type(input_data) != np.ndarray:
if type(input_data) == list:
input_data = np.array(input_data)
else:
raise TypeError('input_data must be of type numpy.ndarray.')
if input_data.ndim != 2:
raise ValueError('input_data must have ndim = 2 dimension.')
lower_bounds_list = [self.bounds_peak[0], self.bounds_baseline[0], input_data.shape[1]-1]
lower_bounds_list = np.array([el for el in lower_bounds_list if el is not None])
lower_bounds_list = lower_bounds_list + input_data.shape[1] * (lower_bounds_list < 0)
if max(lower_bounds_list) >= input_data.shape[1]:
raise ValueError('A lower window boundary was selected that extends beyond the data array length.')
df_out = pd.DataFrame()
if 'baseline' in parameters:
df_out['baseline'] = self.get_baseline(input_data)
if 'baseline_std' in parameters:
df_out['baseline_std'] = self.get_baseline_std(input_data)
if 'amplitude' in parameters:
df_out['amplitude'] = self.get_amplitude(input_data)
if 'peak_position' in parameters:
df_out['peak_position'] = self.get_peak_position(input_data)
if 'area' in parameters:
df_out['area'] = self.get_area(input_data)
if df_out.shape == (0, 0):
warnings.warn("Output from get_basic_properties seems to be empty.")
return df_out
class FullWindow(FixedWindow):
"""Basic processing functions using the full waveform window for baseline / peak calculations
without dedicated peak finding. Applicable especially for naive random dark count finding.
Attributes:
n_slices: Number of slices for robust baseline and baseline standard deviation calculation.
"""
def __init__(self, n_slices: int = 7):
"""Init of the FullWindow class.
Defines baseline and peak window boundaries as None to use full waveform window.
Args:
n_slices: Number of slices for robust baseline and baseline standard deviation calculation.
"""
FixedWindow.__init__(self, bounds_baseline=(None, None), bounds_peak=(None, None))
self.n_slices = n_slices
def get_baseline(self, input_data: np.ndarray) -> np.ndarray:
"""Calculate baselines of individual waveforms with reduced peaks impact.
Apply more robust approach reducing the pull by localized peaks by calculating the median
in `n_slices` slices of approximately (but not necessarily exactly)
equal size and taking the median of those values as baseline value.
Args:
input_data: Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns:
bsl: Array with baseline values of shape (number of waveforms, ).
"""
bsl = np.median(np.asarray([np.median(el, axis=1) for el in
np.array_split(input_data, self.n_slices, axis=1)]).T, axis=1)
return bsl
def get_baseline_std(self, input_data: np.ndarray) -> np.ndarray:
"""Calculate baseline standard deviations of individual waveforms with reduced peaks impact.
Apply more robust approach reducing the pull by localized peaks by calculating the
standard deviation in `n_slices` slices of approximately (but not necessarily exactly)
equal size and taking the median of those values as baseline standard deviation value.
Args:
input_data: Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns:
bsl: Array with baseline standard deviation values of shape (number of waveforms, ).
"""
bsl_std = np.median(np.asarray([np.std(el, axis=1) for el in
np.array_split(input_data, self.n_slices, axis=1)]).T, axis=1)
return bsl_std
Classes
class FixedWindow (bounds_baseline: Tuple[Optional[int], Optional[int]], bounds_peak: Tuple[Optional[int], Optional[int]])
-
Basic processing functions using a fixed window for baseline / peak calculations. Applicable for (externally) triggered data taking, such as during LED calibrations.
Attributes
bounds_baseline
- Lower (included) and upper (excluded) index of window for baseline calculations.
Unbound if element(s)
None
. bounds_peak
- Lower (included) and upper (excluded) index of window for peak calculations.
Unbound if element(s)
None
.
Init of the FixedWindow class.
Defines baseline and peak window boundaries.
Args
bounds_baseline
- Lower (included) and upper (excluded) index of window for baseline calculations.
bounds_peak
- Lower (included) and upper (excluded) index of window for peak calculations.
Expand source code
class FixedWindow: """Basic processing functions using a fixed window for baseline / peak calculations. Applicable for (externally) triggered data taking, such as during LED calibrations. Attributes: bounds_baseline: Lower (included) and upper (excluded) index of window for baseline calculations. Unbound if element(s) `None`. bounds_peak: Lower (included) and upper (excluded) index of window for peak calculations. Unbound if element(s) `None`. """ def __init__(self, bounds_baseline: Tuple[Optional[int], Optional[int]], bounds_peak: Tuple[Optional[int], Optional[int]]): """Init of the FixedWindow class. Defines baseline and peak window boundaries. Args: bounds_baseline: Lower (included) and upper (excluded) index of window for baseline calculations. bounds_peak: Lower (included) and upper (excluded) index of window for peak calculations. """ self.bounds_baseline = self.set_bounds(bounds_baseline, 'bounds_baseline') self.bounds_peak = self.set_bounds(bounds_peak, 'bounds_peak') def set_bounds(self, input_tuple: Tuple[Optional[int], Optional[int]], input_tuple_name: str) -> Tuple[Optional[int], Optional[int]]: """Check and convert boundary tuples. Used for `bounds_baseline` and `bounds_peak`. Assert that tuple of length 2 with integers. Args: input_tuple: Tuple to check and convert. input_tuple_name: Name of the tuple, used in error messages. Returns: output_tuple: Tuple of length 2 with integers. """ # Check that iterable is passed. if not hasattr(input_tuple, '__iter__'): raise TypeError('Expected iterable (ideally tuple) for {}.'.format(input_tuple_name)) # Check length of passed iterable. if len(input_tuple) != 2: raise ValueError('Expected tuple of length 2 for {}.'.format(input_tuple_name)) # Convert to list to make mutable. output_list = list(input_tuple) # Try to convert values to int if necessary. for i, el in enumerate(output_list): if (type(el) not in [int, np.int64]) and (el is not None): try: output_list[i] = int(el) warnings.warn('Converted element {} in {} to int. This may lead to unwanted behavior. ' 'Recommended to directly pass tuples of integers.'.format(i, input_tuple_name)) except Exception: raise TypeError('Expected tuple of integers / Nones for {}.'.format(input_tuple_name)) # Convert to tuple to make immutable. output_tuple = tuple(output_list) # Assert that tuple elements of ascending order. if np.all([el is not None for el in output_tuple]) and output_tuple[0] >= output_tuple[1]: raise ValueError('Elements in {} must be of ascending order or None.format(input_tuple_name)') return output_tuple def get_baseline(self, input_data: np.ndarray) -> np.ndarray: """Calculate baselines of individual waveforms. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: bsl: Array with baseline values of shape (number of waveforms, ). """ bsl = np.median(input_data[:, self.bounds_baseline[0]:self.bounds_baseline[-1]], axis=1) return bsl def get_baseline_std(self, input_data: np.ndarray) -> np.ndarray: """Calculate baseline standard deviations of individual waveforms. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: bsl: Array with baseline standard deviation values of shape (number of waveforms, ). """ bsl_std = np.std(input_data[:, self.bounds_baseline[0]:self.bounds_baseline[-1]], axis=1, ddof=1) return bsl_std def get_amplitude(self, input_data: np.ndarray) -> np.ndarray: """Calculate naive peak amplitudes as baseline subtracted maximum outlier in window of individual waveforms. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: amp_val: Array with amplitude values of shape (number of waveforms, ). """ bsl_val = self.get_baseline(input_data) min_val = np.min(input_data[:, self.bounds_peak[0]:self.bounds_peak[-1]], axis=1) amp_val = bsl_val - min_val return amp_val def get_peak_position(self, input_data: np.ndarray) -> np.ndarray: """Calculate naive peak position index as maximum outlier in window of individual waveforms. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: amp_val: Array with peak position index values of shape (number of waveforms, ). """ min_pos = np.argmin(input_data[:, self.bounds_peak[0]:self.bounds_peak[-1]], axis=1) # Correct for lower peak window boundary. # Zero offset if lower boundary None (defined to falsify in boolean or). min_pos_corrected = min_pos + (self.bounds_peak[0] or 0) return min_pos_corrected def get_area(self, input_data: np.ndarray) -> np.ndarray: """Calculate naive baseline subtracted peak areas. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: area_val: Array with peak area values of shape (number of waveforms, ). """ gross_area = np.sum(input_data[:, self.bounds_peak[0]:self.bounds_peak[-1]], axis=1) window_width_peak = np.sum(np.ones(input_data.shape[1])[self.bounds_peak[0]:self.bounds_peak[-1]]) bsl_val = self.get_baseline(input_data) bsl_area = window_width_peak * bsl_val area_val = bsl_area - gross_area return area_val def get_basic_properties(self, input_data: np.ndarray, parameters: List[str] = ['baseline', 'amplitude', 'area']) -> pd.DataFrame: """Calculate basic waveform properties, such as baseline, peak amplitude and area,... Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). parameters: List of names of the parameters to be calculated. Returns: df_out: Pandas data frame with parameters of interest as columns. """ if type(input_data) != np.ndarray: if type(input_data) == list: input_data = np.array(input_data) else: raise TypeError('input_data must be of type numpy.ndarray.') if input_data.ndim != 2: raise ValueError('input_data must have ndim = 2 dimension.') lower_bounds_list = [self.bounds_peak[0], self.bounds_baseline[0], input_data.shape[1]-1] lower_bounds_list = np.array([el for el in lower_bounds_list if el is not None]) lower_bounds_list = lower_bounds_list + input_data.shape[1] * (lower_bounds_list < 0) if max(lower_bounds_list) >= input_data.shape[1]: raise ValueError('A lower window boundary was selected that extends beyond the data array length.') df_out = pd.DataFrame() if 'baseline' in parameters: df_out['baseline'] = self.get_baseline(input_data) if 'baseline_std' in parameters: df_out['baseline_std'] = self.get_baseline_std(input_data) if 'amplitude' in parameters: df_out['amplitude'] = self.get_amplitude(input_data) if 'peak_position' in parameters: df_out['peak_position'] = self.get_peak_position(input_data) if 'area' in parameters: df_out['area'] = self.get_area(input_data) if df_out.shape == (0, 0): warnings.warn("Output from get_basic_properties seems to be empty.") return df_out
Subclasses
Methods
def get_amplitude(self, input_data: numpy.ndarray) ‑> numpy.ndarray
-
Calculate naive peak amplitudes as baseline subtracted maximum outlier in window of individual waveforms.
Args
input_data
- Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns
amp_val
- Array with amplitude values of shape (number of waveforms, ).
Expand source code
def get_amplitude(self, input_data: np.ndarray) -> np.ndarray: """Calculate naive peak amplitudes as baseline subtracted maximum outlier in window of individual waveforms. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: amp_val: Array with amplitude values of shape (number of waveforms, ). """ bsl_val = self.get_baseline(input_data) min_val = np.min(input_data[:, self.bounds_peak[0]:self.bounds_peak[-1]], axis=1) amp_val = bsl_val - min_val return amp_val
def get_area(self, input_data: numpy.ndarray) ‑> numpy.ndarray
-
Calculate naive baseline subtracted peak areas.
Args
input_data
- Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns
area_val
- Array with peak area values of shape (number of waveforms, ).
Expand source code
def get_area(self, input_data: np.ndarray) -> np.ndarray: """Calculate naive baseline subtracted peak areas. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: area_val: Array with peak area values of shape (number of waveforms, ). """ gross_area = np.sum(input_data[:, self.bounds_peak[0]:self.bounds_peak[-1]], axis=1) window_width_peak = np.sum(np.ones(input_data.shape[1])[self.bounds_peak[0]:self.bounds_peak[-1]]) bsl_val = self.get_baseline(input_data) bsl_area = window_width_peak * bsl_val area_val = bsl_area - gross_area return area_val
def get_baseline(self, input_data: numpy.ndarray) ‑> numpy.ndarray
-
Calculate baselines of individual waveforms.
Args
input_data
- Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns
bsl
- Array with baseline values of shape (number of waveforms, ).
Expand source code
def get_baseline(self, input_data: np.ndarray) -> np.ndarray: """Calculate baselines of individual waveforms. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: bsl: Array with baseline values of shape (number of waveforms, ). """ bsl = np.median(input_data[:, self.bounds_baseline[0]:self.bounds_baseline[-1]], axis=1) return bsl
def get_baseline_std(self, input_data: numpy.ndarray) ‑> numpy.ndarray
-
Calculate baseline standard deviations of individual waveforms.
Args
input_data
- Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns
bsl
- Array with baseline standard deviation values of shape (number of waveforms, ).
Expand source code
def get_baseline_std(self, input_data: np.ndarray) -> np.ndarray: """Calculate baseline standard deviations of individual waveforms. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: bsl: Array with baseline standard deviation values of shape (number of waveforms, ). """ bsl_std = np.std(input_data[:, self.bounds_baseline[0]:self.bounds_baseline[-1]], axis=1, ddof=1) return bsl_std
def get_basic_properties(self, input_data: numpy.ndarray, parameters: List[str] = ['baseline', 'amplitude', 'area']) ‑> pandas.core.frame.DataFrame
-
Calculate basic waveform properties, such as baseline, peak amplitude and area,…
Args
input_data
- Array with ADC data of shape (number of waveforms, time bins per waveform).
parameters
- List of names of the parameters to be calculated.
Returns
df_out
- Pandas data frame with parameters of interest as columns.
Expand source code
def get_basic_properties(self, input_data: np.ndarray, parameters: List[str] = ['baseline', 'amplitude', 'area']) -> pd.DataFrame: """Calculate basic waveform properties, such as baseline, peak amplitude and area,... Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). parameters: List of names of the parameters to be calculated. Returns: df_out: Pandas data frame with parameters of interest as columns. """ if type(input_data) != np.ndarray: if type(input_data) == list: input_data = np.array(input_data) else: raise TypeError('input_data must be of type numpy.ndarray.') if input_data.ndim != 2: raise ValueError('input_data must have ndim = 2 dimension.') lower_bounds_list = [self.bounds_peak[0], self.bounds_baseline[0], input_data.shape[1]-1] lower_bounds_list = np.array([el for el in lower_bounds_list if el is not None]) lower_bounds_list = lower_bounds_list + input_data.shape[1] * (lower_bounds_list < 0) if max(lower_bounds_list) >= input_data.shape[1]: raise ValueError('A lower window boundary was selected that extends beyond the data array length.') df_out = pd.DataFrame() if 'baseline' in parameters: df_out['baseline'] = self.get_baseline(input_data) if 'baseline_std' in parameters: df_out['baseline_std'] = self.get_baseline_std(input_data) if 'amplitude' in parameters: df_out['amplitude'] = self.get_amplitude(input_data) if 'peak_position' in parameters: df_out['peak_position'] = self.get_peak_position(input_data) if 'area' in parameters: df_out['area'] = self.get_area(input_data) if df_out.shape == (0, 0): warnings.warn("Output from get_basic_properties seems to be empty.") return df_out
def get_peak_position(self, input_data: numpy.ndarray) ‑> numpy.ndarray
-
Calculate naive peak position index as maximum outlier in window of individual waveforms.
Args
input_data
- Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns
amp_val
- Array with peak position index values of shape (number of waveforms, ).
Expand source code
def get_peak_position(self, input_data: np.ndarray) -> np.ndarray: """Calculate naive peak position index as maximum outlier in window of individual waveforms. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: amp_val: Array with peak position index values of shape (number of waveforms, ). """ min_pos = np.argmin(input_data[:, self.bounds_peak[0]:self.bounds_peak[-1]], axis=1) # Correct for lower peak window boundary. # Zero offset if lower boundary None (defined to falsify in boolean or). min_pos_corrected = min_pos + (self.bounds_peak[0] or 0) return min_pos_corrected
def set_bounds(self, input_tuple: Tuple[Optional[int], Optional[int]], input_tuple_name: str) ‑> Tuple[Optional[int], Optional[int]]
-
Check and convert boundary tuples.
Used for
bounds_baseline
andbounds_peak
. Assert that tuple of length 2 with integers.Args
input_tuple
- Tuple to check and convert.
input_tuple_name
- Name of the tuple, used in error messages.
Returns
output_tuple
- Tuple of length 2 with integers.
Expand source code
def set_bounds(self, input_tuple: Tuple[Optional[int], Optional[int]], input_tuple_name: str) -> Tuple[Optional[int], Optional[int]]: """Check and convert boundary tuples. Used for `bounds_baseline` and `bounds_peak`. Assert that tuple of length 2 with integers. Args: input_tuple: Tuple to check and convert. input_tuple_name: Name of the tuple, used in error messages. Returns: output_tuple: Tuple of length 2 with integers. """ # Check that iterable is passed. if not hasattr(input_tuple, '__iter__'): raise TypeError('Expected iterable (ideally tuple) for {}.'.format(input_tuple_name)) # Check length of passed iterable. if len(input_tuple) != 2: raise ValueError('Expected tuple of length 2 for {}.'.format(input_tuple_name)) # Convert to list to make mutable. output_list = list(input_tuple) # Try to convert values to int if necessary. for i, el in enumerate(output_list): if (type(el) not in [int, np.int64]) and (el is not None): try: output_list[i] = int(el) warnings.warn('Converted element {} in {} to int. This may lead to unwanted behavior. ' 'Recommended to directly pass tuples of integers.'.format(i, input_tuple_name)) except Exception: raise TypeError('Expected tuple of integers / Nones for {}.'.format(input_tuple_name)) # Convert to tuple to make immutable. output_tuple = tuple(output_list) # Assert that tuple elements of ascending order. if np.all([el is not None for el in output_tuple]) and output_tuple[0] >= output_tuple[1]: raise ValueError('Elements in {} must be of ascending order or None.format(input_tuple_name)') return output_tuple
class FullWindow (n_slices: int = 7)
-
Basic processing functions using the full waveform window for baseline / peak calculations without dedicated peak finding. Applicable especially for naive random dark count finding.
Attributes
n_slices
- Number of slices for robust baseline and baseline standard deviation calculation.
Init of the FullWindow class.
Defines baseline and peak window boundaries as None to use full waveform window.
Args
n_slices
- Number of slices for robust baseline and baseline standard deviation calculation.
Expand source code
class FullWindow(FixedWindow): """Basic processing functions using the full waveform window for baseline / peak calculations without dedicated peak finding. Applicable especially for naive random dark count finding. Attributes: n_slices: Number of slices for robust baseline and baseline standard deviation calculation. """ def __init__(self, n_slices: int = 7): """Init of the FullWindow class. Defines baseline and peak window boundaries as None to use full waveform window. Args: n_slices: Number of slices for robust baseline and baseline standard deviation calculation. """ FixedWindow.__init__(self, bounds_baseline=(None, None), bounds_peak=(None, None)) self.n_slices = n_slices def get_baseline(self, input_data: np.ndarray) -> np.ndarray: """Calculate baselines of individual waveforms with reduced peaks impact. Apply more robust approach reducing the pull by localized peaks by calculating the median in `n_slices` slices of approximately (but not necessarily exactly) equal size and taking the median of those values as baseline value. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: bsl: Array with baseline values of shape (number of waveforms, ). """ bsl = np.median(np.asarray([np.median(el, axis=1) for el in np.array_split(input_data, self.n_slices, axis=1)]).T, axis=1) return bsl def get_baseline_std(self, input_data: np.ndarray) -> np.ndarray: """Calculate baseline standard deviations of individual waveforms with reduced peaks impact. Apply more robust approach reducing the pull by localized peaks by calculating the standard deviation in `n_slices` slices of approximately (but not necessarily exactly) equal size and taking the median of those values as baseline standard deviation value. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: bsl: Array with baseline standard deviation values of shape (number of waveforms, ). """ bsl_std = np.median(np.asarray([np.std(el, axis=1) for el in np.array_split(input_data, self.n_slices, axis=1)]).T, axis=1) return bsl_std
Ancestors
Methods
def get_baseline(self, input_data: numpy.ndarray) ‑> numpy.ndarray
-
Calculate baselines of individual waveforms with reduced peaks impact.
Apply more robust approach reducing the pull by localized peaks by calculating the median in
n_slices
slices of approximately (but not necessarily exactly) equal size and taking the median of those values as baseline value.Args
input_data
- Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns
bsl
- Array with baseline values of shape (number of waveforms, ).
Expand source code
def get_baseline(self, input_data: np.ndarray) -> np.ndarray: """Calculate baselines of individual waveforms with reduced peaks impact. Apply more robust approach reducing the pull by localized peaks by calculating the median in `n_slices` slices of approximately (but not necessarily exactly) equal size and taking the median of those values as baseline value. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: bsl: Array with baseline values of shape (number of waveforms, ). """ bsl = np.median(np.asarray([np.median(el, axis=1) for el in np.array_split(input_data, self.n_slices, axis=1)]).T, axis=1) return bsl
def get_baseline_std(self, input_data: numpy.ndarray) ‑> numpy.ndarray
-
Calculate baseline standard deviations of individual waveforms with reduced peaks impact.
Apply more robust approach reducing the pull by localized peaks by calculating the standard deviation in
n_slices
slices of approximately (but not necessarily exactly) equal size and taking the median of those values as baseline standard deviation value.Args
input_data
- Array with ADC data of shape (number of waveforms, time bins per waveform).
Returns
bsl
- Array with baseline standard deviation values of shape (number of waveforms, ).
Expand source code
def get_baseline_std(self, input_data: np.ndarray) -> np.ndarray: """Calculate baseline standard deviations of individual waveforms with reduced peaks impact. Apply more robust approach reducing the pull by localized peaks by calculating the standard deviation in `n_slices` slices of approximately (but not necessarily exactly) equal size and taking the median of those values as baseline standard deviation value. Args: input_data: Array with ADC data of shape (number of waveforms, time bins per waveform). Returns: bsl: Array with baseline standard deviation values of shape (number of waveforms, ). """ bsl_std = np.median(np.asarray([np.std(el, axis=1) for el in np.array_split(input_data, self.n_slices, axis=1)]).T, axis=1) return bsl_std
Inherited members