def test_that_can_create_versioned_managed_non_child_algorithms(self, alg_manager_mock):
        create_managed_non_child_algorithm("TestAlg", version=2, **{"test_val": 5})
        alg_manager_mock.create.assert_called_once_with("TestAlg", 2)

        alg_manager_mock.reset_mock()
        create_managed_non_child_algorithm("TestAlg", **{"test_val": 5})
        alg_manager_mock.create.assert_called_once_with("TestAlg")
def centre_finder_mass(state, r_min = 0.06, max_iter=10, position_1_start = 0.0, position_2_start = 0.0,
                       tolerance = 0.0001251, component=DetectorType.LAB):
    """
    Finds the beam centre from an initial guess.

    This function finds the centre of the beam by splitting the workspace up into 4 quadrants and running a reduction on
    each. The (left, right) and (up, down) reductions are then compared producing residuals which are minimised through
    repeated iteration.
    :param state: This is a sans state, to find the beam centre for.
    :param r_min: This is the radius of the central beam to mask out.
    :param position_1_start: This is the starting position of the search on the x axis.
    :param position_2_start: This is the starting position of the search on the y axis.
    :param tolerance: This is the tolerance for the search.
    """
    # ------------------------------------------------------------------------------------------------------------------
    # Load the data
    # ------------------------------------------------------------------------------------------------------------------
    workspace_to_name = {SANSDataType.SampleScatter: "SampleScatterWorkspace"}

    workspace_to_monitor = {SANSDataType.SampleScatter: "SampleScatterMonitorWorkSpace"}

    workspaces, monitors = provide_loaded_data(state, False, workspace_to_name, workspace_to_monitor)

    # ------------------------------------------------------------------------------------------------------------------
    # Get reduction settings
    # Split into individual bundles which can be reduced individually. We split here if we have multiple periods or
    # sliced times for example. For the beam centre finder we only use the first period.
    # ------------------------------------------------------------------------------------------------------------------
    reduction_packages = get_reduction_packages(state, workspaces, monitors)
    reduction_package = reduction_packages[0]
    # ------------------------------------------------------------------------------------------------------------------
    # Run reductions (one at a time)
    # ------------------------------------------------------------------------------------------------------------------
    beam_centre_finder = "SANSBeamCentreFinderMassMethod"
    beam_centre_finder_options = {"RMin": r_min/1000, "Centre1": position_1_start,
                                  "Centre2": position_2_start, "Tolerance": tolerance, "Component": DetectorType.to_string(component)}
    beam_centre_alg = create_managed_non_child_algorithm(beam_centre_finder, **beam_centre_finder_options)
    beam_centre_alg.setChild(False)

    # -----------------------------------
    # Set the properties on the algorithm.
    # -----------------------------------
    set_properties_for_beam_centre_algorithm(beam_centre_alg, reduction_package,
                                             workspace_to_name, workspace_to_monitor)
    # -----------------------------------
    #  Run the algorithm.
    # -----------------------------------
    beam_centre_alg.execute()

    # -----------------------------------
    #  Get the outputs
    # -----------------------------------

    centre1 = beam_centre_alg.getProperty("Centre1").value
    centre2 = beam_centre_alg.getProperty("Centre2").value

    return {"pos1": centre1, "pos2": centre2}
Beispiel #3
0
def centre_finder_mass(state, r_min = 0.06, max_iter=10, position_1_start = 0.0, position_2_start = 0.0,
                       tolerance = 0.0001251, component=DetectorType.LAB):
    """
    Finds the beam centre from an initial guess.

    This function finds the centre of the beam by splitting the workspace up into 4 quadrants and running a reduction on
    each. The (left, right) and (up, down) reductions are then compared producing residuals which are minimised through
    repeated iteration.
    :param state: This is a sans state, to find the beam centre for.
    :param r_min: This is the radius of the central beam to mask out.
    :param position_1_start: This is the starting position of the search on the x axis.
    :param position_2_start: This is the starting position of the search on the y axis.
    :param tolerance: This is the tolerance for the search.
    """
    # ------------------------------------------------------------------------------------------------------------------
    # Load the data
    # ------------------------------------------------------------------------------------------------------------------
    workspace_to_name = {SANSDataType.SAMPLE_SCATTER: "SampleScatterWorkspace"}

    workspace_to_monitor = {SANSDataType.SAMPLE_SCATTER: "SampleScatterMonitorWorkSpace"}

    workspaces, monitors = provide_loaded_data(state, False, workspace_to_name, workspace_to_monitor)

    # ------------------------------------------------------------------------------------------------------------------
    # Get reduction settings
    # Split into individual bundles which can be reduced individually. We split here if we have multiple periods or
    # sliced times for example. For the beam centre finder we only use the first period.
    # ------------------------------------------------------------------------------------------------------------------
    reduction_packages = get_reduction_packages(state, workspaces, monitors)
    reduction_package = reduction_packages[0]
    # ------------------------------------------------------------------------------------------------------------------
    # Run reductions (one at a time)
    # ------------------------------------------------------------------------------------------------------------------
    beam_centre_finder = "SANSBeamCentreFinderMassMethod"
    beam_centre_finder_options = {"RMin": r_min/1000, "Centre1": position_1_start,
                                  "Centre2": position_2_start, "Tolerance": tolerance, "Component": component.value}
    beam_centre_alg = create_managed_non_child_algorithm(beam_centre_finder, **beam_centre_finder_options)
    beam_centre_alg.setChild(False)

    # -----------------------------------
    # Set the properties on the algorithm.
    # -----------------------------------
    set_properties_for_beam_centre_algorithm(beam_centre_alg, reduction_package,
                                             workspace_to_name, workspace_to_monitor)
    # -----------------------------------
    #  Run the algorithm.
    # -----------------------------------
    beam_centre_alg.execute()

    # -----------------------------------
    #  Get the outputs
    # -----------------------------------

    centre1 = beam_centre_alg.getProperty("Centre1").value
    centre2 = beam_centre_alg.getProperty("Centre2").value

    return {"pos1": centre1, "pos2": centre2}
def provide_loaded_data(state, use_optimizations, workspace_to_name,
                        workspace_to_monitor):
    """
    Provide the data for reduction.


    :param state: a SANSState object.
    :param use_optimizations: if optimizations are enabled, then the load mechanism will search for workspaces on the
                              ADS.
    :param workspace_to_name: a map of SANSDataType vs output-property name of SANSLoad for workspaces
    :param workspace_to_monitor: a map of SANSDataType vs output-property name of SANSLoad for monitor workspaces
    :return: a list fo workspaces and a list of monitor workspaces
    """
    # Load the data
    state_serialized = state.property_manager
    load_name = "SANSLoad"
    load_options = {
        "SANSState": state_serialized,
        "PublishToCache": use_optimizations,
        "UseCached": use_optimizations,
        "MoveWorkspace": False
    }

    # Set the output workspaces
    set_output_workspaces_on_load_algorithm(load_options, state)

    load_alg = create_managed_non_child_algorithm(load_name, **load_options)
    load_alg.execute()

    # Retrieve the data
    workspace_to_count = {
        SANSDataType.SampleScatter: "NumberOfSampleScatterWorkspaces",
        SANSDataType.SampleTransmission:
        "NumberOfSampleTransmissionWorkspaces",
        SANSDataType.SampleDirect: "NumberOfSampleDirectWorkspaces",
        SANSDataType.CanScatter: "NumberOfCanScatterWorkspaces",
        SANSDataType.CanTransmission: "NumberOfCanTransmissionWorkspaces",
        SANSDataType.CanDirect: "NumberOfCanDirectWorkspaces"
    }

    workspaces = get_workspaces_from_load_algorithm(load_alg,
                                                    workspace_to_count,
                                                    workspace_to_name)
    monitors = get_workspaces_from_load_algorithm(load_alg, workspace_to_count,
                                                  workspace_to_monitor)
    return workspaces, monitors
Beispiel #5
0
def centre_finder_new(state,
                      r_min=0.06,
                      r_max=0.26,
                      iterations=10,
                      position_1_start=0.0,
                      position_2_start=0.0,
                      tolerance=0.0001251,
                      find_direction=FindDirectionEnum.ALL,
                      verbose=False,
                      component=DetectorType.LAB):
    """
    Finds the beam centre from a good initial guess.

    This function finds the centre of the beam by splitting the workspace up into 4 quadrants and running a reduction on
    each. The (left, right) and (up, down) reductions are then compared producing residuals which are minimised through
    repeated iteration.
    :param state: This is a sans state, to find the beam centre for.
    :param r_min: This is the inner radius of the quartile mask.
    :param r_max: This is the outer radius of the quartile mask.
    :param max_iter: This is the maximum number of iterations.
    :param position_1_start: This is the starting position of the search on the x axis.
    :param position_2_start: This is the starting position of the search on the y axis.
    :param tolerance: This is the tolerance for the search.
    :param find_direction: This is an enumerator controlling which axis or both should be searched.
    """
    # ------------------------------------------------------------------------------------------------------------------
    # Load the data
    # ------------------------------------------------------------------------------------------------------------------
    workspace_to_name = {
        SANSDataType.SAMPLE_SCATTER: "SampleScatterWorkspace",
        SANSDataType.SAMPLE_TRANSMISSION: "SampleTransmissionWorkspace",
        SANSDataType.SAMPLE_DIRECT: "SampleDirectWorkspace",
        SANSDataType.CAN_SCATTER: "CanScatterWorkspace",
        SANSDataType.CAN_TRANSMISSION: "CanTransmissionWorkspace",
        SANSDataType.CAN_DIRECT: "CanDirectWorkspace"
    }

    workspace_to_monitor = {
        SANSDataType.SAMPLE_SCATTER: "SampleScatterMonitorWorkSpace",
        SANSDataType.CAN_SCATTER: "CanScatterMonitorWorkspace"
    }

    workspaces, monitors = provide_loaded_data(state, False, workspace_to_name,
                                               workspace_to_monitor)

    # ------------------------------------------------------------------------------------------------------------------
    # Get reduction settings
    # Split into individual bundles which can be reduced individually. We split here if we have multiple periods or
    # sliced times for example. For the beam centre finder we only use the first period.
    # ------------------------------------------------------------------------------------------------------------------
    reduction_packages = get_reduction_packages(state, workspaces, monitors)
    reduction_package = reduction_packages[0]

    # ------------------------------------------------------------------------------------------------------------------
    # Setup the beam centre finder algorithm.
    # ------------------------------------------------------------------------------------------------------------------
    beam_centre_finder = "SANSBeamCentreFinder"
    beam_centre_finder_options = {
        "Iterations": iterations,
        "RMin": r_min / 1000,
        "RMax": r_max / 1000,
        "Position1Start": position_1_start,
        "Position2Start": position_2_start,
        "Tolerance": tolerance,
        "Direction": find_direction.value,
        "Verbose": verbose,
        "Component": component.value
    }
    beam_centre_alg = create_managed_non_child_algorithm(
        beam_centre_finder, **beam_centre_finder_options)
    beam_centre_alg.setChild(False)
    set_properties_for_beam_centre_algorithm(beam_centre_alg,
                                             reduction_package,
                                             workspace_to_name,
                                             workspace_to_monitor)
    # -----------------------------------
    #  Run the beam centre finder algorithm.
    # -----------------------------------
    beam_centre_alg.execute()

    # -----------------------------------
    #  Get the outputs
    # -----------------------------------
    centre1 = beam_centre_alg.getProperty("Centre1").value
    centre2 = beam_centre_alg.getProperty("Centre2").value

    return {"pos1": centre1, "pos2": centre2}
def centre_finder_new(state, r_min = 0.06, r_max = 0.26, iterations = 10, position_1_start = 0.0, position_2_start = 0.0
                      , tolerance = 0.0001251, find_direction = FindDirectionEnum.All, verbose=False, component=DetectorType.LAB):
    """
    Finds the beam centre from a good initial guess.

    This function finds the centre of the beam by splitting the workspace up into 4 quadrants and running a reduction on
    each. The (left, right) and (up, down) reductions are then compared producing residuals which are minimised through
    repeated iteration.
    :param state: This is a sans state, to find the beam centre for.
    :param r_min: This is the inner radius of the quartile mask.
    :param r_max: This is the outer radius of the quartile mask.
    :param max_iter: This is the maximum number of iterations.
    :param position_1_start: This is the starting position of the search on the x axis.
    :param position_2_start: This is the starting position of the search on the y axis.
    :param tolerance: This is the tolerance for the search.
    :param find_direction: This is an enumerator controlling which axis or both should be searched.
    """
    # ------------------------------------------------------------------------------------------------------------------
    # Load the data
    # ------------------------------------------------------------------------------------------------------------------
    workspace_to_name = {SANSDataType.SampleScatter: "SampleScatterWorkspace",
                         SANSDataType.SampleTransmission: "SampleTransmissionWorkspace",
                         SANSDataType.SampleDirect: "SampleDirectWorkspace",
                         SANSDataType.CanScatter: "CanScatterWorkspace",
                         SANSDataType.CanTransmission: "CanTransmissionWorkspace",
                         SANSDataType.CanDirect: "CanDirectWorkspace"}

    workspace_to_monitor = {SANSDataType.SampleScatter: "SampleScatterMonitorWorkSpace",
                            SANSDataType.CanScatter: "CanScatterMonitorWorkspace"}

    workspaces, monitors = provide_loaded_data(state, False, workspace_to_name, workspace_to_monitor)

    # ------------------------------------------------------------------------------------------------------------------
    # Get reduction settings
    # Split into individual bundles which can be reduced individually. We split here if we have multiple periods or
    # sliced times for example. For the beam centre finder we only use the first period.
    # ------------------------------------------------------------------------------------------------------------------
    reduction_packages = get_reduction_packages(state, workspaces, monitors)
    reduction_package = reduction_packages[0]

    # ------------------------------------------------------------------------------------------------------------------
    # Setup the beam centre finder algorithm.
    # ------------------------------------------------------------------------------------------------------------------
    beam_centre_finder = "SANSBeamCentreFinder"
    beam_centre_finder_options = {"Iterations": iterations, "RMin": r_min/1000, "RMax": r_max/1000,
                                  "Position1Start": position_1_start, "Position2Start": position_2_start,
                                  "Tolerance": tolerance, "Direction" : FindDirectionEnum.to_string(find_direction),
                                  "Verbose": verbose, "Component": DetectorType.to_string(component)}
    beam_centre_alg = create_managed_non_child_algorithm(beam_centre_finder, **beam_centre_finder_options)
    beam_centre_alg.setChild(False)
    set_properties_for_beam_centre_algorithm(beam_centre_alg, reduction_package,
                                             workspace_to_name, workspace_to_monitor)
    # -----------------------------------
    #  Run the beam centre finder algorithm.
    # -----------------------------------
    beam_centre_alg.execute()

    # -----------------------------------
    #  Get the outputs
    # -----------------------------------
    centre1 = beam_centre_alg.getProperty("Centre1").value
    centre2 = beam_centre_alg.getProperty("Centre2").value

    return {"pos1": centre1, "pos2": centre2}
def single_reduction_for_batch(state, use_optimizations, output_mode):
    """
    Runs a single reduction.

    This function creates reduction packages which essentially contain information for a single valid reduction, run it
    and store the results according to the user specified setting (output_mode). Although this is considered a single
    reduction it can contain still several reductions since the SANSState object can at this point contain slice
    settings which require on reduction per time slice.
    :param state: a SANSState object
    :param use_optimizations: if true then the optimizations of child algorithms are enabled.
    :param output_mode: the output mode
    """
    # ------------------------------------------------------------------------------------------------------------------
    # Load the data
    # ------------------------------------------------------------------------------------------------------------------
    workspace_to_name = {
        SANSDataType.SampleScatter: "SampleScatterWorkspace",
        SANSDataType.SampleTransmission: "SampleTransmissionWorkspace",
        SANSDataType.SampleDirect: "SampleDirectWorkspace",
        SANSDataType.CanScatter: "CanScatterWorkspace",
        SANSDataType.CanTransmission: "CanTransmissionWorkspace",
        SANSDataType.CanDirect: "CanDirectWorkspace"
    }

    workspace_to_monitor = {
        SANSDataType.SampleScatter: "SampleScatterMonitorWorkspace",
        SANSDataType.CanScatter: "CanScatterMonitorWorkspace"
    }

    workspaces, monitors = provide_loaded_data(state, use_optimizations,
                                               workspace_to_name,
                                               workspace_to_monitor)

    # ------------------------------------------------------------------------------------------------------------------
    # Get reduction settings
    # Split into individual bundles which can be reduced individually. We split here if we have multiple periods or
    # sliced times for example.
    # ------------------------------------------------------------------------------------------------------------------
    reduction_packages = get_reduction_packages(state, workspaces, monitors)

    # ------------------------------------------------------------------------------------------------------------------
    # Run reductions (one at a time)
    # ------------------------------------------------------------------------------------------------------------------
    single_reduction_name = "SANSSingleReduction"
    single_reduction_options = {"UseOptimizations": use_optimizations}
    reduction_alg = create_managed_non_child_algorithm(
        single_reduction_name, **single_reduction_options)
    reduction_alg.setChild(False)
    # Perform the data reduction
    for reduction_package in reduction_packages:
        # -----------------------------------
        # Set the properties on the algorithm
        # -----------------------------------
        set_properties_for_reduction_algorithm(reduction_alg,
                                               reduction_package,
                                               workspace_to_name,
                                               workspace_to_monitor)

        # -----------------------------------
        #  Run the reduction
        # -----------------------------------
        reduction_alg.execute()

        # -----------------------------------
        # Get the output of the algorithm
        # -----------------------------------
        reduction_package.reduced_lab = get_workspace_from_algorithm(
            reduction_alg, "OutputWorkspaceLAB")
        reduction_package.reduced_hab = get_workspace_from_algorithm(
            reduction_alg, "OutputWorkspaceHAB")
        reduction_package.reduced_merged = get_workspace_from_algorithm(
            reduction_alg, "OutputWorkspaceMerged")

        reduction_package.reduced_lab_can = get_workspace_from_algorithm(
            reduction_alg, "OutputWorkspaceLABCan")
        reduction_package.reduced_lab_can_count = get_workspace_from_algorithm(
            reduction_alg, "OutputWorkspaceLABCanCount")
        reduction_package.reduced_lab_can_norm = get_workspace_from_algorithm(
            reduction_alg, "OutputWorkspaceLABCanNorm")
        reduction_package.reduced_hab_can = get_workspace_from_algorithm(
            reduction_alg, "OutputWorkspaceHABCan")
        reduction_package.reduced_hab_can_count = get_workspace_from_algorithm(
            reduction_alg, "OutputWorkspaceHABCanCount")
        reduction_package.reduced_hab_can_norm = get_workspace_from_algorithm(
            reduction_alg, "OutputWorkspaceHABCanNorm")

        # -----------------------------------
        # The workspaces are already on the ADS, but should potentially be grouped
        # -----------------------------------
        group_workspaces_if_required(reduction_package)

    # --------------------------------
    # Perform output of all workspaces
    # --------------------------------
    # We have three options here
    # 1. PublishToADS:
    #    * This means we can leave it as it is
    # 2. SaveToFile:
    #    * This means we need to save out the reduced data
    #    * Then we need to delete the reduced data from the ADS
    # 3. Both:
    #    * This means that we need to save out the reduced data
    #    * The data is already on the ADS, so do nothing

    if output_mode is OutputMode.SaveToFile:
        save_to_file(reduction_packages)
        delete_reduced_workspaces(reduction_packages)
    elif output_mode is OutputMode.Both:
        save_to_file(reduction_packages)

    # -----------------------------------------------------------------------
    # Clean up other workspaces if the optimizations have not been turned on.
    # -----------------------------------------------------------------------
    if not use_optimizations:
        delete_optimization_workspaces(reduction_packages)