def _run_all_reductions(self, centre1, centre2):
     sample_quartiles = self._run_quartile_reduction(scatter_workspace=self.sample_scatter,
                                                     transmission_workspace=self.sample_transmission,
                                                     direct_workspace=self.sample_direct,
                                                     scatter_monitor_workspace=self.sample_scatter_monitor,
                                                     data_type="Sample",
                                                     centre1=centre1, centre2=centre2)
     if self.can_scatter:
         can_quartiles = self._run_quartile_reduction(scatter_workspace=self.can_scatter,
                                                      transmission_workspace=self.can_transmission,
                                                      direct_workspace=self.can_direct,
                                                      data_type="Can",
                                                      scatter_monitor_workspace=self.can_scatter_monitor,
                                                      centre1=centre1, centre2=centre2)
         for key in sample_quartiles:
             sample_quartiles[key] = perform_can_subtraction(sample_quartiles[key], can_quartiles[key], self)
     return sample_quartiles
Exemple #2
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))
    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))