Пример #1
0
class StateScale(StateBase):
    shape = ClassTypeParameter(SampleShape)
    thickness = PositiveFloatParameter()
    width = PositiveFloatParameter()
    height = PositiveFloatParameter()
    scale = PositiveFloatParameter()

    # Geometry from the file
    shape_from_file = ClassTypeParameter(SampleShape)
    thickness_from_file = PositiveFloatParameter()
    width_from_file = PositiveFloatParameter()
    height_from_file = PositiveFloatParameter()

    def __init__(self):
        super(StateScale, self).__init__()

        # The default geometry
        self.shape_from_file = SampleShape.Disc

        # The default values are 1mm
        self.thickness_from_file = 1.
        self.width_from_file = 1.
        self.height_from_file = 1.

    def validate(self):
        pass
Пример #2
0
class StateReductionMode(StateReductionBase, StateBase):
    reduction_mode = ClassTypeParameter(ReductionMode)
    reduction_dimensionality = ClassTypeParameter(ReductionDimensionality)

    # Fitting
    merge_fit_mode = ClassTypeParameter(FitModeForMerge)
    merge_shift = FloatParameter()
    merge_scale = FloatParameter()
    merge_range_min = FloatWithNoneParameter()
    merge_range_max = FloatWithNoneParameter()

    # Map from detector type to detector name
    detector_names = DictParameter()

    def __init__(self):
        super(StateReductionMode, self).__init__()
        self.reduction_mode = ISISReductionMode.LAB
        self.reduction_dimensionality = ReductionDimensionality.OneDim

        # Set the shifts to defaults which essentially don't do anything.
        self.merge_shift = 0.0
        self.merge_scale = 1.0
        self.merge_fit_mode = FitModeForMerge.NoFit
        self.merge_range_min = None
        self.merge_range_max = None

        # Set the detector names to empty strings
        self.detector_names = {
            DetectorType.to_string(DetectorType.LAB): "",
            DetectorType.to_string(DetectorType.HAB): ""
        }

    def get_merge_strategy(self):
        return [ISISReductionMode.LAB, ISISReductionMode.HAB]

    def get_all_reduction_modes(self):
        return [ISISReductionMode.LAB, ISISReductionMode.HAB]

    def get_detector_name_for_reduction_mode(self, reduction_mode):
        if reduction_mode is ISISReductionMode.LAB:
            bank_type = DetectorType.to_string(DetectorType.LAB)
        elif reduction_mode is ISISReductionMode.HAB:
            bank_type = DetectorType.to_string(DetectorType.HAB)
        else:
            raise RuntimeError(
                "SANStateReductionISIS: There is no detector available for the"
                " reduction mode {0}.".format(reduction_mode))
        return self.detector_names[bank_type]

    def validate(self):
        pass
Пример #3
0
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)))
Пример #4
0
class StateWavelength(StateBase):
    rebin_type = ClassTypeParameter(RebinType)
    wavelength_low = PositiveFloatParameter()
    wavelength_high = PositiveFloatParameter()
    wavelength_step = PositiveFloatParameter()
    wavelength_step_type = ClassTypeParameter(RangeStepType)

    def __init__(self):
        super(StateWavelength, self).__init__()
        self.rebin_type = RebinType.Rebin

    def validate(self):
        is_invalid = dict()
        if one_is_none(
            [self.wavelength_low, self.wavelength_high, self.wavelength_step]):
            entry = validation_message(
                "A wavelength entry has not been set.",
                "Make sure that all entries for the wavelength are set.", {
                    "wavelength_low": self.wavelength_low,
                    "wavelength_high": self.wavelength_high,
                    "wavelength_step": self.wavelength_step
                })
            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)

        if is_invalid:
            raise ValueError(
                "StateWavelength: The provided inputs are illegal. "
                "Please see: {0}".format(json.dumps(is_invalid, indent=4)))
Пример #5
0
class StateTransmissionFit(StateBase):
    fit_type = ClassTypeParameter(FitType)
    polynomial_order = PositiveIntegerParameter()
    wavelength_low = PositiveFloatWithNoneParameter()
    wavelength_high = PositiveFloatWithNoneParameter()

    def __init__(self):
        super(StateTransmissionFit, self).__init__()
        self.fit_type = FitType.Log
        self.polynomial_order = 0

    def validate(self):  # noqa
        is_invalid = {}
        if self.fit_type is not FitType.Polynomial and self.polynomial_order != 0:
            entry = validation_message(
                "You can only set a polynomial order of you selected polynomial fitting.",
                "Make sure that you select polynomial fitting.", {
                    "fit_type": self.fit_type,
                    "polynomial_order": self.polynomial_order
                })
            is_invalid.update(entry)

        if not is_pure_none_or_not_none(
            [self.wavelength_low, self.wavelength_high]):
            entry = validation_message(
                "Inconsistent wavelength setting.",
                "Make sure that you have specified both wavelength bounds (or none).",
                {
                    "wavelength_low": self.wavelength_low,
                    "wavelength_high": self.wavelength_high
                })
            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)
        if is_invalid:
            raise ValueError(
                "StateTransmissionFit: The provided inputs are illegal. "
                "Please see: {0}".format(json.dumps(is_invalid)))
Пример #6
0
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
Пример #7
0
class StateMove(StateBase):
    sample_offset = FloatParameter()
    sample_offset_direction = ClassTypeParameter(Coordinates)
    detectors = DictParameter()
    monitor_names = DictParameter()

    def __init__(self):
        super(StateMove, self).__init__()

        # Setup the sample offset
        self.sample_offset = 0.0

        # The sample offset direction is Z for the ISIS instruments
        self.sample_offset_direction = CanonicalCoordinates.Z

    def validate(self):
        # No validation of the descriptors on this level, let potential exceptions from detectors "bubble" up
        for key in self.detectors:
            self.detectors[key].validate()

        # If the detectors are empty, then we raise
        if not self.detectors:
            raise ValueError("No detectors have been set.")
Пример #8
0
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
Пример #9
0
class StateNormalizeToMonitor(StateBase):
    prompt_peak_correction_min = PositiveFloatWithNoneParameter()
    prompt_peak_correction_max = PositiveFloatWithNoneParameter()
    prompt_peak_correction_enabled = BoolParameter()

    rebin_type = ClassTypeParameter(RebinType)
    wavelength_low = PositiveFloatListParameter()
    wavelength_high = PositiveFloatListParameter()
    wavelength_step = PositiveFloatParameter()
    wavelength_step_type = ClassTypeParameter(RangeStepType)

    background_TOF_general_start = FloatParameter()
    background_TOF_general_stop = FloatParameter()
    background_TOF_monitor_start = DictParameter()
    background_TOF_monitor_stop = DictParameter()

    incident_monitor = PositiveIntegerParameter()

    def __init__(self):
        super(StateNormalizeToMonitor, self).__init__()
        self.background_TOF_monitor_start = {}
        self.background_TOF_monitor_stop = {}
        self.prompt_peak_correction_enabled = False

        # Default rebin type is a standard Rebin
        self.rebin_type = RebinType.Rebin

    def validate(self):
        is_invalid = {}
        # -----------------
        # incident Monitor
        # -----------------
        if self.incident_monitor is None:
            is_invalid.update(
                {"incident_monitor": "An incident monitor must be specified."})

        # -----------------
        # Prompt peak
        # -----------------
        if not is_pure_none_or_not_none(
            [self.prompt_peak_correction_min, self.prompt_peak_correction_max
             ]):
            entry = validation_message(
                "A prompt peak correction entry has not been set.",
                "Make sure that either all prompt peak entries have been set or none.",
                {
                    "prompt_peak_correction_min":
                    self.prompt_peak_correction_min,
                    "prompt_peak_correction_max":
                    self.prompt_peak_correction_max
                })
            is_invalid.update(entry)

        if is_not_none_and_first_larger_than_second(
            [self.prompt_peak_correction_min,
             self.prompt_peak_correction_max]):
            entry = validation_message(
                "Incorrect prompt peak correction bounds.",
                "Make sure that lower prompt peak time bound is smaller then upper bound.",
                {
                    "prompt_peak_correction_min":
                    self.prompt_peak_correction_min,
                    "prompt_peak_correction_max":
                    self.prompt_peak_correction_max
                })
            is_invalid.update(entry)

        # -----------------
        # Wavelength rebin
        # -----------------
        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)

        # ----------------------
        # Background correction
        # ----------------------
        if not is_pure_none_or_not_none([
                self.background_TOF_general_start,
                self.background_TOF_general_stop
        ]):
            entry = validation_message(
                "A general background TOF entry has not been set.",
                "Make sure that either all general background TOF entries are set or none.",
                {
                    "background_TOF_general_start":
                    self.background_TOF_general_start,
                    "background_TOF_general_stop":
                    self.background_TOF_general_stop
                })
            is_invalid.update(entry)

        if is_not_none_and_first_larger_than_second([
                self.background_TOF_general_start,
                self.background_TOF_general_stop
        ]):
            entry = validation_message(
                "Incorrect general background TOF bounds.",
                "Make sure that lower general background TOF bound is smaller then upper bound.",
                {
                    "background_TOF_general_start":
                    self.background_TOF_general_start,
                    "background_TOF_general_stop":
                    self.background_TOF_general_stop
                })
            is_invalid.update(entry)

        if not is_pure_none_or_not_none([
                self.background_TOF_monitor_start,
                self.background_TOF_monitor_stop
        ]):
            entry = validation_message(
                "A monitor background TOF entry has not been set.",
                "Make sure that either all monitor background TOF entries are set or none.",
                {
                    "background_TOF_monitor_start":
                    self.background_TOF_monitor_start,
                    "background_TOF_monitor_stop":
                    self.background_TOF_monitor_stop
                })
            is_invalid.update(entry)

        if self.background_TOF_monitor_start is not None and self.background_TOF_monitor_stop is not None:
            if len(self.background_TOF_monitor_start) != len(
                    self.background_TOF_monitor_stop):
                entry = validation_message(
                    "The monitor background TOF entries have a length mismatch.",
                    "Make sure that all monitor background TOF entries have the same length.",
                    {
                        "background_TOF_monitor_start":
                        self.background_TOF_monitor_start,
                        "background_TOF_monitor_stop":
                        self.background_TOF_monitor_stop
                    })
                is_invalid.update(entry)
            for key_start, value_start in list(
                    self.background_TOF_monitor_start.items()):
                if key_start not in self.background_TOF_monitor_stop:
                    entry = validation_message(
                        "The monitor background TOF had spectrum number mismatch.",
                        "Make sure that all monitors have entries for start and stop.",
                        {
                            "background_TOF_monitor_start":
                            self.background_TOF_monitor_start,
                            "background_TOF_monitor_stop":
                            self.background_TOF_monitor_stop
                        })
                    is_invalid.update(entry)
                else:
                    value_stop = self.background_TOF_monitor_stop[key_start]
                    if value_start > value_stop:
                        entry = validation_message(
                            "Incorrect monitor background TOF bounds.",
                            "Make sure that lower monitor background TOF bound is"
                            " smaller then upper bound.", {
                                "background_TOF_monitor_start":
                                self.background_TOF_monitor_start,
                                "background_TOF_monitor_stop":
                                self.background_TOF_monitor_stop
                            })
                        is_invalid.update(entry)

        if is_invalid:
            raise ValueError(
                "StateMoveDetector: The provided inputs are illegal. "
                "Please see: {0}".format(json.dumps(is_invalid)))
Пример #10
0
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)))
Пример #11
0
class StateReductionMode(StateReductionBase, StateBase):
    reduction_mode = ClassTypeParameter(ReductionMode)
    reduction_dimensionality = ClassTypeParameter(ReductionDimensionality)
    merge_max = FloatWithNoneParameter()
    merge_min = FloatWithNoneParameter()
    merge_mask = BoolParameter()

    # Fitting
    merge_fit_mode = ClassTypeParameter(FitModeForMerge)
    merge_shift = FloatParameter()
    merge_scale = FloatParameter()
    merge_range_min = FloatWithNoneParameter()
    merge_range_max = FloatWithNoneParameter()

    # Map from detector type to detector name
    detector_names = DictParameter()

    def __init__(self):
        super(StateReductionMode, self).__init__()
        self.reduction_mode = ISISReductionMode.LAB
        self.reduction_dimensionality = ReductionDimensionality.OneDim

        # Set the shifts to defaults which essentially don't do anything.
        self.merge_shift = 0.0
        self.merge_scale = 1.0
        self.merge_fit_mode = FitModeForMerge.NoFit
        self.merge_range_min = None
        self.merge_range_max = None
        self.merge_max = None
        self.merge_min = None
        self.merge_mask = False

        # Set the detector names to empty strings
        self.detector_names = {
            DetectorType.to_string(DetectorType.LAB): "",
            DetectorType.to_string(DetectorType.HAB): ""
        }

    def get_merge_strategy(self):
        return [ISISReductionMode.LAB, ISISReductionMode.HAB]

    def get_all_reduction_modes(self):
        return [ISISReductionMode.LAB, ISISReductionMode.HAB]

    def get_detector_name_for_reduction_mode(self, reduction_mode):
        if reduction_mode is ISISReductionMode.LAB:
            bank_type = DetectorType.to_string(DetectorType.LAB)
        elif reduction_mode is ISISReductionMode.HAB:
            bank_type = DetectorType.to_string(DetectorType.HAB)
        else:
            raise RuntimeError(
                "SANStateReductionISIS: There is no detector available for the"
                " reduction mode {0}.".format(reduction_mode))
        return self.detector_names[bank_type]

    def validate(self):
        is_invalid = {}
        if self.merge_max and self.merge_min:
            if self.merge_min > self.merge_max:
                is_invalid.update({
                    "StateReduction":
                    "The minimum of the merge region is greater than the maximum."
                })

        if is_invalid:
            raise ValueError(
                "StateReduction: The provided inputs are illegal. "
                "Please see: {0}".format(json.dumps(is_invalid)))
class StateCalculateTransmission(StateBase):
    # -----------------------
    # Transmission
    # -----------------------
    transmission_radius_on_detector = PositiveFloatParameter()
    transmission_roi_files = StringListParameter()
    transmission_mask_files = StringListParameter()

    default_transmission_monitor = PositiveIntegerParameter()
    transmission_monitor = PositiveIntegerParameter()

    default_incident_monitor = PositiveIntegerParameter()
    incident_monitor = PositiveIntegerParameter()

    # ----------------------
    # Prompt peak correction
    # ----------------------
    prompt_peak_correction_min = PositiveFloatParameter()
    prompt_peak_correction_max = PositiveFloatParameter()
    prompt_peak_correction_enabled = BoolParameter()

    # ----------------
    # Wavelength rebin
    # ----------------
    rebin_type = ClassTypeParameter(RebinType)
    wavelength_low = PositiveFloatParameter()
    wavelength_high = PositiveFloatParameter()
    wavelength_step = PositiveFloatParameter()
    wavelength_step_type = ClassTypeParameter(RangeStepType)

    use_full_wavelength_range = BoolParameter()
    wavelength_full_range_low = PositiveFloatParameter()
    wavelength_full_range_high = PositiveFloatParameter()

    # -----------------------
    # Background correction
    # ----------------------
    background_TOF_general_start = FloatParameter()
    background_TOF_general_stop = FloatParameter()
    background_TOF_monitor_start = DictParameter()
    background_TOF_monitor_stop = DictParameter()
    background_TOF_roi_start = FloatParameter()
    background_TOF_roi_stop = FloatParameter()

    # -----------------------
    # Fit
    # ----------------------
    fit = DictParameter()

    def __init__(self):
        super(StateCalculateTransmission, self).__init__()
        # The keys of this dictionaries are the spectrum number of the monitors (as a string)
        self.background_TOF_monitor_start = {}
        self.background_TOF_monitor_stop = {}

        self.fit = {DataType.to_string(DataType.Sample): StateTransmissionFit(),
                    DataType.to_string(DataType.Can): StateTransmissionFit()}
        self.use_full_wavelength_range = False

        # Default rebin type is a standard Rebin
        self.rebin_type = RebinType.Rebin

        self.prompt_peak_correction_enabled = False

    def validate(self):  # noqa
        is_invalid = {}
        # -----------------
        # Incident monitor
        # -----------------
        if self.incident_monitor is None and self.default_incident_monitor is None:
            entry = validation_message("No incident monitor was specified.",
                                       "Make sure that incident monitor has been specified.",
                                       {"incident_monitor": self.incident_monitor,
                                        "default_incident_monitor": self.default_incident_monitor})
            is_invalid.update(entry)

        # --------------
        # Transmission, either we need some ROI (ie radius, roi files /mask files) or a transmission monitor
        # --------------
        has_no_transmission_monitor_setting = self.transmission_monitor is None and\
                                              self.default_transmission_monitor is None  # noqa
        has_no_transmission_roi_setting = self.transmission_radius_on_detector is None and\
                                          self.transmission_roi_files is None  # noqa
        if has_no_transmission_monitor_setting and has_no_transmission_roi_setting:
            entry = validation_message("No transmission settings were specified.",
                                       "Make sure that transmission settings are specified.",
                                       {"transmission_monitor": self.transmission_monitor,
                                        "default_transmission_monitor": self.default_transmission_monitor,
                                        "transmission_radius_on_detector": self.transmission_radius_on_detector,
                                        "transmission_roi_files": self.transmission_roi_files})
            is_invalid.update(entry)

        # -----------------
        # Prompt peak
        # -----------------
        if not is_pure_none_or_not_none([self.prompt_peak_correction_min, self.prompt_peak_correction_max]):
            entry = validation_message("Inconsistent prompt peak setting.",
                                       "Make sure that you have specified both prompt peak bounds (or none).",
                                       {"prompt_peak_correction_min": self.prompt_peak_correction_min,
                                        "prompt_peak_correction_max": self.prompt_peak_correction_max})
            is_invalid.update(entry)

        if is_not_none_and_first_larger_than_second([self.prompt_peak_correction_min, self.prompt_peak_correction_max]):
            entry = validation_message("Incorrect prompt peak bounds.",
                                       "Make sure that lower prompt peak bound is smaller then upper bound.",
                                       {"prompt_peak_correction_min": self.prompt_peak_correction_min,
                                        "prompt_peak_correction_max": self.prompt_peak_correction_max})
            is_invalid.update(entry)

        # -----------------
        # Wavelength rebin
        # -----------------
        if one_is_none([self.wavelength_low, self.wavelength_high, self.wavelength_step, self.wavelength_step_type,
                        self.wavelength_step_type, self.rebin_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,
                                        "rebin_type": self.rebin_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)

        if self.use_full_wavelength_range:
            if self.wavelength_full_range_low is None or self.wavelength_full_range_high is None:
                entry = validation_message("Incorrect full wavelength settings.",
                                           "Make sure that both full wavelength entries have been set.",
                                           {"wavelength_full_range_low": self.wavelength_full_range_low,
                                            "wavelength_full_range_high": self.wavelength_full_range_high})
                is_invalid.update(entry)
            if is_not_none_and_first_larger_than_second([self.wavelength_full_range_low,
                                                         self.wavelength_full_range_high]):
                entry = validation_message("Incorrect wavelength bounds.",
                                           "Make sure that lower full wavelength bound is smaller then upper bound.",
                                           {"wavelength_full_range_low": self.wavelength_full_range_low,
                                            "wavelength_full_range_high": self.wavelength_full_range_high})
                is_invalid.update(entry)

        # ----------------------
        # Background correction
        # ----------------------
        if not is_pure_none_or_not_none([self.background_TOF_general_start, self.background_TOF_general_stop]):
            entry = validation_message("A general background TOF entry has not been set.",
                                       "Make sure that either all general background TOF entries are set or none.",
                                       {"background_TOF_general_start": self.background_TOF_general_start,
                                        "background_TOF_general_stop": self.background_TOF_general_stop})
            is_invalid.update(entry)
        if is_not_none_and_first_larger_than_second([self.background_TOF_general_start,
                                                     self.background_TOF_general_stop]):
            entry = validation_message("Incorrect general background TOF bounds.",
                                       "Make sure that lower general background TOF bound is smaller then upper bound.",
                                       {"background_TOF_general_start": self.background_TOF_general_start,
                                        "background_TOF_general_stop": self.background_TOF_general_stop})
            is_invalid.update(entry)

        if not is_pure_none_or_not_none([self.background_TOF_roi_start, self.background_TOF_roi_stop]):
            entry = validation_message("A ROI background TOF entry has not been set.",
                                       "Make sure that either all ROI background TOF entries are set or none.",
                                       {"background_TOF_roi_start": self.background_TOF_roi_start,
                                        "background_TOF_roi_stop": self.background_TOF_roi_stop})
            is_invalid.update(entry)

        if is_not_none_and_first_larger_than_second([self.background_TOF_roi_start,
                                                     self.background_TOF_roi_stop]):
            entry = validation_message("Incorrect ROI background TOF bounds.",
                                       "Make sure that lower ROI background TOF bound is smaller then upper bound.",
                                       {"background_TOF_roi_start": self.background_TOF_roi_start,
                                        "background_TOF_roi_stop": self.background_TOF_roi_stop})
            is_invalid.update(entry)

        if not is_pure_none_or_not_none([self.background_TOF_monitor_start, self.background_TOF_monitor_stop]):
            entry = validation_message("A monitor background TOF entry has not been set.",
                                       "Make sure that either all monitor background TOF entries are set or none.",
                                       {"background_TOF_monitor_start": self.background_TOF_monitor_start,
                                        "background_TOF_monitor_stop": self.background_TOF_monitor_stop})
            is_invalid.update(entry)

        if self.background_TOF_monitor_start is not None and self.background_TOF_monitor_stop is not None:
            if len(self.background_TOF_monitor_start) != len(self.background_TOF_monitor_stop):
                entry = validation_message("The monitor background TOF entries have a length mismatch.",
                                           "Make sure that all monitor background TOF entries have the same length.",
                                           {"background_TOF_monitor_start": self.background_TOF_monitor_start,
                                            "background_TOF_monitor_stop": self.background_TOF_monitor_stop})
                is_invalid.update(entry)
            for key_start, value_start in list(self.background_TOF_monitor_start.items()):
                if key_start not in self.background_TOF_monitor_stop:
                    entry = validation_message("The monitor background TOF had spectrum number mismatch.",
                                               "Make sure that all monitors have entries for start and stop.",
                                               {"background_TOF_monitor_start": self.background_TOF_monitor_start,
                                                "background_TOF_monitor_stop": self.background_TOF_monitor_stop})
                    is_invalid.update(entry)
                else:
                    value_stop = self.background_TOF_monitor_stop[key_start]
                    if value_start > value_stop:
                        entry = validation_message("Incorrect monitor background TOF bounds.",
                                                   "Make sure that lower monitor background TOF bound is"
                                                   " smaller then upper bound.",
                                                   {"background_TOF_monitor_start": self.background_TOF_monitor_start,
                                                    "background_TOF_monitor_stop": self.background_TOF_monitor_stop})
                        is_invalid.update(entry)

        # -----
        # Fit
        # -----
        self.fit[DataType.to_string(DataType.Sample)].validate()
        self.fit[DataType.to_string(DataType.Can)].validate()

        if is_invalid:
            raise ValueError("StateCalculateTransmission: The provided inputs are illegal. "
                             "Please see: {0}".format(json.dumps(is_invalid)))
Пример #13
0
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)))