Source code for quicknxs.interfaces.configuration

# pylint: disable=invalid-name, line-too-long, too-few-public-methods, too-many-instance-attributes, wrong-import-order, bare-except
"""Application configuration, including reduction options."""

from enum import IntEnum
from typing import List, Optional

from quicknxs.interfaces.data_handling.instrument import Instrument

# TODO: extract to file based parameter setting
# TODO: add docstring for Configuration attributes


[docs] class BinningType(IntEnum): """Enum for binning types.""" NONE = 0 NORMAL = 1 CONST_Q = 2 def __str__(self): """ Return a user-friendly string representation of the binning type for UI display. Returns ------- str The name of the binning type ("None", "Normal", or "Const Q"). """ return { BinningType.NONE: "None", BinningType.NORMAL: "Normal", BinningType.CONST_Q: "Const Q", }[self]
[docs] class Configuration(object): """Hold reduction options. Class Attributes ---------------- TBD Instance Attributes ------------------- metadata_roi_peak: List[float] Peak range of interest, obtained from data set's metadata metadata_roi_bck: List[float] Background range of interest, obtained from data set's metadata """ # Choice of axes for off-specular binning QX_VS_QZ = 0 KZI_VS_KZF = 1 DELTA_KZ_VS_QZ = 3 ### Global variables sample_size = 10 wl_bandwidth = 3.2 # Binning Q step global option binning_type_global = BinningType.NONE binning_q_step_global = -0.02 # Normalize to unity when stitching normalize_to_unity = True total_reflectivity_q_cutoff = 0.01 # Use all cross-sections when stitching global_stitching = False # Use a polynomial curve fit when stitching polynomial_stitching = False polynomial_stitching_degree = 3 polynomial_stitching_points = 3 # Dead time options apply_deadtime = False paralyzable_deadtime = True deadtime_value = 4.2 deadtime_tof_step = 100 # Direct beam uses the same low res roi as the data run lock_direct_beam_y = False # Number of events below which we throw away a workspace nbr_events_min = 100 # Peak finder options use_roi = True update_peak_range = False use_peak_finder = False use_low_res_finder = False use_tight_bck = False bck_offset = 5 use_metadata_bck_roi = True
[docs] @classmethod def setup_default_values(cls): """Initialize class variables - only used for testing purposes.""" cls.QX_VS_QZ = 0 cls.KZI_VS_KZF = 1 cls.DELTA_KZ_VS_QZ = 3 cls.sample_size = 10 cls.wl_bandwidth = 3.2 cls.binning_type_global = BinningType.NONE cls.binning_q_step_global = -0.02 cls.normalize_to_unity = True cls.total_reflectivity_q_cutoff = 0.01 cls.global_stitching = False cls.polynomial_stitching = False cls.polynomial_stitching_degree = 3 cls.polynomial_stitching_points = 3 cls.apply_deadtime = False cls.paralyzable_deadtime = True cls.deadtime_value = 4.2 cls.deadtime_tof_step = 100 cls.lock_direct_beam_y = False cls.nbr_events_min = 100 cls.use_roi = True cls.update_peak_range = False cls.use_peak_finder = False cls.use_low_res_finder = False cls.use_tight_bck = False cls.bck_offset = 5 cls.use_metadata_bck_roi = True
def __init__(self): self.instrument = Instrument() # Number of TOF bins self.tof_bins = 400 self.tof_range: Optional[List[float]] = None # Bin type: # 0 = Constant bin width # 1 = Constant Q bin width # 2 = Constant 1/wavelength bin width self.tof_bin_type = 0 # Threshold under which we skip a cross-section, as fraction of the max count self.count_threshold = 0.01 self.tof_overwrite = None ### Reduction parameters # Use region of interest specified in metadata self.metadata_roi_peak: List[int] = [] self.metadata_roi_bck: List[int] = [] self.set_direct_pixel = False self.direct_pixel_overwrite = 0.0 self.set_direct_angle_offset = False self.direct_angle_offset_overwrite = 0 self.use_dangle = False # Options to override the range self.peak_position = 130 self.peak_width = 20 self.low_res_position = 130 self.low_res_width = 20 self.bck_position = 30 self.bck_width = 20 # Subtract background self.subtract_background = True # Overall scaling factor self.scaling_factor = 1.0 # Error in the scaling factor self.scaling_error = 0.0 # Cut first and last N points self.cut_first_n_points = 1 self.cut_last_n_points = 1 # Binning options self.binning_type_run = BinningType.NONE self.binning_q_step_run = -0.02 # UI elements self.normalize_x_tof = False self.x_wl_map = False self.angle_map = False self.log_1d = True self.log_2d = True # Off-specular options self.off_spec_x_axis = Configuration.DELTA_KZ_VS_QZ self.off_spec_slice = False self.off_spec_qz_list = [] self.off_spec_slice_qz_min = 0.05 self.off_spec_slice_qz_max = 0.07 self.off_spec_err_weight = False self.off_spec_nxbins = 450 self.off_spec_nybins = 200 # Off-specular smoothing self.apply_smoothing = False self.off_spec_sigmas = 3 self.off_spec_sigmax = 0.0005 self.off_spec_sigmay = 0.0005 self.off_spec_x_min = -0.015 self.off_spec_x_max = 0.015 self.off_spec_y_min = 0.0 self.off_spec_y_max = 0.15 # GISANS options self.gisans_wl_min = 2.0 self.gisans_wl_max = 8.0 self.gisans_wl_npts = 2 self.gisans_qy_npts = 50 self.gisans_qz_npts = 50 self.gisans_use_pf = False self.gisans_slice = False self.gisans_slice_qz_min = 0.015 self.gisans_slice_qz_max = 0.035 # Reduction options self.match_direct_beam = False self.direct_beam = None @property def peak_roi(self): peak_min = int(round(float(self.peak_position) - (float(self.peak_width) / 2.0))) peak_max = int(round(float(self.peak_position) + (float(self.peak_width) / 2.0))) return [peak_min, peak_max] @peak_roi.setter def peak_roi(self, value): self.peak_position = (value[1] + value[0]) / 2.0 self.peak_width = value[1] - value[0] @property def low_res_roi(self): peak_min = int(round(float(self.low_res_position) - (float(self.low_res_width) / 2.0))) peak_max = int(round(float(self.low_res_position) + (float(self.low_res_width) / 2.0))) return [peak_min, peak_max] @low_res_roi.setter def low_res_roi(self, value): self.low_res_position = (value[1] + value[0]) / 2.0 self.low_res_width = value[1] - value[0] @property def bck_roi(self): peak_min = int(round(float(self.bck_position) - (float(self.bck_width) / 2.0))) peak_max = int(round(float(self.bck_position) + (float(self.bck_width) / 2.0))) return [peak_min, peak_max] @bck_roi.setter def bck_roi(self, value): self.bck_position = (value[1] + value[0]) / 2.0 self.bck_width = value[1] - value[0]
[docs] def get_direct_beam_low_res_roi(data_conf: Configuration, direct_beam_conf: Configuration) -> List[int]: """Get the direct beam low res ROI. Either from the data run or from the direct beam depending on the configuration `data_conf.lock_direct_beam_y` Returns ------- List[int] The pixel range of the direct beam ROI in the low res direction (y) """ def _as_ints(a): return [int(round(a[0])), int(round(a[1]))] if data_conf.lock_direct_beam_y: # use same low res ROI as the data run direct_beam_low_res_roi = _as_ints(data_conf.low_res_roi) else: # use ROI from the direct beam table direct_beam_low_res_roi = _as_ints(direct_beam_conf.low_res_roi) return direct_beam_low_res_roi