class StateAdjustmentFiles(StateBase): pixel_adjustment_file = StringParameter() wavelength_adjustment_file = StringParameter() def __init__(self): super(StateAdjustmentFiles, self).__init__() def validate(self): is_invalid = {} # TODO: It would be nice to have a typed parameter for files which checks if a file input exists or not. # This is very low priority, but would be nice to have. if is_invalid: raise ValueError( "StateAdjustmentFiles: The provided inputs are illegal. " "Please see: {0}".format(json.dumps(is_invalid)))
class VerySimpleState(StateBase): string_parameter = StringParameter() def __init__(self): super(VerySimpleState, self).__init__() self.string_parameter = "test_in_very_simple" def validate(self): pass
class StateWavelengthAndPixelAdjustment(StateBase): wavelength_low = PositiveFloatParameter() wavelength_high = PositiveFloatParameter() wavelength_step = PositiveFloatParameter() wavelength_step_type = ClassTypeParameter(RangeStepType) adjustment_files = DictParameter() idf_path = StringParameter() def __init__(self): super(StateWavelengthAndPixelAdjustment, self).__init__() self.adjustment_files = { DetectorType.to_string(DetectorType.LAB): StateAdjustmentFiles(), DetectorType.to_string(DetectorType.HAB): StateAdjustmentFiles() } def validate(self): is_invalid = {} if one_is_none([ self.wavelength_low, self.wavelength_high, self.wavelength_step, self.wavelength_step_type ]): entry = validation_message( "A wavelength entry has not been set.", "Make sure that all entries are set.", { "wavelength_low": self.wavelength_low, "wavelength_high": self.wavelength_high, "wavelength_step": self.wavelength_step, "wavelength_step_type": self.wavelength_step_type }) is_invalid.update(entry) if is_not_none_and_first_larger_than_second( [self.wavelength_low, self.wavelength_high]): entry = validation_message( "Incorrect wavelength bounds.", "Make sure that lower wavelength bound is smaller then upper bound.", { "wavelength_low": self.wavelength_low, "wavelength_high": self.wavelength_high }) is_invalid.update(entry) try: self.adjustment_files[DetectorType.to_string( DetectorType.LAB)].validate() self.adjustment_files[DetectorType.to_string( DetectorType.HAB)].validate() except ValueError as e: is_invalid.update({"adjustment_files": str(e)}) if is_invalid: raise ValueError( "StateWavelengthAndPixelAdjustment: The provided inputs are illegal. " "Please see: {0}".format(json.dumps(is_invalid)))
class StateCompatibility(StateBase): use_compatibility_mode = BoolParameter() time_rebin_string = StringParameter() def __init__(self): super(StateCompatibility, self).__init__() self.use_compatibility_mode = False self.time_rebin_string = "" def validate(self): pass
class StateSave(StateBase): zero_free_correction = BoolParameter() file_format = ClassTypeListParameter(SaveType) # Settings for the output name user_specified_output_name = StringWithNoneParameter() user_specified_output_name_suffix = StringParameter() use_reduction_mode_as_suffix = BoolParameter() def __init__(self): super(StateSave, self).__init__() self.zero_free_correction = True def validate(self): pass
class StateBaseTestClass(StateBase): string_parameter = StringParameter() bool_parameter = BoolParameter() float_parameter = FloatParameter() positive_float_parameter = PositiveFloatParameter() positive_integer_parameter = PositiveIntegerParameter() dict_parameter = DictParameter() float_with_none_parameter = FloatWithNoneParameter() positive_float_with_none_parameter = PositiveFloatWithNoneParameter() float_list_parameter = FloatListParameter() string_list_parameter = StringListParameter() positive_integer_list_parameter = PositiveIntegerListParameter() class_type_parameter = ClassTypeParameter(TestType) class_type_list_parameter = ClassTypeListParameter(TestType) def __init__(self): super(StateBaseTestClass, self).__init__() def validate(self): pass
class SimpleState(StateBase): string_parameter = StringParameter() bool_parameter = BoolParameter() float_parameter = FloatParameter() positive_float_parameter = PositiveFloatParameter() positive_integer_parameter = PositiveIntegerParameter() dict_parameter = DictParameter() float_with_none_parameter = FloatWithNoneParameter() positive_float_with_none_parameter = PositiveFloatWithNoneParameter() float_list_parameter = FloatListParameter() string_list_parameter = StringListParameter() positive_integer_list_parameter = PositiveIntegerListParameter() class_type_parameter = ClassTypeParameter(TestType) class_type_list_parameter = ClassTypeListParameter(TestType) sub_state_very_simple = TypedParameter(VerySimpleState, validator_sub_state) def __init__(self): super(SimpleState, self).__init__() self.string_parameter = "String_in_SimpleState" self.bool_parameter = False # We explicitly leave out the float_parameter self.positive_float_parameter = 1. self.positive_integer_parameter = 6 self.dict_parameter = {"1": 123, "2": "test"} self.float_with_none_parameter = 325. # We expliclty leave out the positive_float_with_none_parameter self.float_list_parameter = [123., 234.] self.string_list_parameter = ["test1", "test2"] self.positive_integer_list_parameter = [1, 2, 3] self.class_type_parameter = TestType.TypeA self.class_type_list_parameter = [TestType.TypeA, TestType.TypeB] self.sub_state_very_simple = VerySimpleState() def validate(self): pass
class SANSParameterTestClass2(object): my_string_parameter = StringParameter() my_bool_parameter = BoolParameter()
class StateMaskDetector(StateBase): # Vertical strip masks single_vertical_strip_mask = PositiveIntegerListParameter() range_vertical_strip_start = PositiveIntegerListParameter() range_vertical_strip_stop = PositiveIntegerListParameter() # Horizontal strip masks single_horizontal_strip_mask = PositiveIntegerListParameter() range_horizontal_strip_start = PositiveIntegerListParameter() range_horizontal_strip_stop = PositiveIntegerListParameter() # Spectrum Block block_horizontal_start = PositiveIntegerListParameter() block_horizontal_stop = PositiveIntegerListParameter() block_vertical_start = PositiveIntegerListParameter() block_vertical_stop = PositiveIntegerListParameter() # Spectrum block cross block_cross_horizontal = PositiveIntegerListParameter() block_cross_vertical = PositiveIntegerListParameter() # Time/Bin mask bin_mask_start = FloatListParameter() bin_mask_stop = FloatListParameter() # Name of the detector detector_name = StringParameter() detector_name_short = StringParameter() # Single Spectra single_spectra = PositiveIntegerListParameter() # Spectrum Range spectrum_range_start = PositiveIntegerListParameter() spectrum_range_stop = PositiveIntegerListParameter() def __init__(self): super(StateMaskDetector, self).__init__() def validate(self): is_invalid = {} # -------------------- # Vertical strip mask # -------------------- range_check(self.range_vertical_strip_start, self.range_vertical_strip_stop, is_invalid, "range_vertical_strip_start", "range_vertical_strip_stop", "range_vertical_strip") # -------------------- # Horizontal strip mask # -------------------- range_check(self.range_horizontal_strip_start, self.range_horizontal_strip_stop, is_invalid, "range_horizontal_strip_start", "range_horizontal_strip_stop", "range_horizontal_strip") # -------------------- # Block mask # -------------------- range_check(self.block_horizontal_start, self.block_horizontal_stop, is_invalid, "block_horizontal_start", "block_horizontal_stop", "block_horizontal") range_check(self.block_vertical_start, self.block_vertical_stop, is_invalid, "block_vertical_start", "block_vertical_stop", "block_vertical") # -------------------- # Time/Bin mask # -------------------- range_check(self.bin_mask_start, self.bin_mask_stop, is_invalid, "bin_mask_start", "bin_mask_stop", "bin_mask") if not self.detector_name: entry = validation_message( "Missing detector name.", "Make sure that the detector names are set.", {"detector_name": self.detector_name}) is_invalid.update(entry) if not self.detector_name_short: entry = validation_message( "Missing short detector name.", "Make sure that the short detector names are set.", {"detector_name_short": self.detector_name_short}) is_invalid.update(entry) # -------------------- # Spectrum Range # -------------------- range_check(self.spectrum_range_start, self.spectrum_range_stop, is_invalid, "spectrum_range_start", "spectrum_range_stop", "spectrum_range") if is_invalid: raise ValueError( "StateMoveDetectorISIS: The provided inputs are illegal. " "Please see: {0}".format(json.dumps(is_invalid)))
class StateMask(StateBase): # Radius Mask radius_min = FloatParameter() radius_max = FloatParameter() # Bin mask bin_mask_general_start = FloatListParameter() bin_mask_general_stop = FloatListParameter() # Mask files mask_files = StringListParameter() # Angle masking phi_min = FloatParameter() phi_max = FloatParameter() use_mask_phi_mirror = BoolParameter() # Beam stop beam_stop_arm_width = PositiveFloatParameter() beam_stop_arm_angle = FloatParameter() beam_stop_arm_pos1 = FloatParameter() beam_stop_arm_pos2 = FloatParameter() # Clear commands clear = BoolParameter() clear_time = BoolParameter() # The detector dependent masks detectors = DictParameter() # The idf path of the instrument idf_path = StringParameter() def __init__(self): super(StateMask, self).__init__() # Setup the detectors self.detectors = { DetectorType.to_string(DetectorType.LAB): StateMaskDetector(), DetectorType.to_string(DetectorType.HAB): StateMaskDetector() } # IDF Path self.idf_path = "" def validate(self): is_invalid = dict() # -------------------- # Radius Mask # -------------------- # Radius mask rule: the min radius must be less or equal to the max radius if self.radius_max is not None and self.radius_min is not None and\ self.radius_max != -1 and self.radius_min != -1: # noqa if self.radius_min > 0 and self.radius_max > 0 and ( self.radius_min > self.radius_max): entry = validation_message( "Incorrect radius bounds.", "Makes sure that the lower radius bound is smaller than the" " upper radius bound.", { "radius_min": self.radius_min, "radius_max": self.radius_max }) is_invalid.update(entry) # -------------------- # General bin mask # -------------------- range_check(self.bin_mask_general_start, self.bin_mask_general_stop, is_invalid, "bin_mask_general_start", "bin_mask_general_stop", "bin_mask_general") # -------------------- # Mask files # -------------------- if self.mask_files: for mask_file in self.mask_files: if not find_full_file_path(mask_file): entry = validation_message( "Mask file not found.", "Makes sure that the mask file is in your path", {"mask_file": self.mask_files}) is_invalid.update(entry) # -------------------- # Detectors # -------------------- for _, value in list(self.detectors.items()): value.validate() if is_invalid: raise ValueError("StateMask: The provided inputs are illegal. " "Please see: {0}".format(json.dumps(is_invalid)))
class StateData(StateBase): ALL_PERIODS = sans.common.constants.ALL_PERIODS sample_scatter = StringParameter() sample_scatter_period = PositiveIntegerParameter() sample_transmission = StringParameter() sample_transmission_period = PositiveIntegerParameter() sample_direct = StringParameter() sample_direct_period = PositiveIntegerParameter() can_scatter = StringParameter() can_scatter_period = PositiveIntegerParameter() can_transmission = StringParameter() can_transmission_period = PositiveIntegerParameter() can_direct = StringParameter() can_direct_period = PositiveIntegerParameter() calibration = StringParameter() sample_scatter_run_number = PositiveIntegerParameter() sample_scatter_is_multi_period = BoolParameter() instrument = ClassTypeParameter(SANSInstrument) idf_file_path = StringParameter() ipf_file_path = StringParameter() def __init__(self): super(StateData, self).__init__() # Setup default values for periods self.sample_scatter_period = StateData.ALL_PERIODS self.sample_transmission_period = StateData.ALL_PERIODS self.sample_direct_period = StateData.ALL_PERIODS self.can_scatter_period = StateData.ALL_PERIODS self.can_transmission_period = StateData.ALL_PERIODS self.can_direct_period = StateData.ALL_PERIODS # This should be reset by the builder. Setting this to NoInstrument ensure that we will trip early on, # in case this is not set, for example by not using the builders. self.instrument = SANSInstrument.NoInstrument def validate(self): is_invalid = dict() # A sample scatter must be specified if self.sample_scatter is None: entry = validation_message( "Sample scatter was not specified.", "Make sure that the sample scatter file is specified.", {"sample_scatter": self.sample_scatter}) is_invalid.update(entry) # If the sample transmission/direct was specified, then a sample direct/transmission is required if not is_pure_none_or_not_none( [self.sample_transmission, self.sample_direct]): entry = validation_message( "If the sample transmission is specified then, the direct run needs to be " "specified too.", "Make sure that the transmission and direct runs are both specified (or none).", { "sample_transmission": self.sample_transmission, "sample_direct": self.sample_direct }) is_invalid.update(entry) # If the can transmission/direct was specified, then this requires the can scatter if (self.can_direct or self.can_transmission) and (not self.can_scatter): entry = validation_message( "If the can transmission is specified then the can scatter run needs to be " "specified too.", "Make sure that the can scatter file is set.", { "can_scatter": self.can_scatter, "can_transmission": self.can_transmission, "can_direct": self.can_direct }) is_invalid.update(entry) # If a can transmission/direct was specified, then the other can entries need to be specified as well. if self.can_scatter and not is_pure_none_or_not_none( [self.can_transmission, self.can_direct]): entry = validation_message( "Inconsistent can transmission setting.", "Make sure that the can transmission and can direct runs are set (or none of" " them).", { "can_transmission": self.can_transmission, "can_direct": self.can_direct }) is_invalid.update(entry) if is_invalid: raise ValueError("StateData: The provided inputs are illegal. " "Please see: {0}".format(json.dumps(is_invalid)))
class StateConvertToQ(StateBase): reduction_dimensionality = ClassTypeParameter(ReductionDimensionality) use_gravity = BoolParameter() gravity_extra_length = PositiveFloatParameter() radius_cutoff = PositiveFloatParameter() wavelength_cutoff = PositiveFloatParameter() # 1D settings q_min = PositiveFloatParameter() q_max = PositiveFloatParameter() q_1d_rebin_string = StringParameter() # 2D settings q_xy_max = PositiveFloatParameter() q_xy_step = PositiveFloatParameter() q_xy_step_type = ClassTypeParameter(RangeStepType) # ----------------------- # Q Resolution specific # --------------------- use_q_resolution = BoolParameter() q_resolution_collimation_length = PositiveFloatParameter() q_resolution_delta_r = PositiveFloatParameter() moderator_file = StringParameter() # Circular aperture settings q_resolution_a1 = PositiveFloatParameter() q_resolution_a2 = PositiveFloatParameter() # Rectangular aperture settings q_resolution_h1 = PositiveFloatParameter() q_resolution_h2 = PositiveFloatParameter() q_resolution_w1 = PositiveFloatParameter() q_resolution_w2 = PositiveFloatParameter() def __init__(self): super(StateConvertToQ, self).__init__() self.reduction_dimensionality = ReductionDimensionality.OneDim self.use_gravity = False self.gravity_extra_length = 0.0 self.use_q_resolution = False self.radius_cutoff = 0.0 self.wavelength_cutoff = 0.0 def validate(self): is_invalid = {} # 1D Q settings if not is_pure_none_or_not_none([self.q_min, self.q_max]): entry = validation_message( "The q boundaries for the 1D reduction are inconsistent.", "Make sure that both q boundaries are set (or none).", { "q_min": self.q_min, "q_max": self.q_max }) is_invalid.update(entry) if is_not_none_and_first_larger_than_second([self.q_min, self.q_max]): entry = validation_message( "Incorrect q bounds for 1D reduction.", "Make sure that the lower q bound is smaller than the upper q bound.", { "q_min": self.q_min, "q_max": self.q_max }) is_invalid.update(entry) if self.reduction_dimensionality is ReductionDimensionality.OneDim: if self.q_min is None or self.q_max is None: entry = validation_message( "Q bounds not set for 1D reduction.", "Make sure to set the q boundaries when using a 1D reduction.", { "q_min": self.q_min, "q_max": self.q_max }) is_invalid.update(entry) if self.q_1d_rebin_string is not None: if self.q_1d_rebin_string == "": entry = validation_message( "Q rebin string does not seem to be valid.", "Make sure to provide a valid rebin string", {"q_1d_rebin_string": self.q_1d_rebin_string}) is_invalid.update(entry) elif not is_valid_rebin_string(self.q_1d_rebin_string): entry = validation_message( "Q rebin string does not seem to be valid.", "Make sure to provide a valid rebin string", {"q_1d_rebin_string": self.q_1d_rebin_string}) is_invalid.update(entry) # QXY settings if self.reduction_dimensionality is ReductionDimensionality.TwoDim: if self.q_xy_max is None or self.q_xy_step is None: entry = validation_message( "Q bounds not set for 2D reduction.", "Make sure that the q_max value bound and the step for the 2D reduction.", { "q_xy_max": self.q_xy_max, "q_xy_step": self.q_xy_step }) is_invalid.update(entry) # Q Resolution settings if self.use_q_resolution: if not is_pure_none_or_not_none( [self.q_resolution_a1, self.q_resolution_a2]): entry = validation_message( "Inconsistent circular geometry.", "Make sure that both diameters for the circular apertures are set.", { "q_resolution_a1": self.q_resolution_a1, "q_resolution_a2": self.q_resolution_a2 }) is_invalid.update(entry) if not is_pure_none_or_not_none([ self.q_resolution_h1, self.q_resolution_h2, self.q_resolution_w1, self.q_resolution_w2 ]): entry = validation_message( "Inconsistent rectangular geometry.", "Make sure that both diameters for the circular apertures are set.", { "q_resolution_h1": self.q_resolution_h1, "q_resolution_h2": self.q_resolution_h2, "q_resolution_w1": self.q_resolution_w1, "q_resolution_w2": self.q_resolution_w2 }) is_invalid.update(entry) if all(element is None for element in [ self.q_resolution_a1, self.q_resolution_a2, self.q_resolution_w1, self.q_resolution_w2, self.q_resolution_h1, self.q_resolution_h2 ]): entry = validation_message( "Aperture is undefined.", "Make sure that you set the geometry for a circular or a " "rectangular aperture.", { "q_resolution_a1": self.q_resolution_a1, "q_resolution_a2": self.q_resolution_a2, "q_resolution_h1": self.q_resolution_h1, "q_resolution_h2": self.q_resolution_h2, "q_resolution_w1": self.q_resolution_w1, "q_resolution_w2": self.q_resolution_w2 }) is_invalid.update(entry) if self.moderator_file is None: entry = validation_message( "Missing moderator file.", "Make sure to specify a moderator file when using q resolution.", {"moderator_file": self.moderator_file}) is_invalid.update(entry) is_invalid.update({ "moderator_file": "A moderator file is required for the q resolution calculation." }) if is_invalid: raise ValueError( "StateMoveDetectorISIS: The provided inputs are illegal. " "Please see: {0}".format(json.dumps(is_invalid)))