Skip to content
Snippets Groups Projects
Commit 4fa7be00 authored by David Fairbrother's avatar David Fairbrother
Browse files

Re #19509 Fixed abs. corrections in focus mixing up units

parent f602bac0
No related branches found
No related tags found
No related merge requests found
......@@ -33,19 +33,17 @@ class Gem(AbstractInst):
do_absorb_corrections=self._inst_settings.do_absorb_corrections)
def set_sample_details(self, **kwargs):
kwarg_name = "sample"
sample_details_obj = common.dictionary_key_helper(
dictionary=kwargs, key="new_sample_details",
dictionary=kwargs, key=kwarg_name,
exception_msg="The argument containing sample details was not found. Please"
" set the following argument: new_sample_details")
if not isinstance(sample_details_obj, sample_details.SampleDetails):
raise ValueError("The object passed was not a SampleDetails object. Please create a"
" SampleDetails object and set the relevant properties to use on this method")
" set the following argument: " + kwarg_name)
self._sample_details = sample_details_obj
# Private methods
def _get_run_details(self, run_number_string):
run_number_string_key = run_number_string + str(self._inst_settings.file_extension)
run_number_string_key = str(run_number_string) + str(self._inst_settings.file_extension)
if run_number_string_key in self._cached_run_details:
return self._cached_run_details[run_number_string_key]
......@@ -70,7 +68,7 @@ class Gem(AbstractInst):
else:
return absorb_corrections.run_cylinder_absorb_corrections(
ws_to_correct=ws_to_correct, multiple_scattering=self._inst_settings.multiple_scattering,
sample_details_obj=sample_details)
sample_details_obj=self._sample_details)
def _crop_banks_to_user_tof(self, focused_banks):
return common.crop_banks_using_crop_list(focused_banks, self._inst_settings.focused_cropping_values)
......
......@@ -47,7 +47,7 @@ class Pearl(AbstractInst):
do_absorb_corrections=self._inst_settings.absorb_corrections)
def _get_run_details(self, run_number_string):
run_number_string_key = run_number_string + str(self._inst_settings.file_extension)
run_number_string_key = str(run_number_string) + str(self._inst_settings.file_extension)
if run_number_string_key in self._cached_run_details:
return self._cached_run_details[run_number_string_key]
......
......@@ -35,13 +35,11 @@ class Polaris(AbstractInst):
do_absorb_corrections=self._inst_settings.do_absorb_corrections)
def set_sample_details(self, **kwargs):
kwarg_name = "sample"
sample_details_obj = common.dictionary_key_helper(
dictionary=kwargs, key="new_sample_details",
dictionary=kwargs, key=kwarg_name,
exception_msg="The argument containing sample details was not found. Please"
" set the following argument: new_sample_details")
if not isinstance(sample_details_obj, sample_details.SampleDetails):
raise ValueError("The object passed was not a SampleDetails object. Please create a"
" SampleDetails object and set the relevant properties to use on this method")
" set the following argument: " + kwarg_name)
self._sample_details = sample_details_obj
# Overrides
......@@ -52,7 +50,7 @@ class Polaris(AbstractInst):
else:
return absorb_corrections.run_cylinder_absorb_corrections(
ws_to_correct=ws_to_correct, multiple_scattering=self._inst_settings.multiple_scattering,
sample_details_obj=sample_details)
sample_details_obj=self._sample_details)
@staticmethod
def _can_auto_gen_vanadium_cal():
......@@ -105,7 +103,7 @@ class Polaris(AbstractInst):
return self._inst_settings.input_mode
def _get_run_details(self, run_number_string):
run_number_string_key = run_number_string + str(self._inst_settings.file_extension)
run_number_string_key = str(run_number_string) + str(self._inst_settings.file_extension)
if run_number_string_key in self._run_details_cached_obj:
return self._run_details_cached_obj[run_number_string_key]
......
......@@ -2,7 +2,7 @@ from __future__ import (absolute_import, division, print_function)
import mantid.simpleapi as mantid
from isis_powder.routines import common, sample_details
from isis_powder.routines import common, common_enums, sample_details
def create_vanadium_sample_details_obj(config_dict):
......@@ -26,7 +26,7 @@ def create_vanadium_sample_details_obj(config_dict):
formula = common.dictionary_key_helper(dictionary=config_dict, key=formula_key, exception_msg=e_msg + formula_key)
number_density = common.dictionary_key_helper(dictionary=config_dict, key=number_density_key, throws=False)
vanadium_sample_details = sample_details.SampleDetails(height=height, radius=radius, pos=pos)
vanadium_sample_details = sample_details.SampleDetails(height=height, radius=radius, center=pos)
vanadium_sample_details.set_material(chemical_formula=formula, number_density=number_density)
return vanadium_sample_details
......@@ -43,6 +43,11 @@ def run_cylinder_absorb_corrections(ws_to_correct, multiple_scattering, sample_d
: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. Please create a"
" SampleDetails object and set the relevant properties it. Then set the new sample by "
"calling set_sample_details()")
height = sample_details_obj.height
radius = sample_details_obj.radius
pos = sample_details_obj.center
......@@ -88,9 +93,17 @@ def _calculate__cylinder_absorb_corrections(ws_to_correct, multiple_scattering,
mantid.SetSample(InputWorkspace=ws_to_correct, Geometry=geometry_json, Material=material_json)
ws_to_correct = mantid.ConvertUnits(InputWorkspace=ws_to_correct, OutputWorkspace=ws_to_correct, Target="TOF")
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)
ws_to_correct = mantid.ConvertUnits(InputWorkspace=ws_to_correct, OutputWorkspace=ws_to_correct, Target="dSpacing")
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
......@@ -14,7 +14,7 @@ def focus(run_number_string, instrument, perform_vanadium_norm, absorb):
return _individual_run_focusing(instrument=instrument, perform_vanadium_norm=perform_vanadium_norm,
run_number=run_number_string, absorb=absorb)
elif input_batching == INPUT_BATCHING.Summed:
return _batched_run_focusing(instrument, perform_vanadium_norm, run_number_string)
return _batched_run_focusing(instrument, perform_vanadium_norm, run_number_string, absorb=absorb)
else:
raise ValueError("Input batching not passed through. Please contact development team.")
......@@ -33,17 +33,18 @@ def _focus_one_ws(ws, run_number, instrument, perform_vanadium_norm, absorb):
empty_sample_ws_string=run_details.sample_empty,
scale_factor=instrument._inst_settings.sample_empty_scale)
# Correct for absorption / multiple scattering if required
if absorb:
input_workspace = instrument._apply_absorb_corrections(run_details=run_details, ws_to_correct=input_workspace)
# Crop to largest acceptable TOF range
input_workspace = instrument._crop_raw_to_expected_tof_range(ws_to_crop=input_workspace)
# Align / Focus
# Align
aligned_ws = mantid.AlignDetectors(InputWorkspace=input_workspace,
CalibrationFile=run_details.offset_file_path)
# Correct for absorption / multiple scattering if required
if absorb:
input_workspace = instrument._apply_absorb_corrections(run_details=run_details, ws_to_correct=input_workspace)
# Focus the spectra into banks
focused_ws = mantid.DiffractionFocussing(InputWorkspace=aligned_ws,
GroupingFileName=run_details.grouping_file_path)
......
......@@ -26,8 +26,8 @@ class InstrumentSettings(object):
if kwargs:
config_file_path = kwargs.get("config_file", None)
if not config_file_path:
warnings.warn("No config file was specified. If one was meant to be used the path to a YAML config file"
" is set with the 'config_file' parameter.")
warnings.warn("No config file was specified. If a configuration file was meant to be used "
"the path to the file is set with the 'config_file' parameter.\n")
# Always do this so we have a known state of the internal variable
self._basic_conf_dict = yaml_parser.open_yaml_file_as_dictionary(config_file_path)
......
......@@ -43,7 +43,7 @@ class SampleDetails(object):
" have not been set they can be modified with 'set_material_properties()'. Otherwise"
" to change the material call 'reset_sample_material()'")
self.material_object = _Material(chemical_formula=chemical_formula, numeric_density=number_density)
self.material_object = _Material(chemical_formula=chemical_formula, number_density=number_density)
def set_material_properties(self, **kwargs):
err_msg = "The following argument is required but was not set or passed: "
......@@ -95,20 +95,20 @@ class SampleDetails(object):
class _Material(object):
def __init__(self, chemical_formula, numeric_density=None):
def __init__(self, chemical_formula, number_density=None):
self.chemical_formula = chemical_formula
# If it is not an element Mantid requires us to provide the numeric density
# If it is not an element Mantid requires us to provide the number density
# which is required for absorption corrections.
if len(chemical_formula) > 2 and numeric_density is None:
raise ValueError("A numeric density formula must be set on a chemical formula which is not elemental."
" An element can only be a maximum of 2 characters (e.g. 'Si' or 'V'). The numeric"
" density can be set using the following key: numeric_density")
if numeric_density:
if len(chemical_formula) > 2 and number_density is None:
raise ValueError("A number density formula must be set on a chemical formula which is not elemental."
" An element can only be a maximum of 2 characters (e.g. 'Si' or 'V'). The number"
" density can be set using the following key: number_density")
if number_density:
# Always check value is sane if user has given one
_check_value_is_physical(property_name="numeric_density", value=numeric_density)
_check_value_is_physical(property_name="number_density", value=number_density)
self.numeric_density = numeric_density
self.number_density = number_density
# Advanced material properties
self.absorption_cross_section = None
......@@ -122,10 +122,10 @@ class _Material(object):
print("------------------------")
print("Chemical formula: {}".format(self.chemical_formula))
if self.numeric_density:
print("Numeric Density: {}".format(self.numeric_density))
if self.number_density:
print("Number Density: {}".format(self.number_density))
else:
print("Numeric Density: Set from elemental properties by Mantid")
print("Number Density: Set from elemental properties by Mantid")
self._print_material_properties()
def _print_material_properties(self):
......
......@@ -149,7 +149,7 @@ class ISISPowderSampleDetailsTest(unittest.TestCase):
material_obj_one_char = sample_details._Material(chemical_formula=chemical_formula_one_char_element)
self.assertIsNotNone(material_obj_one_char)
self.assertEqual(material_obj_one_char.chemical_formula, chemical_formula_one_char_element)
self.assertIsNone(material_obj_one_char.numeric_density)
self.assertIsNone(material_obj_one_char.number_density)
# Also check that the absorption and scattering X sections have not been set
self.assertIsNone(material_obj_one_char.absorption_cross_section)
......@@ -160,12 +160,12 @@ class ISISPowderSampleDetailsTest(unittest.TestCase):
material_obj_two_char = sample_details._Material(chemical_formula=chemical_formula_two_char_element)
self.assertIsNotNone(material_obj_two_char)
self.assertEqual(material_obj_two_char.chemical_formula, chemical_formula_two_char_element)
self.assertIsNone(material_obj_two_char.numeric_density)
self.assertIsNone(material_obj_two_char.number_density)
# Check it stores numeric density if passed
material_obj_numeric_density = sample_details._Material(chemical_formula=chemical_formula_two_char_element,
numeric_density=numeric_density_sample)
self.assertEqual(material_obj_numeric_density.numeric_density, numeric_density_sample)
self.assertEqual(material_obj_numeric_density.number_density, numeric_density_sample)
# Check that it raises an error if we have a non-elemental formula without numeric density
with assertRaisesRegex(self, ValueError, "A numeric density formula must be set on a chemical formula"):
......@@ -175,7 +175,7 @@ class ISISPowderSampleDetailsTest(unittest.TestCase):
material_obj_num_complex_formula = sample_details._Material(chemical_formula=chemical_formula_complex,
numeric_density=numeric_density_sample)
self.assertEqual(material_obj_num_complex_formula.chemical_formula, chemical_formula_complex)
self.assertEqual(material_obj_num_complex_formula.numeric_density, numeric_density_sample)
self.assertEqual(material_obj_num_complex_formula.number_density, numeric_density_sample)
def test_material_set_properties(self):
bad_absorb = '-1'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment