예제 #1
0
def calculate_transmission(transmission_ws, direct_ws,
                           state_adjustment_calculate_transmission,
                           data_type_str):
    """
    Calculates the transmission for a SANS reduction.
    :param transmission_ws: The transmission workspace in time-of-light units.
    :param direct_ws: The direct workspace in time-of-flight units.
    :param state_adjustment_calculate_transmission: The state.adjustment.calculate_transmission object
    :param data_type_str: The component of the instrument which is to be reduced. Allowed values: ['Sample', 'Can']
    :return: Tuple of: Output Workspace and Unfitted Data - Both in wavelength
    """
    calculate_transmission_state = state_adjustment_calculate_transmission
    # The calculation of the transmission has the following steps:
    # 1. Get all spectrum numbers which take part in the transmission calculation
    # 2. Clean up the transmission and direct workspaces, ie peak prompt correction, flat background calculation,
    #    wavelength conversion and rebinning of the data.
    # 3. Run the CalculateTransmission algorithm
    incident_monitor_spectrum_number = calculate_transmission_state.incident_monitor
    if incident_monitor_spectrum_number is None:
        incident_monitor_spectrum_number = calculate_transmission_state.default_incident_monitor

    # 1. Get relevant spectra
    detector_id_incident_monitor = get_detector_id_for_spectrum_number(
        transmission_ws, incident_monitor_spectrum_number)
    detector_ids_roi, detector_id_transmission_monitor, detector_id_default_transmission_monitor = \
        _get_detector_ids_for_transmission_calculation(transmission_ws, calculate_transmission_state)
    all_detector_ids = [detector_id_incident_monitor]

    if len(detector_ids_roi) > 0:
        all_detector_ids.extend(detector_ids_roi)
    elif detector_id_transmission_monitor is not None:
        all_detector_ids.append(detector_id_transmission_monitor)
    elif detector_id_default_transmission_monitor is not None:
        all_detector_ids.append(detector_id_default_transmission_monitor)
    else:
        raise RuntimeError(
            "SANSCalculateTransmission: No region of interest or transmission monitor selected."
        )

    # 2. Clean transmission data

    data_type = DataType(data_type_str)
    transmission_ws = _get_corrected_wavelength_workspace(
        transmission_ws,
        all_detector_ids,
        calculate_transmission_state,
        data_type=data_type)
    direct_ws = _get_corrected_wavelength_workspace(
        direct_ws,
        all_detector_ids,
        calculate_transmission_state,
        data_type=data_type)

    # 3. Fit
    output_workspace, unfitted_transmission_workspace = \
        _perform_fit(transmission_ws, direct_ws, detector_ids_roi,
                     detector_id_transmission_monitor, detector_id_default_transmission_monitor,
                     detector_id_incident_monitor, calculate_transmission_state, data_type)

    return output_workspace, unfitted_transmission_workspace
예제 #2
0
def slice_sans_event(state_slice,
                     input_ws,
                     input_ws_monitor,
                     data_type_str="Sample"):
    """
    Takes an event slice from an event workspace
    :param state_slice: The state.slice object
    :param input_ws: The input workspace. If it is an event workspace, then the slice is taken.
                     In case of a Workspace2D the original workspace is returned
    :param input_ws_monitor: The monitor workspace associated with the main input workspace.
    :param data_type_str: The component of the instrument which is to be reduced. Allowed values: ['Sample', 'Can']
    :return: A dict with the following:
             'SliceEventFactor': The factor of the event slicing. This corresponds to the proportion of the
                                 the total proton charge, which the slice corresponds to.
             'OutputWorkspace' : The slice workspace
             'OutputWorkspaceMonitor' : The output monitor workspace which has the correct slice factor applied to it.
    """

    data_type = DataType(data_type_str)

    # This should be removed in the future when cycle 19/1 data is unlikely to be processed by users
    # This prevents time slicing falling over, since we wrap around and get -0
    _clean_logs(ws=input_ws, estimate_logs=True)

    if isinstance(input_ws, Workspace2D):
        sliced_workspace = input_ws
        slice_factor = 1.0
    else:
        sliced_workspace, slice_factor = _create_slice(workspace=input_ws,
                                                       slice_info=state_slice,
                                                       data_type=data_type)

    # Scale the monitor accordingly
    slice_monitor = _scale_monitors(slice_factor=slice_factor,
                                    input_monitor_ws=input_ws_monitor)

    # Set the outputs
    append_to_sans_file_tag(sliced_workspace, "_sliced")

    to_return = {
        "OutputWorkspace": sliced_workspace,
        "SliceEventFactor": slice_factor,
        "OutputWorkspaceMonitor": slice_monitor
    }

    return to_return