def runTest(self):
        testws_e = mantid.CreateWorkspace([1.0, 2.0, 3.0], [4.0, 4.0, 4.0],
                                          UnitX="Wavelength")
        mantid.EditInstrumentGeometry(Workspace=testws_e,
                                      PrimaryFlightPath=10.0,
                                      L2=1.0,
                                      Polar=1.0)
        mantid.SetSample(testws_e,
                         ContainerGeometry={
                             'Shape': 'FlatPlate',
                             'Height': 4.0,
                             'Width': 2.0,
                             'Thick': 1.0,
                             'Center': [0., 0., 0.]
                         },
                         ContainerMaterial={
                             'ChemicalFormula': 'Al',
                             'NumberDensity': 0.01
                         })
        mantid.SetBeam(InputWorkspace=testws_e,
                       Geometry={
                           'Shape': 'Slit',
                           'Width': 3.0,
                           'Height': 6.75
                       })
        self.abs_e = mantid.MonteCarloAbsorption(InputWorkspace=testws_e,
                                                 OutputWorkspace="abs_e",
                                                 EventsPerPoint=100)

        testws_s = mantid.CreateWorkspace([1.0, 2.0, 3.0], [4.0, 4.0, 4.0],
                                          UnitX="Wavelength")
        mantid.EditInstrumentGeometry(Workspace=testws_s,
                                      PrimaryFlightPath=10.0,
                                      L2=1.0,
                                      Polar=1.0)
        mantid.SetSample(testws_s,
                         Geometry={
                             'Shape': 'FlatPlate',
                             'Height': 4.0,
                             'Width': 2.0,
                             'Thick': 1.0,
                             'Center': [0., 0., 0.]
                         },
                         Material={
                             'ChemicalFormula': 'Al',
                             'NumberDensity': 0.01
                         })
        mantid.SetBeam(InputWorkspace=testws_s,
                       Geometry={
                           'Shape': 'Slit',
                           'Width': 3.0,
                           'Height': 6.75
                       })
        self.abs_s = mantid.MonteCarloAbsorption(InputWorkspace=testws_s,
                                                 OutputWorkspace="abs_s",
                                                 EventsPerPoint=100)
def _setup_sample_for_cylinder_absorb_corrections(ws_to_correct,
                                                  sample_details_obj):
    geometry_json = common.generate_sample_geometry(sample_details_obj)
    material_json = common.generate_sample_material(sample_details_obj)
    mantid.SetSample(InputWorkspace=ws_to_correct,
                     Geometry=geometry_json,
                     Material=material_json)
def _calculate__cylinder_absorb_corrections(ws_to_correct, multiple_scattering,
                                            sample_details_obj):
    """
    Calculates vanadium absorption corrections for the specified workspace. The workspace
    should have any monitor spectra masked before being passed into this method. Additionally
    it takes details of the sample container and sets the sample geometry to a cylinder with
    the specified geometry. This function uses Mayers Sample Correction to perform the corrections.
    :param ws_to_correct: The workspace to apply the sample corrections to
    :param multiple_scattering: True if the effects of multiple scattering should be accounted for, else False
    :param sample_details_obj: The SampleDetails object in a checked state which describes the sample
    to ensure a none elemental formula has associated number density
    :return: The workspace with corrections applied
    """

    geometry_json = {
        'Shape': 'Cylinder',
        'Height': sample_details_obj.height,
        'Radius': sample_details_obj.radius,
        'Center': sample_details_obj.center
    }
    material = sample_details_obj.material_object
    # See SetSampleMaterial for documentation on this dictionary
    material_json = {'ChemicalFormula': material.chemical_formula}
    if material.number_density:
        material_json["SampleNumberDensity"] = material.number_density
    if material.absorption_cross_section:
        material_json[
            "AttenuationXSection"] = material.absorption_cross_section
    if material.scattering_cross_section:
        material_json["ScatteringXSection"] = material.scattering_cross_section

    mantid.SetSample(InputWorkspace=ws_to_correct,
                     Geometry=geometry_json,
                     Material=material_json)

    previous_units = ws_to_correct.getAxis(0).getUnit().unitID()
    ws_units = common_enums.WORKSPACE_UNITS

    # Mayers Sample correction must be completed in TOF, convert if needed. Then back to original units afterwards
    if previous_units != ws_units.tof:
        ws_to_correct = mantid.ConvertUnits(InputWorkspace=ws_to_correct,
                                            OutputWorkspace=ws_to_correct,
                                            Target=ws_units.tof)
    ws_to_correct = mantid.MayersSampleCorrection(
        InputWorkspace=ws_to_correct,
        OutputWorkspace=ws_to_correct,
        MultipleScattering=multiple_scattering)
    if previous_units != ws_units.tof:
        ws_to_correct = mantid.ConvertUnits(InputWorkspace=ws_to_correct,
                                            OutputWorkspace=ws_to_correct,
                                            Target=previous_units)

    return ws_to_correct
Example #4
0
def calculate_slab_absorb_corrections(ws_to_correct, sample_details_obj):
    """
    Sets a slab sample from the user specified dictionary and performs HRPDSlabCanAbsorption on the workspace.
    The SampleDetails object defines the sample, material and associated properties.
    :param ws_to_correct: The workspace to do corrections on
    :param sample_details_obj: The object containing the sample details
    :return: The corrected workspace
    """

    if not isinstance(sample_details_obj, sample_details.SampleDetails):
        raise RuntimeError("A SampleDetails object was not set or a different object type was found when sample"
                           " absorption corrections were requested. If you want sample absorption corrections please "
                           "create a SampleDetails object and set the relevant properties it. "
                           "Then set the new sample by calling set_sample_details().")
    if not sample_details_obj.is_material_set():
        raise RuntimeError("The material for this sample has not been set yet. Please call"
                           " set_material on the SampleDetails object to set the material")

    geometry_json = {"Shape": "FlatPlate", "Thick": sample_details_obj.thickness(), "Width": sample_details_obj.width(),
                     "Height": sample_details_obj.height(), "Center": sample_details_obj.center(),
                     "Angle": sample_details_obj.angle()}
    material = sample_details_obj.material_object
    # See SetSampleMaterial for documentation on this dictionary
    material_json = {"ChemicalFormula": material.chemical_formula}
    if material.number_density:
        material_json["SampleNumberDensity"] = material.number_density
    if material.absorption_cross_section:
        material_json["AttenuationXSection"] = material.absorption_cross_section
    if material.scattering_cross_section:
        material_json["ScatteringXSection"] = material.scattering_cross_section

    mantid.SetSample(InputWorkspace=ws_to_correct, Geometry=geometry_json, Material=material_json)

    previous_units = ws_to_correct.getAxis(0).getUnit().unitID()
    ws_units = common_enums.WORKSPACE_UNITS

    # HRPDSlabCanAbsorption must be completed in units of wavelength - convert if needed, than convert back afterwards
    if previous_units != ws_units.wavelength:
        ws_to_correct = mantid.ConvertUnits(InputWorkspace=ws_to_correct, OutputWorkspace=ws_to_correct,
                                            Target=ws_units.wavelength)

    absorb_factors = mantid.HRPDSlabCanAbsorption(InputWorkspace=ws_to_correct)
    ws_to_correct = mantid.Divide(LHSWorkspace=ws_to_correct, RHSWorkspace=absorb_factors,
                                  OutputWorkspace=ws_to_correct)
    mantid.DeleteWorkspace(Workspace=absorb_factors)

    if previous_units != ws_units.wavelength:
        ws_to_correct = mantid.ConvertUnits(InputWorkspace=ws_to_correct, OutputWorkspace=ws_to_correct,
                                            Target=previous_units)

    return ws_to_correct
Example #5
0
def apply_paalmanpings_absorb_and_subtract_empty(
        workspace,
        summed_empty,
        sample_details,
        paalman_pings_events_per_point=None):
    if paalman_pings_events_per_point:
        events_per_point = int(paalman_pings_events_per_point)
    else:
        events_per_point = 1000

    container_geometry = sample_details.generate_container_geometry()
    container_material = sample_details.generate_container_material()
    if container_geometry and container_material:
        mantid.SetSample(workspace,
                         Geometry=sample_details.generate_sample_geometry(),
                         Material=sample_details.generate_sample_material(),
                         ContainerGeometry=container_geometry,
                         ContainerMaterial=container_material)
        corrections = mantid.PaalmanPingsMonteCarloAbsorption(
            InputWorkspace=workspace,
            Shape='Preset',
            EventsPerPoint=events_per_point)
        workspace = mantid.ApplyPaalmanPingsCorrection(
            SampleWorkspace=workspace,
            CorrectionsWorkspace=corrections,
            CanWorkspace=summed_empty)
    else:
        mantid.SetSample(workspace,
                         Geometry=sample_details.generate_sample_geometry(),
                         Material=sample_details.generate_sample_material())
        corrections = mantid.PaalmanPingsMonteCarloAbsorption(
            InputWorkspace=workspace,
            Shape='Preset',
            EventsPerPoint=events_per_point)
        workspace = mantid.ApplyPaalmanPingsCorrection(
            SampleWorkspace=workspace, CorrectionsWorkspace=corrections)
    return workspace
Example #6
0
def _setup_sample_for_cylinder_absorb_corrections(ws_to_correct,
                                                  sample_details_obj):
    geometry_json = {
        'Shape': 'Cylinder',
        'Height': sample_details_obj.height(),
        'Radius': sample_details_obj.radius(),
        'Center': sample_details_obj.center()
    }
    material = sample_details_obj.material_object
    # See SetSampleMaterial for documentation on this dictionary
    material_json = {'ChemicalFormula': material.chemical_formula}
    if material.number_density:
        material_json["SampleNumberDensity"] = material.number_density
    if material.absorption_cross_section:
        material_json[
            "AttenuationXSection"] = material.absorption_cross_section
    if material.scattering_cross_section:
        material_json["ScatteringXSection"] = material.scattering_cross_section

    mantid.SetSample(InputWorkspace=ws_to_correct,
                     Geometry=geometry_json,
                     Material=material_json)
Example #7
0
def _focus_one_ws(input_workspace, run_number, instrument,
                  perform_vanadium_norm, absorb, sample_details,
                  vanadium_path):
    run_details = instrument._get_run_details(run_number_string=run_number)
    if perform_vanadium_norm:
        _test_splined_vanadium_exists(instrument, run_details)

    # Subtract empty instrument runs, as long as this run isn't an empty and user hasn't turned empty subtraction off
    if not common.runs_overlap(run_number, run_details.empty_runs
                               ) and instrument.should_subtract_empty_inst():
        input_workspace = common.subtract_summed_runs(
            ws_to_correct=input_workspace,
            instrument=instrument,
            empty_sample_ws_string=run_details.empty_runs)

    # Subtract a sample empty if specified
    if run_details.sample_empty:
        input_workspace = common.subtract_summed_runs(
            ws_to_correct=input_workspace,
            instrument=instrument,
            empty_sample_ws_string=run_details.sample_empty,
            scale_factor=instrument._inst_settings.sample_empty_scale)

    # Crop to largest acceptable TOF range
    input_workspace = instrument._crop_raw_to_expected_tof_range(
        ws_to_crop=input_workspace)

    # Correct for absorption / multiple scattering if required
    if absorb:
        input_workspace = instrument._apply_absorb_corrections(
            run_details=run_details, ws_to_correct=input_workspace)
    else:
        # Set sample material if specified by the user
        if sample_details is not None:
            mantid.SetSample(
                InputWorkspace=input_workspace,
                Geometry=common.generate_sample_geometry(sample_details),
                Material=common.generate_sample_material(sample_details))
    # Align
    aligned_ws = mantid.AlignDetectors(
        InputWorkspace=input_workspace,
        CalibrationFile=run_details.offset_file_path)

    # Focus the spectra into banks
    focused_ws = mantid.DiffractionFocussing(
        InputWorkspace=aligned_ws,
        GroupingFileName=run_details.grouping_file_path)

    calibrated_spectra = _apply_vanadium_corrections(
        instrument=instrument,
        input_workspace=focused_ws,
        perform_vanadium_norm=perform_vanadium_norm,
        vanadium_splines=vanadium_path)

    output_spectra = instrument._crop_banks_to_user_tof(calibrated_spectra)

    bin_widths = instrument._get_instrument_bin_widths()
    if bin_widths:
        # Reduce the bin width if required on this instrument
        output_spectra = common.rebin_workspace_list(
            workspace_list=output_spectra, bin_width_list=bin_widths)

    # Output
    d_spacing_group, tof_group = instrument._output_focused_ws(
        output_spectra, run_details=run_details)

    common.keep_single_ws_unit(d_spacing_group=d_spacing_group,
                               tof_group=tof_group,
                               unit_to_keep=instrument._get_unit_to_keep())

    # Tidy workspaces from Mantid
    common.remove_intermediate_workspace(input_workspace)
    common.remove_intermediate_workspace(aligned_ws)
    common.remove_intermediate_workspace(focused_ws)
    common.remove_intermediate_workspace(output_spectra)

    return d_spacing_group
Example #8
0
def _focus_one_ws(input_workspace,
                  run_number,
                  instrument,
                  perform_vanadium_norm,
                  absorb,
                  sample_details,
                  vanadium_path,
                  empty_can_subtraction_method,
                  paalman_pings_events_per_point=None):
    run_details = instrument._get_run_details(run_number_string=run_number)
    if perform_vanadium_norm:
        _test_splined_vanadium_exists(instrument, run_details)

    # Subtract empty instrument runs, as long as this run isn't an empty, user hasn't turned empty subtraction off, or
    # The user has not supplied a sample empty
    is_run_empty = common.runs_overlap(run_number, run_details.empty_inst_runs)
    summed_empty = None
    if not is_run_empty and instrument.should_subtract_empty_inst(
    ) and not run_details.sample_empty:
        if os.path.isfile(run_details.summed_empty_inst_file_path):
            logger.warning('Pre-summed empty instrument workspace found at ' +
                           run_details.summed_empty_inst_file_path)
            summed_empty = mantid.LoadNexus(
                Filename=run_details.summed_empty_inst_file_path)
        else:
            summed_empty = common.generate_summed_runs(
                empty_sample_ws_string=run_details.empty_inst_runs,
                instrument=instrument)
    elif run_details.sample_empty:
        scale_factor = 1.0
        if empty_can_subtraction_method != 'PaalmanPings':
            scale_factor = instrument._inst_settings.sample_empty_scale
        # Subtract a sample empty if specified ie empty can
        summed_empty = common.generate_summed_runs(
            empty_sample_ws_string=run_details.sample_empty,
            instrument=instrument,
            scale_factor=scale_factor)

    if absorb and empty_can_subtraction_method == 'PaalmanPings':
        if run_details.sample_empty:  # need summed_empty including container
            input_workspace = instrument._apply_paalmanpings_absorb_and_subtract_empty(
                workspace=input_workspace,
                summed_empty=summed_empty,
                sample_details=sample_details,
                paalman_pings_events_per_point=paalman_pings_events_per_point)
            # Crop to largest acceptable TOF range
            input_workspace = instrument._crop_raw_to_expected_tof_range(
                ws_to_crop=input_workspace)
        else:
            raise TypeError(
                "The PaalmanPings absorption method requires 'sample_empty' to be supplied."
            )
    else:
        if summed_empty:
            input_workspace = common.subtract_summed_runs(
                ws_to_correct=input_workspace, empty_sample=summed_empty)
        # Crop to largest acceptable TOF range
        input_workspace = instrument._crop_raw_to_expected_tof_range(
            ws_to_crop=input_workspace)

        if absorb:
            input_workspace = instrument._apply_absorb_corrections(
                run_details=run_details, ws_to_correct=input_workspace)
        else:
            # Set sample material if specified by the user
            if sample_details is not None:
                mantid.SetSample(
                    InputWorkspace=input_workspace,
                    Geometry=sample_details.generate_sample_geometry(),
                    Material=sample_details.generate_sample_material())

    # Align
    mantid.ApplyDiffCal(InstrumentWorkspace=input_workspace,
                        CalibrationFile=run_details.offset_file_path)
    aligned_ws = mantid.ConvertUnits(InputWorkspace=input_workspace,
                                     Target="dSpacing")

    solid_angle = instrument.get_solid_angle_corrections(
        run_details.vanadium_run_numbers, run_details)
    if solid_angle:
        aligned_ws = mantid.Divide(LHSWorkspace=aligned_ws,
                                   RHSWorkspace=solid_angle)
        mantid.DeleteWorkspace(solid_angle)

    # Focus the spectra into banks
    focused_ws = mantid.DiffractionFocussing(
        InputWorkspace=aligned_ws,
        GroupingFileName=run_details.grouping_file_path)

    instrument.apply_calibration_to_focused_data(focused_ws)

    calibrated_spectra = _apply_vanadium_corrections(
        instrument=instrument,
        input_workspace=focused_ws,
        perform_vanadium_norm=perform_vanadium_norm,
        vanadium_splines=vanadium_path)

    output_spectra = instrument._crop_banks_to_user_tof(calibrated_spectra)

    bin_widths = instrument._get_instrument_bin_widths()
    if bin_widths:
        # Reduce the bin width if required on this instrument
        output_spectra = common.rebin_workspace_list(
            workspace_list=output_spectra, bin_width_list=bin_widths)

    # Output
    d_spacing_group, tof_group = instrument._output_focused_ws(
        output_spectra, run_details=run_details)

    common.keep_single_ws_unit(d_spacing_group=d_spacing_group,
                               tof_group=tof_group,
                               unit_to_keep=instrument._get_unit_to_keep())

    # Tidy workspaces from Mantid
    common.remove_intermediate_workspace(input_workspace)
    common.remove_intermediate_workspace(aligned_ws)
    common.remove_intermediate_workspace(focused_ws)
    common.remove_intermediate_workspace(output_spectra)

    return d_spacing_group