Skip to content

Commit

Permalink
Cherry pick pull request #18888
Browse files Browse the repository at this point in the history
Refs #18877 Add handling of missing file extension

(cherry picked from commit 6977e9e)

Refs #18877 Add correct workspace name for batch reduce

(cherry picked from commit 78de78b)

Refs #18877 Add metadata to saving

(cherry picked from commit c517eb0)

Refs #18877 Fix trailing white space

(cherry picked from commit d135f78)

Refs #188877 Grab geom info at right point

(cherry picked from commit bc7aed4)

Add patch release note
  • Loading branch information
martyngigg committed Feb 23, 2017
1 parent 6f71ba7 commit 8397a19
Show file tree
Hide file tree
Showing 5 changed files with 313 additions and 23 deletions.
3 changes: 3 additions & 0 deletions docs/source/release/v3.9.1/index.rst
Expand Up @@ -30,6 +30,7 @@ Changes in this version
* `18865 <https://www.github.com/mantidproject/mantid/pull/18865>`_ Fix bug in reflectometry GUI
* `18875 <https://www.github.com/mantidproject/mantid/pull/18875>`_ U correction not correctly applied to viewport
* `18884 <https://www.github.com/mantidproject/mantid/pull/18884>`_ Add support for NeXus files in LoadVesuvio
* `18888 <https://www.github.com/mantidproject/mantid/pull/18888>`_ Fix LOQ Batch reduction issues
* `18891 <https://www.github.com/mantidproject/mantid/pull/18891>`_ Fix bug in gd_prtn_chrg for chunked data
* `18907 <https://www.github.com/mantidproject/mantid/pull/18907>`_ Fix zeropadding for IMAT in Facilities.XML
* `18914 <https://www.github.com/mantidproject/mantid/pull/18914>`_ Fix mass ws deletion bug
Expand Down Expand Up @@ -57,6 +58,8 @@ Summary of impact
+-------+-----------------------------------------------------------------------------------+---------------------------------------------+--------------+
| 18884 | Allows Vesuvio to Load NeXus files from current cycle | Use Load not LoadRaw in algorithm | **medium** |
+-------+-----------------------------------------------------------------------------------+---------------------------------------------+--------------+
| 18888 | Fixes batch reduction for LOQ at ISIS | Checks correctly for userfile in batch run | **medium** |
+-------+-----------------------------------------------------------------------------------+---------------------------------------------+--------------+
| 18891 | Fixes bug in gd_prtn_chrg for chunked data | Recalculate proton charge just prior to use | **low** |
+-------+-----------------------------------------------------------------------------------+---------------------------------------------+--------------+
| 18907 | Allows IMAT to use general file finding mechanism | Facilities file update | **low** |
Expand Down
112 changes: 91 additions & 21 deletions scripts/SANS/SANSBatchMode.py
Expand Up @@ -140,6 +140,44 @@ def get_transmission_properties(workspace):
return transmission_properties


def get_geometry_properties(reducer):
"""
This extracts geometry properties from the ReductionSingleton. They are saved in the CanSAS1D format.
@param reducer: a handle to the redcution singleton
@return: a dict with geometry properties
"""
def _add_property(key, element, props):
if element is None:
raise RuntimeError("Could not extract value for {0}.".format(key))
props.update({key: element})

geometry_properties = {}
geometry = reducer.get_sample().geometry

# Get the shape
shape = geometry.shape
if shape == 'cylinder-axis-up':
shape_to_save = "Cylinder"
elif shape == 'cuboid':
shape_to_save = "Flat plate"
elif shape == 'cylinder-axis-along':
shape_to_save = 'Disc'
else:
raise RuntimeError("Unknown shape {0}. Cannot extract property".format(shape))
geometry_properties.update({"Geometry": shape_to_save})

# Get the Height
_add_property("SampleHeight", geometry.height, geometry_properties)

# Get the Width
_add_property("SampleWidth", geometry.width, geometry_properties)

# Get the thickness
_add_property("SampleThickness", geometry.thickness, geometry_properties)
return geometry_properties


def BatchReduce(filename, format, plotresults=False, saveAlgs={'SaveRKH':'txt'},verbose=False,
centreit=False, reducer=None, combineDet=None, save_as_zero_error_free=False):
"""
Expand Down Expand Up @@ -197,14 +235,21 @@ def BatchReduce(filename, format, plotresults=False, saveAlgs={'SaveRKH':'txt'},
original_user_file=original_user_file,
original_settings = settings,
original_prop_man_settings = prop_man_settings)
except (RunTimeError, ValueError) as e:
# When we set a new user file, that means that the combineDet feature could be invalid,
# ie if the detector under investigation changed in the user file. We need to change this
# here too. But only if it is not None.
if combineDet is not None:
new_combineDet = ReductionSingleton().instrument.get_detector_selection()
combineDet = su.get_correct_combinDet_setting(ins_name, new_combineDet)
except (RuntimeError, ValueError) as e:
sanslog.warning("Error in Batchmode user files: Could not reset the specified user file %s. More info: %s" %(
str(run['user_file']),str(e)))
str(run['user_file']), str(e)))

local_settings = copy.deepcopy(ReductionSingleton().reference())
local_prop_man_settings = ReductionSingleton().settings.clone("TEMP_SETTINGS")

raw_workspaces = []
geometry_properties = {}
try:
# Load in the sample runs specified in the csv file
raw_workspaces.append(read_run(run, 'sample_sans', format))
Expand All @@ -222,6 +267,12 @@ def BatchReduce(filename, format, plotresults=False, saveAlgs={'SaveRKH':'txt'},
if verbose == 1:
FindBeamCentre(50.,170.,12)

try:
geometry_properties = get_geometry_properties(ReductionSingleton())
except RuntimeError as e:
message = "Could not extract geometry properties from the reducer: {0}".format(str(e))
sanslog.warning(message)

# WavRangeReduction runs the reduction for the specified
# wavelength range where the final argument can either be
# DefaultTrans or CalcTrans:
Expand Down Expand Up @@ -254,34 +305,42 @@ def BatchReduce(filename, format, plotresults=False, saveAlgs={'SaveRKH':'txt'},
final_name = sanitize_name(final_name)

#convert the names from the default one, to the agreement
# This caused a renaming with the following logic
# | combinDet | Name HAB | Name LAB | Name Merged |
# | rear | +_rear | - | - |
# | front | - | +_front | - |
# | both | +_rear | +_front | - |
# | merged | +_rear | +_front | +_merged |
# This is not great since it uses SANS2D terminology for all instruments

names = [final_name]
if combineDet == 'rear':
names = [final_name+'_rear']
RenameWorkspace(InputWorkspace=reduced,OutputWorkspace= final_name+'_rear')
new_name = su.rename_workspace_correctly(ins_name, su.ReducedType.LAB, final_name, reduced)
names = [new_name]
elif combineDet == 'front':
names = [final_name+'_front']
RenameWorkspace(InputWorkspace=reduced,OutputWorkspace= final_name+'_front')
new_name = su.rename_workspace_correctly(ins_name, su.ReducedType.HAB, final_name, reduced)
names = [new_name]
elif combineDet == 'both':
names = [final_name+'_front', final_name+'_rear']
if ins_name == 'SANS2D':
rear_reduced = reduced.replace('front','rear')
rear_reduced = reduced.replace('front', 'rear')
else: #if ins_name == 'lOQ':
rear_reduced = reduced.replace('HAB','main')
RenameWorkspace(InputWorkspace=reduced,OutputWorkspace=final_name+'_front')
RenameWorkspace(InputWorkspace=rear_reduced,OutputWorkspace=final_name+'_rear')
rear_reduced = reduced.replace('HAB', 'main')
new_name_HAB = su.rename_workspace_correctly(ins_name, su.ReducedType.HAB, final_name, reduced)
new_name_LAB = su.rename_workspace_correctly(ins_name, su.ReducedType.LAB, final_name, rear_reduced)
names = [new_name_HAB, new_name_LAB]
elif combineDet == 'merged':
names = [final_name + '_merged', final_name + '_rear', final_name+'_front']
if ins_name == 'SANS2D':
rear_reduced = reduced.replace('merged','rear')
front_reduced = reduced.replace('merged','front')
rear_reduced = reduced.replace('merged', 'rear')
front_reduced = reduced.replace('merged', 'front')
else:
rear_reduced = reduced.replace('_merged','')
front_reduced = rear_reduced.replace('main','HAB')
RenameWorkspace(InputWorkspace=reduced,OutputWorkspace= final_name + '_merged')
RenameWorkspace(InputWorkspace=rear_reduced,OutputWorkspace= final_name + '_rear')
RenameWorkspace(InputWorkspace=front_reduced,OutputWorkspace= final_name+'_front')
rear_reduced = reduced.replace('_merged', '')
front_reduced = rear_reduced.replace('main', 'HAB')
new_name_Merged = su.rename_workspace_correctly(ins_name, su.ReducedType.Merged, final_name, reduced)
new_name_LAB = su.rename_workspace_correctly(ins_name, su.ReducedType.LAB, final_name, rear_reduced)
new_name_HAB = su.rename_workspace_correctly(ins_name, su.ReducedType.HAB, final_name, front_reduced)
names = [new_name_Merged, new_name_LAB, new_name_HAB]
else:
RenameWorkspace(InputWorkspace=reduced,OutputWorkspace=final_name)
RenameWorkspace(InputWorkspace=reduced, OutputWorkspace=final_name)

file = run['output_as']
#saving if optional and doesn't happen if the result workspace is left blank. Is this feature used?
Expand Down Expand Up @@ -310,6 +369,11 @@ def BatchReduce(filename, format, plotresults=False, saveAlgs={'SaveRKH':'txt'},
# sample logs.
_ws = mtd[workspace_name]
transmission_properties = get_transmission_properties(_ws)

# Add the geometry properties if they exist
if geometry_properties:
transmission_properties.update(geometry_properties)

# Call the SaveCanSAS1D with the Transmission and TransmissionCan if they are
# available
SaveCanSAS1D(save_names_dict[workspace_name], workspace_name+ext, DetectorNames=detnames,
Expand Down Expand Up @@ -496,7 +560,13 @@ def setUserFileInBatchMode(new_user_file, current_user_file, original_user_file,

# Try to find the user file in the default paths
if not os.path.isfile(new_user_file):
user_file = FileFinder.getFullPath(new_user_file)
# Find the user file in the Mantid path. we make sure that the user file has a txt extension.
user_file_names_with_extension = su.get_user_file_name_options_with_txt_extension(new_user_file)
for user_file_name_with_extension in user_file_names_with_extension:
user_file = FileFinder.getFullPath(user_file_name_with_extension)
if user_file:
break

if not os.path.isfile(user_file):
user_file_to_set = original_user_file
else:
Expand Down
106 changes: 106 additions & 0 deletions scripts/SANS/SANSUtility.py
Expand Up @@ -1962,6 +1962,112 @@ def get_unfitted_transmission_workspace_name(workspace_name):
return unfitted_workspace_name


def get_user_file_name_options_with_txt_extension(user_file_name):
"""
A user file is a .txt file. The user file can be specified without the .txt ending. Which will prevent the
FileFinder from picking it up.
@param user_file_name: the name of the user file
@return: either the original user file name or a list of user file names with .txt and .TXT extensions
"""
capitalized_user_file = user_file_name.upper()
if capitalized_user_file.endswith('.TXT'):
user_file_with_extension = [user_file_name]
else:
user_file_with_extension = [user_file_name + ".txt", user_file_name + ".TXT"]
return user_file_with_extension


def get_correct_combinDet_setting(instrument_name, detector_selection):
"""
We want to get the correct combinDet variable for batch reductions from a new detector selection.
@param instrument_name: the name of the intrument
@param detector_selection: a detector selection comes directly from the reducer
@return: a combinedet option
"""
if detector_selection is None:
return None

instrument_name = instrument_name.upper()
# If we are dealing with LARMOR, then the correct combineDet selection is None
if instrument_name == "LARMOR":
return None

detector_selection = detector_selection.upper()
# If we are dealing with LOQ, then the correct combineDet selection is
if instrument_name == "LOQ":
if detector_selection == "MAIN":
new_combine_detector_selection = 'rear'
elif detector_selection == "HAB":
new_combine_detector_selection = 'front'
elif detector_selection == "MERGED":
new_combine_detector_selection = 'merged'
elif detector_selection == "BOTH":
new_combine_detector_selection = 'both'
else:
raise RuntimeError("SANSBatchReduce: Unknown detector {0} for conversion "
"to combineDet.".format(detector_selection))
return new_combine_detector_selection

# If we are dealing with SANS2D, then the correct combineDet selection is
if instrument_name == "SANS2D":
if detector_selection == "REAR":
new_combine_detector_selection = 'rear'
elif detector_selection == "FRONT":
new_combine_detector_selection = 'front'
elif detector_selection == "MERGED":
new_combine_detector_selection = 'merged'
elif detector_selection == "BOTH":
new_combine_detector_selection = 'both'
else:
raise RuntimeError("SANSBatchReduce: Unknown detector {0} for conversion "
"to combineDet.".format(detector_selection))
return new_combine_detector_selection
raise RuntimeError("SANSBatchReduce: Unknown instrument {0}.".format(instrument_name))


class ReducedType(object):
class LAB(object):
pass

class HAB(object):
pass

class Merged(object):
pass


def rename_workspace_correctly(instrument_name, reduced_type, final_name, workspace):
def get_suffix(inst_name, red_type):
if inst_name == "SANS2D":
if red_type is ReducedType.LAB:
suffix = "_rear"
elif red_type is ReducedType.HAB:
suffix = "_front"
elif red_type is ReducedType.Merged:
suffix = "_merged"
else:
raise RuntimeError("Unknown reduction type {0}.".format(red_type))
return suffix
elif inst_name == "LOQ":
if red_type is ReducedType.LAB:
suffix = "_main"
elif red_type is ReducedType.HAB:
suffix = "_hab"
elif red_type is ReducedType.Merged:
suffix = "_merged"
else:
raise RuntimeError("Unknown reduction type {0}.".format(red_type))
return suffix
else:
return ""
final_suffix = get_suffix(instrument_name, reduced_type)
complete_name = final_name + final_suffix
RenameWorkspace(InputWorkspace=workspace, OutputWorkspace=complete_name)
return complete_name


###############################################################################
######################### Start of Deprecated Code ############################
###############################################################################
Expand Down
17 changes: 17 additions & 0 deletions scripts/test/SANSBatchModeTest.py
Expand Up @@ -142,5 +142,22 @@ def test_reducer_is_not_reset_if_file_to_set_is_original_and_current(self):
# Clean up
self._delete_minimal_user_files(user_files)


class TestGeometrySettings(unittest.TestCase):
def test_that_can_get_geometry_properties(self):
LOQ()
reducer = ReductionSingleton()
geometry_settings = bm.get_geometry_properties(reducer)
self.assertTrue("Geometry" in geometry_settings)
self.assertTrue("SampleHeight" in geometry_settings)
self.assertTrue("SampleWidth" in geometry_settings)
self.assertTrue("SampleThickness" in geometry_settings)

self.assertTrue(geometry_settings["Geometry"] == "Disc")
self.assertTrue(geometry_settings["SampleHeight"] == 1.)
self.assertTrue(geometry_settings["SampleWidth"] == 1.)
self.assertTrue(geometry_settings["SampleThickness"] == 1.)


if __name__ == "__main__":
unittest.main()

0 comments on commit 8397a19

Please sign in to comment.