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
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
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
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)
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
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