Example #1
0
def get_detector_size_from_sans_file(state, detector):
    instrument_file = get_instrument_paths_for_sans_file(state.data.sample_scatter)

    if detector == DetectorType.HAB:
        x_dim = get_named_elements_from_ipf_file(instrument_file[1], "high-angle-detector-num-columns",
                                                 float)['high-angle-detector-num-columns']
        y_dim = get_named_elements_from_ipf_file(instrument_file[1], "high-angle-detector-num-rows",
                                                 float)['high-angle-detector-num-rows']
    else:
        x_dim = get_named_elements_from_ipf_file(instrument_file[1], "low-angle-detector-num-columns", float)[
                                                 'low-angle-detector-num-columns']
        y_dim = get_named_elements_from_ipf_file(instrument_file[1], "low-angle-detector-num-rows", float)[
                                                 'low-angle-detector-num-rows']

    return x_dim, y_dim
def get_detector_size_from_sans_file(state, detector):
    instrument_file = get_instrument_paths_for_sans_file(state.data.sample_scatter)

    if detector == DetectorType.HAB:
        x_dim = get_named_elements_from_ipf_file(instrument_file[1], "high-angle-detector-num-columns",
                                                 float)['high-angle-detector-num-columns']
        y_dim = get_named_elements_from_ipf_file(instrument_file[1], "high-angle-detector-num-rows",
                                                 float)['high-angle-detector-num-rows']
    else:
        x_dim = get_named_elements_from_ipf_file(instrument_file[1], "low-angle-detector-num-columns", float)[
                                                 'low-angle-detector-num-columns']
        y_dim = get_named_elements_from_ipf_file(instrument_file[1], "low-angle-detector-num-rows", float)[
                                                 'low-angle-detector-num-rows']

    return x_dim, y_dim
    def reset_to_defaults_for_instrument(self, file_information = None):
        r_range = {}
        instrument = None

        if file_information:
            instrument_file_path = get_instrument_paths_for_sans_file(file_information=file_information)
            r_range = get_named_elements_from_ipf_file(instrument_file_path[1],
                                                       ["beam_centre_radius_min", "beam_centre_radius_max"], float)
            instrument = file_information.get_instrument()

        self._max_iterations = 10
        self._r_min = r_range["beam_centre_radius_min"] if "beam_centre_radius_min" in r_range else 60
        self._r_max = r_range["beam_centre_radius_max"] if "beam_centre_radius_max" in r_range else 280
        self._left_right = True
        self._up_down = True
        self._tolerance = 0.0001251
        self._lab_pos_1 = ''
        self._lab_pos_2 = ''
        self._hab_pos_2 = ''
        self._hab_pos_1 = ''
        self.scale_1 = 1000
        self.scale_2 = 1000
        self.COM = False
        self.verbose = False
        self.q_min = 0.01
        self.q_max = 0.1
        self._component = DetectorType.LAB
        self.update_lab = True
        self.update_hab = True

        if instrument == SANSInstrument.LARMOR:
            self.scale_1 = 1.0
Example #4
0
def set_detector_names(state, ipf_path):
    """
    Sets the detectors names on a State object which has a `detector` map entry, e.g. StateMask

    @param state: the state object
    @param ipf_path: the path to the Instrument Parameter File
    """
    lab_keyword = DetectorType.to_string(DetectorType.LAB)
    hab_keyword = DetectorType.to_string(DetectorType.HAB)
    detector_names = {lab_keyword: "low-angle-detector-name",
                      hab_keyword: "high-angle-detector-name"}
    detector_names_short = {lab_keyword: "low-angle-detector-short-name",
                            hab_keyword: "high-angle-detector-short-name"}

    names_to_search = []
    names_to_search.extend(detector_names.values())
    names_to_search.extend(detector_names_short.values())

    found_detector_names = get_named_elements_from_ipf_file(ipf_path, names_to_search, str)

    for detector_type in state.detectors:
        try:
            detector_name_tag = detector_names[detector_type]
            detector_name_short_tag = detector_names_short[detector_type]
            detector_name = found_detector_names[detector_name_tag]
            detector_name_short = found_detector_names[detector_name_short_tag]
        except KeyError:
            continue

        state.detectors[detector_type].detector_name = detector_name
        state.detectors[detector_type].detector_name_short = detector_name_short
    def get_position_steps(self, state):
        instrument_file = get_instrument_paths_for_sans_file(state.data.sample_scatter)
        position_1_step = get_named_elements_from_ipf_file(
            instrument_file[1], ["centre-finder-step-size"], float)['centre-finder-step-size']
        try:
            position_2_step = get_named_elements_from_ipf_file(
                instrument_file[1], ["centre-finder-step-size2"], float)['centre-finder-step-size2']
        except:
            position_2_step = position_1_step

        find_direction = self.getProperty("Direction").value
        if find_direction == FindDirectionEnum.LEFT_RIGHT.value:
            position_2_step = 0.0
        elif find_direction == FindDirectionEnum.UP_DOWN.value:
            position_1_step = 0.0

        return position_1_step, position_2_step
def set_default_incident_monitor(normalize_monitor_info, data_info):
    """
    The default incident monitor is stored on the IPF.
    :param normalize_monitor_info: a StateNormalizeMonitor object on which we set the default value
    :param data_info: a StateData object
    """
    ipf_file_path = data_info.ipf_file_path
    named_element = "default-incident-monitor-spectrum"
    monitor_spectrum_tag_to_search = [named_element]
    found_monitor_spectrum = get_named_elements_from_ipf_file(ipf_file_path, monitor_spectrum_tag_to_search, int)
    if named_element in found_monitor_spectrum:
        normalize_monitor_info.incident_monitor = found_monitor_spectrum[named_element]
Example #7
0
def set_default_incident_monitor(normalize_monitor_info, data_info):
    """
    The default incident monitor is stored on the IPF.
    :param normalize_monitor_info: a StateNormalizeMonitor object on which we set the default value
    :param data_info: a StateData object
    """
    ipf_file_path = data_info.ipf_file_path
    named_element = "default-incident-monitor-spectrum"
    monitor_spectrum_tag_to_search = [named_element]
    found_monitor_spectrum = get_named_elements_from_ipf_file(
        ipf_file_path, monitor_spectrum_tag_to_search, int)
    if named_element in found_monitor_spectrum:
        normalize_monitor_info.incident_monitor = found_monitor_spectrum[
            named_element]
def set_default_monitors(calculate_transmission_info, data_info):
    """
    The default incident monitor is stored on the IPF.
    :param calculate_transmission_info: a StateCalculateTransmission object on which we set the default value
    :param data_info: a StateData object
    """
    ipf_file_path = data_info.ipf_file_path
    incident_tag = "default-incident-monitor-spectrum"
    transmission_tag = "default-transmission-monitor-spectrum"
    monitors_to_search = [incident_tag, transmission_tag]
    found_monitor_spectrum = get_named_elements_from_ipf_file(ipf_file_path, monitors_to_search, int)
    if incident_tag in found_monitor_spectrum:
        calculate_transmission_info.default_incident_monitor = found_monitor_spectrum[incident_tag]
    if transmission_tag in found_monitor_spectrum:
        calculate_transmission_info.default_transmission_monitor = found_monitor_spectrum[transmission_tag]
Example #9
0
def setup_detectors_from_ipf(reduction_info, data_info):
    ipf_file_path = data_info.ipf_file_path

    detector_names = {DetectorType.to_string(DetectorType.LAB): "low-angle-detector-name",
                      DetectorType.to_string(DetectorType.HAB): "high-angle-detector-name"}

    names_to_search = []
    names_to_search.extend(list(detector_names.values()))

    found_detector_names = get_named_elements_from_ipf_file(ipf_file_path, names_to_search, str)

    for detector_type in list(reduction_info.detector_names.keys()):
        try:
            detector_name_tag = detector_names[detector_type]
            detector_name = found_detector_names[detector_name_tag]
        except KeyError:
            continue
        reduction_info.detector_names[detector_type] = detector_name
Example #10
0
def setup_detectors_from_ipf(reduction_info, data_info):
    ipf_file_path = data_info.ipf_file_path

    detector_names = {DetectorType.to_string(DetectorType.LAB): "low-angle-detector-name",
                      DetectorType.to_string(DetectorType.HAB): "high-angle-detector-name"}

    names_to_search = []
    names_to_search.extend(list(detector_names.values()))

    found_detector_names = get_named_elements_from_ipf_file(ipf_file_path, names_to_search, str)

    for detector_type in list(reduction_info.detector_names.keys()):
        try:
            detector_name_tag = detector_names[detector_type]
            detector_name = found_detector_names[detector_name_tag]
        except KeyError:
            continue
        reduction_info.detector_names[detector_type] = detector_name
Example #11
0
    def test_that_named_entries_in_instrument_parameter_file_can_be_retrieved(self):
        # Arrange
        test_file = "LARMOR00003368"
        file_information_factory = SANSFileInformationFactory()
        file_information = file_information_factory.create_sans_file_information(test_file)
        full_file_path = file_information.get_file_name()

        _, ipf = get_instrument_paths_for_sans_file(full_file_path)
        to_search = ["low-angle-detector-name", "high-angle-detector-short-name"]

        # Act
        results = get_named_elements_from_ipf_file(ipf, to_search, str)

        # Assert
        self.assertTrue(len(results) == 2)

        self.assertTrue(results["low-angle-detector-name"] == "DetectorBench")
        self.assertTrue(results["high-angle-detector-short-name"] == "front")
Example #12
0
    def test_that_named_entries_in_instrument_parameter_file_can_be_retrieved(self):
        # Arrange
        test_file = "LARMOR00003368"
        file_information_factory = SANSFileInformationFactory()
        file_information = file_information_factory.create_sans_file_information(test_file)
        full_file_path = file_information.get_file_name()

        _, ipf = get_instrument_paths_for_sans_file(full_file_path)
        to_search = ["low-angle-detector-name", "high-angle-detector-short-name"]

        # Act
        results = get_named_elements_from_ipf_file(ipf, to_search, str)

        # Assert
        self.assertTrue(len(results) == 2)

        self.assertTrue(results["low-angle-detector-name"] == "DetectorBench")
        self.assertTrue(results["high-angle-detector-short-name"] == "front")
Example #13
0
def set_detector_names(state, ipf_path, invalid_detector_types=None):
    """
    Sets the detectors names on a State object which has a `detector` map entry, e.g. StateMask

    :param state: the state object
    :param ipf_path: the path to the Instrument Parameter File
    :param invalid_detector_types: a list of invalid detector types which don't exist for the instrument
    """
    if invalid_detector_types is None:
        invalid_detector_types = []

    lab_keyword = DetectorType.to_string(DetectorType.LAB)
    hab_keyword = DetectorType.to_string(DetectorType.HAB)
    detector_names = {
        lab_keyword: "low-angle-detector-name",
        hab_keyword: "high-angle-detector-name"
    }
    detector_names_short = {
        lab_keyword: "low-angle-detector-short-name",
        hab_keyword: "high-angle-detector-short-name"
    }

    names_to_search = []
    names_to_search.extend(list(detector_names.values()))
    names_to_search.extend(list(detector_names_short.values()))

    found_detector_names = get_named_elements_from_ipf_file(
        ipf_path, names_to_search, str)

    for detector_type in state.detectors:
        try:
            if DetectorType.from_string(
                    detector_type) in invalid_detector_types:
                continue
            detector_name_tag = detector_names[detector_type]
            detector_name_short_tag = detector_names_short[detector_type]
            detector_name = found_detector_names[detector_name_tag]
            detector_name_short = found_detector_names[detector_name_short_tag]
        except KeyError:
            continue

        state.detectors[detector_type].detector_name = detector_name
        state.detectors[
            detector_type].detector_name_short = detector_name_short
Example #14
0
def setup_detectors_from_ipf(reduction_info, data_info):
    file_name = data_info.sample_scatter
    _, ipf_path = get_instrument_paths_for_sans_file(file_name)

    detector_names = {DetectorType.to_string(DetectorType.LAB): "low-angle-detector-name",
                      DetectorType.to_string(DetectorType.HAB): "high-angle-detector-name"}

    names_to_search = []
    names_to_search.extend(detector_names.values())

    found_detector_names = get_named_elements_from_ipf_file(ipf_path, names_to_search, str)

    for detector_type in reduction_info.detector_names.keys():
        try:
            detector_name_tag = detector_names[detector_type]
            detector_name = found_detector_names[detector_name_tag]
        except KeyError:
            continue
        reduction_info.detector_names[detector_type] = detector_name
Example #15
0
    def reset_to_defaults_for_instrument(self, file_information=None):
        r_range = {}
        instrument = None

        if file_information:
            instrument_file_path = get_instrument_paths_for_sans_file(
                file_information=file_information)
            r_range = get_named_elements_from_ipf_file(
                instrument_file_path[1],
                ["beam_centre_radius_min", "beam_centre_radius_max"], float)
            instrument = file_information.get_instrument()

        self._max_iterations = 10
        self._r_min = r_range[
            "beam_centre_radius_min"] if "beam_centre_radius_min" in r_range else 60
        self._r_max = r_range[
            "beam_centre_radius_max"] if "beam_centre_radius_max" in r_range else 280
        self._left_right = True
        self._up_down = True
        self._tolerance = 0.0001251
        self._lab_pos_1 = ''
        self._lab_pos_2 = ''
        self._hab_pos_2 = ''
        self._hab_pos_1 = ''
        self.scale_1 = 1000
        self.scale_2 = 1000
        self.COM = False
        self.verbose = False
        self.q_min = 0.01
        self.q_max = 0.1
        self._component = DetectorType.LAB
        self.update_lab = True
        self.update_hab = True

        if instrument == SANSInstrument.LARMOR:
            self.scale_1 = 1.0
Example #16
0
def set_detector_names(state, ipf_path, invalid_detector_types=None):
    """
    Sets the detectors names on a State object which has a `detector` map entry, e.g. StateMask

    :param state: the state object
    :param ipf_path: the path to the Instrument Parameter File
    :param invalid_detector_types: a list of invalid detector types which don't exist for the instrument
    """
    if invalid_detector_types is None:
        invalid_detector_types = []

    lab_keyword = DetectorType.to_string(DetectorType.LAB)
    hab_keyword = DetectorType.to_string(DetectorType.HAB)
    detector_names = {lab_keyword: "low-angle-detector-name",
                      hab_keyword: "high-angle-detector-name"}
    detector_names_short = {lab_keyword: "low-angle-detector-short-name",
                            hab_keyword: "high-angle-detector-short-name"}

    names_to_search = []
    names_to_search.extend(list(detector_names.values()))
    names_to_search.extend(list(detector_names_short.values()))

    found_detector_names = get_named_elements_from_ipf_file(ipf_path, names_to_search, str)

    for detector_type in state.detectors:
        try:
            if DetectorType.from_string(detector_type) in invalid_detector_types:
                continue
            detector_name_tag = detector_names[detector_type]
            detector_name_short_tag = detector_names_short[detector_type]
            detector_name = found_detector_names[detector_name_tag]
            detector_name_short = found_detector_names[detector_name_short_tag]
        except KeyError:
            continue
        state.detectors[detector_type].detector_name = detector_name
        state.detectors[detector_type].detector_name_short = detector_name_short
Example #17
0
def get_geometry_information(ipf_path, detector_type):
    """
    This function extracts geometry information for the detector benches.

    The information requested is:
    1. Are we dealing with a rectangular detector
    2. What is the width
    3. What is the height
    4. If the detector has a hole in somewhere then the total number of pixels cannot be solely determined by height
       and width. This provides an override for the number of pixels
    :param ipf_path: The path to the Instrument Parameter File.
    :param detector_type: The type of detector for which we should get the information.
    :return: Geometry information for LAB and HAB as well as the firs
    """
    def create_detector_shape_bundle(num_columns, non_rectangle_width,
                                     num_rows, non_rectangle_height,
                                     num_pixels):
        cols_data = num_columns
        if len(cols_data) > 0:
            rectangular_shape = True
            width = int(cols_data[0])
        else:
            rectangular_shape = False
            width = int(non_rectangle_width[0])

        rows_data = num_rows
        if len(rows_data) > 0:
            height = int(rows_data[0])
        else:
            rectangular_shape = False
            height = int(non_rectangle_height[0])

        number_of_pixels = num_pixels
        if len(number_of_pixels) > 0:
            number_of_pixels_override = int(number_of_pixels[0])
        else:
            number_of_pixels_override = None

        return detector_shape_bundle(
            rectangular_shape=rectangular_shape,
            width=width,
            height=height,
            number_of_pixels_override=number_of_pixels_override)

    # Determine the prefix for the detector
    if detector_type is DetectorType.LAB:
        prefix = "low-angle-detector-"
    elif detector_type is DetectorType.HAB:
        prefix = "high-angle-detector-"
    else:
        raise RuntimeError(
            "MaskingParser: Tyring to get information for unknown "
            "detector {0}".format(str(detector_type)))

    search_items_for_detectors = [
        "num-columns", "non-rectangle-width", "num-rows",
        "non-rectangle-height", "num-pixels"
    ]
    search_items = [prefix + item for item in search_items_for_detectors]
    search_items.append("first-low-angle-spec-number")

    found_items = get_named_elements_from_ipf_file(ipf_path, search_items, int)
    # Some items might not have been found, it they are not in the dictionary, then add an empty list
    not_found_items = [
        item for item in search_items if item not in list(found_items.keys())
    ]
    for not_found_item in not_found_items:
        found_items.update({not_found_item: []})

    # The old code assumed that we have an iterable value, which is not normally true, hence make it iterable
    for key, value in list(found_items.items()):
        if not isinstance(value, Sequence):
            found_items[key] = [value]

    shape = create_detector_shape_bundle(
        num_columns=found_items[prefix + "num-columns"],
        non_rectangle_width=found_items[prefix + "non-rectangle-width"],
        num_rows=found_items[prefix + "num-rows"],
        non_rectangle_height=found_items[prefix + "non-rectangle-height"],
        num_pixels=found_items[prefix + "num-pixels"])

    return geometry_bundle(
        shape=shape,
        first_low_angle_spec_number=found_items["first-low-angle-spec-number"])
    def PyExec(self):
        state = self._get_state()
        state_serialized = state.property_manager
        logger = Logger("CentreFinder")
        logger.notice("Starting centre finder routine...")
        progress = self._get_progress()
        self.scale_1 = 1000
        self.scale_2 = 1000
        verbose = self.getProperty('Verbose').value
        x_start = self.getProperty("Position1Start").value
        y_start = self.getProperty("Position2Start").value

        sample_scatter = self._get_cloned_workspace("SampleScatterWorkspace")
        sample_scatter_monitor = self._get_cloned_workspace("SampleScatterMonitorWorkspace")
        sample_transmission = self._get_cloned_workspace("SampleTransmissionWorkspace")
        sample_direct = self._get_cloned_workspace("SampleDirectWorkspace")

        instrument = sample_scatter.getInstrument()
        if instrument.getName() == 'LARMOR':
            self.scale_1 = 1.0

        can_scatter = self._get_cloned_workspace("CanScatterWorkspace")
        can_scatter_monitor = self._get_cloned_workspace("CanScatterMonitorWorkspace")
        can_transmission = self._get_cloned_workspace("CanTransmissionWorkspace")
        can_direct = self._get_cloned_workspace("CanDirectWorkspace")

        component = self.getProperty("Component").value
        tolerance = self.getProperty("Tolerance").value
        max_iterations = self.getProperty("Iterations").value

        r_min = self.getProperty("RMin").value
        r_max = self.getProperty("RMax").value

        instrument_file = get_instrument_paths_for_sans_file(state.data.sample_scatter)
        position_1_step = get_named_elements_from_ipf_file(
            instrument_file[1], ["centre-finder-step-size"], float)['centre-finder-step-size']
        try:
            position_2_step = get_named_elements_from_ipf_file(
                instrument_file[1], ["centre-finder-step-size2"], float)['centre-finder-step-size2']
        except:
            position_2_step = position_1_step

        find_direction = self.getProperty("Direction").value
        if find_direction == FindDirectionEnum.to_string(FindDirectionEnum.Left_Right):
            position_2_step = 0.0
        elif find_direction == FindDirectionEnum.to_string(FindDirectionEnum.Up_Down):
            position_1_step = 0.0
        centre1 = x_start
        centre2 = y_start
        residueLR = []
        residueTB = []
        centre_1_hold = x_start
        centre_2_hold = y_start
        for j in range(0, max_iterations + 1):
            if(j != 0):
                centre1 += position_1_step
                centre2 += position_2_step

            progress.report("Reducing ... Pos1 " + str(centre1) + " Pos2 " + str(centre2))
            sample_quartiles = self._run_quartile_reduction(sample_scatter, sample_transmission, sample_direct,
                                                            "Sample", sample_scatter_monitor, component,
                                                            state_serialized, centre1, centre2, r_min, r_max)

            if can_scatter:
                can_quartiles = self._run_quartile_reduction(can_scatter, can_transmission, can_direct, "Can",
                                                             can_scatter_monitor, component, state_serialized, centre1,
                                                             centre2, r_min, r_max)
                for key in sample_quartiles:
                    sample_quartiles[key] = perform_can_subtraction(sample_quartiles[key], can_quartiles[key], self)

            if mantidplot:
                output_workspaces = self._publish_to_ADS(sample_quartiles)
                if verbose:
                    self._rename_and_group_workspaces(j, output_workspaces)

            residueLR.append(self._calculate_residuals(sample_quartiles[MaskingQuadrant.Left],
                                                       sample_quartiles[MaskingQuadrant.Right]))
            residueTB.append(self._calculate_residuals(sample_quartiles[MaskingQuadrant.Top],
                                                       sample_quartiles[MaskingQuadrant.Bottom]))
            if(j == 0):
                logger.notice("Itr {0}: ( {1}, {2} )  SX={3:.5g}  SY={4:.5g}".
                              format(j, self.scale_1 * centre1, self.scale_2 * centre2, residueLR[j], residueTB[j]))
                if mantidplot:
                    self._plot_quartiles(output_workspaces, state.data.sample_scatter)

            else:
                # have we stepped across the y-axis that goes through the beam center?
                if residueLR[j] > residueLR[j-1]:
                    # yes with stepped across the middle, reverse direction and half the step size
                    position_1_step = - position_1_step / 2
                if residueTB[j] > residueTB[j-1]:
                    position_2_step = - position_2_step / 2

                logger.notice("Itr {0}: ( {1}, {2} )  SX={3:.5g}  SY={4:.5g}".
                              format(j, self.scale_1 * centre1, self.scale_2 * centre2, residueLR[j], residueTB[j]))

                if (residueLR[j]+residueTB[j]) < (residueLR[j-1]+residueTB[j-1]) or state.compatibility.use_compatibility_mode:
                    centre_1_hold = centre1
                    centre_2_hold = centre2

                if abs(position_1_step) < tolerance and abs(position_2_step) < tolerance:
                    # this is the success criteria, we've close enough to the center
                    logger.notice("Converged - check if stuck in local minimum! ")
                    break

            if j == max_iterations:
                logger.notice("Out of iterations, new coordinates may not be the best")

        self.setProperty("Centre1", centre_1_hold)
        self.setProperty("Centre2", centre_2_hold)

        logger.notice("Centre coordinates updated: [{}, {}]".format(centre_1_hold*self.scale_1, centre_2_hold*self.scale_2))
Example #19
0
    def PyExec(self):
        state = self._get_state()
        state_serialized = state.property_manager
        logger = Logger("CentreFinder")
        logger.notice("Starting centre finder routine...")
        progress = self._get_progress()
        self.scale_1 = 1000
        self.scale_2 = 1000
        verbose = self.getProperty('Verbose').value
        x_start = self.getProperty("Position1Start").value
        y_start = self.getProperty("Position2Start").value

        sample_scatter = self._get_cloned_workspace("SampleScatterWorkspace")
        sample_scatter_monitor = self._get_cloned_workspace(
            "SampleScatterMonitorWorkspace")
        sample_transmission = self._get_cloned_workspace(
            "SampleTransmissionWorkspace")
        sample_direct = self._get_cloned_workspace("SampleDirectWorkspace")

        instrument = sample_scatter.getInstrument()
        if instrument.getName() == 'LARMOR':
            self.scale_1 = 1.0

        can_scatter = self._get_cloned_workspace("CanScatterWorkspace")
        can_scatter_monitor = self._get_cloned_workspace(
            "CanScatterMonitorWorkspace")
        can_transmission = self._get_cloned_workspace(
            "CanTransmissionWorkspace")
        can_direct = self._get_cloned_workspace("CanDirectWorkspace")

        component = self.getProperty("Component").value
        tolerance = self.getProperty("Tolerance").value
        max_iterations = self.getProperty("Iterations").value

        r_min = self.getProperty("RMin").value
        r_max = self.getProperty("RMax").value

        instrument_file = get_instrument_paths_for_sans_file(
            state.data.sample_scatter)
        position_1_step = get_named_elements_from_ipf_file(
            instrument_file[1], "centre-finder-step-size",
            float)['centre-finder-step-size']
        try:
            position_2_step = get_named_elements_from_ipf_file(
                instrument_file[1], "centre-finder-step-size2",
                float)['centre-finder-step-size2']
        except:
            position_2_step = position_1_step

        find_direction = self.getProperty("Direction").value
        if find_direction == FindDirectionEnum.to_string(
                FindDirectionEnum.Left_Right):
            position_2_step = 0.0
        elif find_direction == FindDirectionEnum.to_string(
                FindDirectionEnum.Up_Down):
            position_1_step = 0.0
        centre1 = x_start
        centre2 = y_start
        residueLR = []
        residueTB = []
        centre_1_hold = x_start
        centre_2_hold = y_start
        for j in range(0, max_iterations + 1):
            if (j != 0):
                centre1 += position_1_step
                centre2 += position_2_step

            progress.report("Reducing ... Pos1 " + str(centre1) + " Pos2 " +
                            str(centre2))
            sample_quartiles = self._run_quartile_reduction(
                sample_scatter, sample_transmission, sample_direct, "Sample",
                sample_scatter_monitor, component, state_serialized, centre1,
                centre2, r_min, r_max)

            if can_scatter:
                can_quartiles = self._run_quartile_reduction(
                    can_scatter, can_transmission, can_direct, "Can",
                    can_scatter_monitor, component, state_serialized, centre1,
                    centre2, r_min, r_max)
                for key in sample_quartiles:
                    sample_quartiles[key] = perform_can_subtraction(
                        sample_quartiles[key], can_quartiles[key], self)

            if mantidplot:
                output_workspaces = self._publish_to_ADS(sample_quartiles)
                if verbose:
                    self._rename_and_group_workspaces(j, output_workspaces)

            residueLR.append(
                self._calculate_residuals(
                    sample_quartiles[MaskingQuadrant.Left],
                    sample_quartiles[MaskingQuadrant.Right]))
            residueTB.append(
                self._calculate_residuals(
                    sample_quartiles[MaskingQuadrant.Top],
                    sample_quartiles[MaskingQuadrant.Bottom]))
            if (j == 0):
                logger.notice("Itr " + str(j) + ": (" +
                              str(self.scale_1 * centre1) + ", " +
                              str(self.scale_2 * centre2) + ")  SX=" +
                              str(residueLR[j]) + "  SY=" + str(residueTB[j]))
                if mantidplot:
                    self._plot_quartiles(output_workspaces,
                                         state.data.sample_scatter)

            else:
                # have we stepped across the y-axis that goes through the beam center?
                if residueLR[j] > residueLR[j - 1]:
                    # yes with stepped across the middle, reverse direction and half the step size
                    position_1_step = -position_1_step / 2
                if residueTB[j] > residueTB[j - 1]:
                    position_2_step = -position_2_step / 2

                logger.notice("Itr " + str(j) + ": (" +
                              str(self.scale_1 * centre1) + ", " +
                              str(self.scale_2 * centre2) + ")  SX=" +
                              str(residueLR[j]) + "  SY=" + str(residueTB[j]))

                if (residueLR[j] + residueTB[j]) < (
                        residueLR[j - 1] + residueTB[j - 1]
                ) or state.compatibility.use_compatibility_mode:
                    centre_1_hold = centre1
                    centre_2_hold = centre2

                if abs(position_1_step) < tolerance and abs(
                        position_2_step) < tolerance:
                    # this is the success criteria, we've close enough to the center
                    logger.notice(
                        "Converged - check if stuck in local minimum! ")
                    break

            if j == max_iterations:
                logger.notice(
                    "Out of iterations, new coordinates may not be the best")

        self.setProperty("Centre1", centre_1_hold)
        self.setProperty("Centre2", centre_2_hold)

        logger.notice("Centre coordinates updated: [{}, {}]".format(
            centre_1_hold * self.scale_1, centre_2_hold * self.scale_2))
Example #20
0
def get_geometry_information(ipf_path, detector_type):
    """
    This function extracts geometry information for the detector benches.

    The information requested is:
    1. Are we dealing with a rectangular detector
    2. What is the width
    3. What is the height
    4. If the detector has a hole in somewhere then the total number of pixels cannot be solely determined by height
       and width. This provides an override for the number of pixels
    :param ipf_path: The path to the Instrument Parameter File.
    :param detector_type: The type of detector for which we should get the information.
    :return: Geometry information for LAB and HAB as well as the firs
    """
    def create_detector_shape_bundle(num_columns, non_rectangle_width, num_rows, non_rectangle_height, num_pixels):
        cols_data = num_columns
        if len(cols_data) > 0:
            rectangular_shape = True
            width = int(cols_data[0])
        else:
            rectangular_shape = False
            width = int(non_rectangle_width[0])

        rows_data = num_rows
        if len(rows_data) > 0:
            height = int(rows_data[0])
        else:
            rectangular_shape = False
            height = int(non_rectangle_height[0])

        number_of_pixels = num_pixels
        if len(number_of_pixels) > 0:
            number_of_pixels_override = int(number_of_pixels[0])
        else:
            number_of_pixels_override = None

        return detector_shape_bundle(rectangular_shape=rectangular_shape, width=width, height=height,
                                     number_of_pixels_override=number_of_pixels_override)

    # Determine the prefix for the detector
    if detector_type is DetectorType.LAB:
        prefix = "low-angle-detector-"
    elif detector_type is DetectorType.HAB:
        prefix = "high-angle-detector-"
    else:
        raise RuntimeError("MaskingParser: Tyring to get information for unknown "
                           "detector {0}".format(str(detector_type)))

    search_items_for_detectors = ["num-columns",
                                  "non-rectangle-width", "num-rows",
                                  "non-rectangle-height", "num-pixels"]
    search_items = [prefix + item for item in search_items_for_detectors]
    search_items.append("first-low-angle-spec-number")

    found_items = get_named_elements_from_ipf_file(ipf_path, search_items, int)
    # Some items might not have been found, it they are not in the dictionary, then add an empty list
    not_found_items = [item for item in search_items if item not in list(found_items.keys())]
    for not_found_item in not_found_items:
        found_items.update({not_found_item: []})

    # The old code assumed that we have an iterable value, which is not normally true, hence make it iterable
    for key, value in list(found_items.items()):
        if not isinstance(value, Sequence):
            found_items[key] = [value]

    shape = create_detector_shape_bundle(num_columns=found_items[prefix + "num-columns"],
                                         non_rectangle_width=found_items[prefix + "non-rectangle-width"],
                                         num_rows=found_items[prefix + "num-rows"],
                                         non_rectangle_height=found_items[prefix + "non-rectangle-height"],
                                         num_pixels=found_items[prefix + "num-pixels"])

    return geometry_bundle(shape=shape,
                           first_low_angle_spec_number=found_items["first-low-angle-spec-number"])