Esempio n. 1
0
def run_core_reduction(reduction_alg, reduction_setting_bundle):
    """
    This function runs a core reduction. This is essentially half a reduction (either smaple or can).

    :param reduction_alg: a handle to the reduction algorithm.
    :param reduction_setting_bundle: a ReductionSettingBundle tuple
    :return: an OutputBundle and an OutputPartsBundle
    """

    # Get component to reduce
    component = get_component_to_reduce(reduction_setting_bundle)
    # Set the properties on the reduction algorithms
    serialized_state = reduction_setting_bundle.state.property_manager
    reduction_alg.setProperty("SANSState", serialized_state)
    reduction_alg.setProperty("Component", component)
    reduction_alg.setProperty("ScatterWorkspace",
                              reduction_setting_bundle.scatter_workspace)
    reduction_alg.setProperty(
        "ScatterMonitorWorkspace",
        reduction_setting_bundle.scatter_monitor_workspace)
    reduction_alg.setProperty(
        "DataType", DataType.to_string(reduction_setting_bundle.data_type))

    if reduction_setting_bundle.transmission_workspace is not None:
        reduction_alg.setProperty(
            "TransmissionWorkspace",
            reduction_setting_bundle.transmission_workspace)

    if reduction_setting_bundle.direct_workspace is not None:
        reduction_alg.setProperty("DirectWorkspace",
                                  reduction_setting_bundle.direct_workspace)

    reduction_alg.setProperty("OutputWorkspace", EMPTY_NAME)
    reduction_alg.setProperty("SumOfCounts", EMPTY_NAME)
    reduction_alg.setProperty("SumOfNormFactors", EMPTY_NAME)

    # Run the reduction core
    reduction_alg.execute()

    # Get the results
    output_workspace = reduction_alg.getProperty("OutputWorkspace").value
    output_workspace_count = reduction_alg.getProperty("SumOfCounts").value
    output_workspace_norm = reduction_alg.getProperty("SumOfNormFactors").value
    # Pull the result out of the workspace
    output_bundle = OutputBundle(
        state=reduction_setting_bundle.state,
        data_type=reduction_setting_bundle.data_type,
        reduction_mode=reduction_setting_bundle.reduction_mode,
        output_workspace=output_workspace)

    output_parts_bundle = OutputPartsBundle(
        state=reduction_setting_bundle.state,
        data_type=reduction_setting_bundle.data_type,
        reduction_mode=reduction_setting_bundle.reduction_mode,
        output_workspace_count=output_workspace_count,
        output_workspace_norm=output_workspace_norm)
    return output_bundle, output_parts_bundle
Esempio n. 2
0
def _pack_bundles(reduction_alg, reduction_setting_bundle):
    output_workspaces = reduction_alg.getProperty("OutputWorkspaces").value
    output_workspace_counts = reduction_alg.getProperty("SumOfCounts").value
    output_workspace_norms = reduction_alg.getProperty(
        "SumOfNormFactors").value
    out_trans_ws = reduction_alg.getProperty(
        "CalculatedTransmissionWorkspaces").value
    out_unfit_trans_ws = reduction_alg.getProperty(
        "UnfittedTransmissionWorkspaces").value

    slices: CompletedSlices = []
    for i, reduced_ws in enumerate(output_workspaces):
        calc_trans_ws = out_trans_ws.getItem(i) if out_trans_ws else None
        unfit_trans_ws = out_unfit_trans_ws.getItem(
            i) if out_unfit_trans_ws else None

        slice = ReducedSlice(
            wav_range=reduced_ws.getRun().getProperty(
                "Wavelength Range").valueAsStr,
            output_bundle=OutputBundle(
                state=reduction_setting_bundle.state,
                data_type=reduction_setting_bundle.data_type,
                reduction_mode=reduction_setting_bundle.reduction_mode,
                output_workspace=reduced_ws),
            parts_bundle=OutputPartsBundle(
                state=reduction_setting_bundle.state,
                data_type=reduction_setting_bundle.data_type,
                reduction_mode=reduction_setting_bundle.reduction_mode,
                output_workspace_count=output_workspace_counts.getItem(i),
                output_workspace_norm=output_workspace_norms.getItem(i)),
            transmission_bundle=OutputTransmissionBundle(
                state=reduction_setting_bundle.state,
                data_type=reduction_setting_bundle.data_type,
                calculated_transmission_workspace=calc_trans_ws,
                unfitted_transmission_workspace=unfit_trans_ws))
        slices.append(slice)
    return slices
Esempio n. 3
0
def _get_existing_cans(reduction_setting_bundle, state):
    output_parts = reduction_setting_bundle.output_parts
    reduction_mode = reduction_setting_bundle.reduction_mode
    data_type = reduction_setting_bundle.data_type

    existing_slices = []
    for wav_slice in state.wavelength.wavelength_interval.selected_ranges:
        wav_string = wav_range_to_str(wav_slice)

        reduced_can_workspace, reduced_can_workspace_count, reduced_can_workspace_norm = \
            get_reduced_can_workspace_from_ads(state, output_parts, reduction_mode, wav_string)
        output_calculated_transmission_workspace, output_unfitted_transmission_workspace = \
            get_transmission_workspaces_from_ads(state, reduction_mode, wav_string)
        # Set the results on the output bundle
        existing_slices.append(
            ReducedSlice(
                wav_range=wav_string,
                output_bundle=OutputBundle(
                    state=state,
                    data_type=data_type,
                    reduction_mode=reduction_mode,
                    output_workspace=reduced_can_workspace),
                parts_bundle=OutputPartsBundle(
                    state=state,
                    data_type=data_type,
                    reduction_mode=reduction_mode,
                    output_workspace_count=reduced_can_workspace_count,
                    output_workspace_norm=reduced_can_workspace_norm),
                transmission_bundle=OutputTransmissionBundle(
                    state=reduction_setting_bundle.state,
                    data_type=data_type,
                    calculated_transmission_workspace=
                    output_calculated_transmission_workspace,
                    unfitted_transmission_workspace=
                    output_unfitted_transmission_workspace)))
    return existing_slices
Esempio n. 4
0
def run_core_event_slice_reduction(reduction_alg, reduction_setting_bundle):
    """
    This function runs a core reduction for event slice data. This reduction slices by event time and converts to q.
    All other operations, such as moving and converting to histogram, have been performed before the event slicing.

    :param reduction_alg: a handle to the reduction algorithm.
    :param reduction_setting_bundle: a ReductionSettingBundle tuple
    :return: an OutputBundle and an OutputPartsBundle
    """

    # Get component to reduce
    component = get_component_to_reduce(reduction_setting_bundle)
    # Set the properties on the reduction algorithms
    serialized_state = Serializer.to_json(reduction_setting_bundle.state)
    reduction_alg.setProperty("SANSState", serialized_state)
    reduction_alg.setProperty("Component", component)
    reduction_alg.setProperty("ScatterWorkspace",
                              reduction_setting_bundle.scatter_workspace)
    reduction_alg.setProperty("DirectWorkspace",
                              reduction_setting_bundle.direct_workspace)
    reduction_alg.setProperty("TransmissionWorkspace",
                              reduction_setting_bundle.transmission_workspace)
    reduction_alg.setProperty("DummyMaskWorkspace",
                              reduction_setting_bundle.dummy_mask_workspace)
    reduction_alg.setProperty(
        "ScatterMonitorWorkspace",
        reduction_setting_bundle.scatter_monitor_workspace)

    reduction_alg.setProperty("DataType",
                              reduction_setting_bundle.data_type.value)

    reduction_alg.setProperty("OutputWorkspace", EMPTY_NAME)
    reduction_alg.setProperty("SumOfCounts", EMPTY_NAME)
    reduction_alg.setProperty("SumOfNormFactors", EMPTY_NAME)

    # Run the reduction core
    reduction_alg.execute()

    # Get the results
    output_workspace = reduction_alg.getProperty("OutputWorkspace").value
    output_workspace_count = reduction_alg.getProperty("SumOfCounts").value
    output_workspace_norm = reduction_alg.getProperty("SumOfNormFactors").value
    output_calculated_transmission_workspace = reduction_alg.getProperty(
        "CalculatedTransmissionWorkspace").value
    output_unfitted_transmission_workspace = reduction_alg.getProperty(
        "UnfittedTransmissionWorkspace").value

    # Pull the result out of the workspace
    output_bundle = OutputBundle(
        state=reduction_setting_bundle.state,
        data_type=reduction_setting_bundle.data_type,
        reduction_mode=reduction_setting_bundle.reduction_mode,
        output_workspace=output_workspace)

    output_parts_bundle = OutputPartsBundle(
        state=reduction_setting_bundle.state,
        data_type=reduction_setting_bundle.data_type,
        reduction_mode=reduction_setting_bundle.reduction_mode,
        output_workspace_count=output_workspace_count,
        output_workspace_norm=output_workspace_norm)

    output_transmission_bundle = OutputTransmissionBundle(
        state=reduction_setting_bundle.state,
        data_type=reduction_setting_bundle.data_type,
        calculated_transmission_workspace=
        output_calculated_transmission_workspace,
        unfitted_transmission_workspace=output_unfitted_transmission_workspace,
    )
    return output_bundle, output_parts_bundle, output_transmission_bundle
Esempio n. 5
0
def run_optimized_for_can(reduction_alg,
                          reduction_setting_bundle,
                          event_slice_optimisation=False):
    """
    Check if the state can reduction already exists, and if so, use it else reduce it and add it to the ADS.

    :param reduction_alg: a handle to the SANSReductionCore algorithm
    :param reduction_setting_bundle: a ReductionSettingBundle tuple.
    :param event_slice_optimisation: An optional bool. If true then run run_core_event_slice_reduction, else run_core_reduction.
    :return: a reduced workspace, a partial output workspace for the counts, a partial workspace for the normalization.
    """
    state = reduction_setting_bundle.state
    output_parts = reduction_setting_bundle.output_parts
    reduction_mode = reduction_setting_bundle.reduction_mode
    data_type = reduction_setting_bundle.data_type
    reduced_can_workspace, reduced_can_workspace_count, reduced_can_workspace_norm = \
        get_reduced_can_workspace_from_ads(state, output_parts, reduction_mode)
    output_calculated_transmission_workspace, output_unfitted_transmission_workspace = \
        get_transmission_workspaces_from_ads(state, reduction_mode)
    # Set the results on the output bundle
    output_bundle = OutputBundle(state=state,
                                 data_type=data_type,
                                 reduction_mode=reduction_mode,
                                 output_workspace=reduced_can_workspace)
    output_parts_bundle = OutputPartsBundle(
        state=state,
        data_type=data_type,
        reduction_mode=reduction_mode,
        output_workspace_count=reduced_can_workspace_count,
        output_workspace_norm=reduced_can_workspace_norm)
    output_transmission_bundle = OutputTransmissionBundle(
        state=reduction_setting_bundle.state,
        data_type=data_type,
        calculated_transmission_workspace=
        output_calculated_transmission_workspace,
        unfitted_transmission_workspace=output_unfitted_transmission_workspace)
    # The logic table for the recalculation of the partial outputs is:
    # | output_parts | reduced_can_workspace_count is None |  reduced_can_workspace_norm is None | Recalculate |
    # ----------------------------------------------------------------------------------------------------------
    # |  False       |        True                         |           True                      |    False    |
    # |  False       |        True                         |           False                     |    False    |
    # |  False       |        False                        |           True                      |    False    |
    # |  False       |        False                        |           False                     |    False    |
    # |  True        |        True                         |           True                      |    False    |
    # |  True        |        True                         |           False                     |    True     |
    # |  True        |        False                        |           True                      |    True     |
    # |  True        |        False                        |           False                     |    False    |

    is_invalid_partial_workspaces = (
        (output_parts_bundle.output_workspace_count is None
         and output_parts_bundle.output_workspace_norm is not None)
        or (output_parts_bundle.output_workspace_count is not None
            and output_parts_bundle.output_workspace_norm is None))
    is_invalid_transmission_workspaces = (
        output_transmission_bundle.calculated_transmission_workspace is None
        or output_transmission_bundle.unfitted_transmission_workspace is None)
    partial_output_require_reload = output_parts and is_invalid_partial_workspaces

    must_reload = output_bundle.output_workspace is None or partial_output_require_reload or is_invalid_transmission_workspaces
    if 'boost.mpi' in sys.modules:
        # In MPI runs the result is only present on rank 0 (result of Q1D2 integration),
        # so the reload flag must be broadcasted from rank 0.
        must_reload = mpisetup.boost.mpi.broadcast(mpisetup.boost.mpi.world,
                                                   must_reload, 0)

    if must_reload:
        # if output_bundle.output_workspace is None or partial_output_require_reload:
        if not event_slice_optimisation:
            output_bundle, output_parts_bundle, \
                output_transmission_bundle = run_core_reduction(reduction_alg, reduction_setting_bundle)
        else:
            output_bundle, output_parts_bundle, \
                output_transmission_bundle = run_core_event_slice_reduction(reduction_alg, reduction_setting_bundle)

        # Now we need to tag the workspaces and add it to the ADS
        if output_bundle.output_workspace is not None:
            write_hash_into_reduced_can_workspace(
                state=output_bundle.state,
                workspace=output_bundle.output_workspace,
                partial_type=None,
                reduction_mode=reduction_mode)
        if output_transmission_bundle.calculated_transmission_workspace is not None and \
                output_transmission_bundle.unfitted_transmission_workspace is not None:
            write_hash_into_reduced_can_workspace(
                state=output_transmission_bundle.state,
                workspace=output_transmission_bundle.
                calculated_transmission_workspace,
                partial_type=TransmissionType.CALCULATED,
                reduction_mode=reduction_mode)
            write_hash_into_reduced_can_workspace(
                state=output_transmission_bundle.state,
                workspace=output_transmission_bundle.
                unfitted_transmission_workspace,
                partial_type=TransmissionType.UNFITTED,
                reduction_mode=reduction_mode)
        if (output_parts_bundle.output_workspace_count is not None
                and output_parts_bundle.output_workspace_norm is not None):
            write_hash_into_reduced_can_workspace(
                state=output_parts_bundle.state,
                workspace=output_parts_bundle.output_workspace_count,
                partial_type=OutputParts.COUNT,
                reduction_mode=reduction_mode)

            write_hash_into_reduced_can_workspace(
                state=output_parts_bundle.state,
                workspace=output_parts_bundle.output_workspace_norm,
                partial_type=OutputParts.NORM,
                reduction_mode=reduction_mode)

    return output_bundle, output_parts_bundle, output_transmission_bundle
Esempio n. 6
0
def run_optimized_for_can(reduction_alg, reduction_setting_bundle):
    """
    Check if the state can reduction already exists, and if so, use it else reduce it and add it to the ADS.

    @param reduction_alg: a handle to the SANSReductionCore algorithm
    @param reduction_setting_bundle: a ReductionSettingBundle tuple.
    @return: a reduced workspace, a partial output workspace for the counts, a partial workspace for the normalization.
    """
    state = reduction_setting_bundle.state
    output_parts = reduction_setting_bundle.output_parts
    reduction_mode = reduction_setting_bundle.reduction_mode
    data_type = reduction_setting_bundle.data_type
    reduced_can_workspace, reduced_can_workspace_count, reduced_can_workspace_norm = \
        get_reduced_can_workspace_from_ads(state, output_parts, reduction_mode)
    # Set the results on the output bundle
    output_bundle = OutputBundle(state=state, data_type=data_type, reduction_mode=reduction_mode,
                                 output_workspace=reduced_can_workspace)
    output_parts_bundle = OutputPartsBundle(state=state, data_type=data_type, reduction_mode=reduction_mode,
                                            output_workspace_count=reduced_can_workspace_count,
                                            output_workspace_norm=reduced_can_workspace_norm)
    # The logic table for the recalculation of the partial outputs is:
    # | output_parts | reduced_can_workspace_count is None |  reduced_can_workspace_norm is None | Recalculate |
    # ----------------------------------------------------------------------------------------------------------
    # |  False       |        True                         |           True                      |    False    |
    # |  False       |        True                         |           False                     |    False    |
    # |  False       |        False                        |           True                      |    False    |
    # |  False       |        False                        |           False                     |    False    |
    # |  True        |        True                         |           True                      |    False    |
    # |  True        |        True                         |           False                     |    True     |
    # |  True        |        False                        |           True                      |    True     |
    # |  True        |        False                        |           False                     |    False    |

    is_invalid_partial_workspaces = ((output_parts_bundle.output_workspace_count is None and
                                     output_parts_bundle.output_workspace_norm is not None) or
                                     (output_parts_bundle.output_workspace_count is not None and
                                     output_parts_bundle.output_workspace_norm is None))
    partial_output_require_reload = output_parts and is_invalid_partial_workspaces

    if output_bundle.output_workspace is None or partial_output_require_reload:
        output_bundle, output_parts_bundle = run_core_reduction(reduction_alg, reduction_setting_bundle)

        # Now we need to tag the workspaces and add it to the ADS
        if output_bundle.output_workspace is not None:
            write_hash_into_reduced_can_workspace(state=output_bundle.state,
                                                  workspace=output_bundle.output_workspace,
                                                  partial_type=None,
                                                  reduction_mode=reduction_mode)

        if (output_parts_bundle.output_workspace_count is not None and
           output_parts_bundle.output_workspace_norm is not None):
            write_hash_into_reduced_can_workspace(state=output_parts_bundle.state,
                                                  workspace=output_parts_bundle.output_workspace_count,
                                                  partial_type=OutputParts.Count,
                                                  reduction_mode=reduction_mode)

            write_hash_into_reduced_can_workspace(state=output_parts_bundle.state,
                                                  workspace=output_parts_bundle.output_workspace_norm,
                                                  partial_type=OutputParts.Norm,
                                                  reduction_mode=reduction_mode)

    return output_bundle, output_parts_bundle