Skip to content
Snippets Groups Projects
Commit 5b44344b authored by Elliot Oram's avatar Elliot Oram
Browse files

Merge pull request #13963 from mantidproject/13960_evs_diffraction_algo

Add VESUVIO diffraction algorithm
parents 6367a7d6 671bb070
No related branches found
No related tags found
No related merge requests found
from mantid.simpleapi import *
from mantid.api import *
from mantid.kernel import *
from mantid import config
import os
class EVSDiffractionReduction(DataProcessorAlgorithm):
_workspace_names = None
_chopped_data = None
_output_ws = None
_data_files = None
_instrument_name = None
_mode = None
_par_filename = None
_spectra_range = None
_grouping_method = None
_rebin_string = None
_ipf_filename = None
_sum_files = None
def category(self):
return 'Diffraction;PythonAlgorithms'
def summary(self):
return 'Performs diffraction reduction for VESUVIO'
def PyInit(self):
self.declareProperty(StringArrayProperty('InputFiles'),
doc='Comma separated list of input files.')
self.declareProperty(FileProperty('InstrumentParFile', '',
action=FileAction.Load,
extensions=['.dat', '.par']),
doc='PAR file containing instrument definition.')
self.declareProperty(name='SumFiles', defaultValue=False,
doc='Enabled to sum spectra from each input file.')
self.declareProperty(IntArrayProperty('SpectraRange', [3, 198]),
doc='Range of spectra to use.')
self.declareProperty(name='RebinParam', defaultValue='',
doc='Rebin parameters.')
self.declareProperty(name='GroupingPolicy', defaultValue='All',
validator=StringListValidator(['All', 'Individual', 'IPF']),
doc='Selects the type of detector grouping to be used.')
self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '',
direction=Direction.Output),
doc='Group name for the result workspaces.')
def validateInputs(self):
"""
Checks for issues with user input.
"""
issues = dict()
# Validate input files
input_files = self.getProperty('InputFiles').value
if len(input_files) == 0:
issues['InputFiles'] = 'InputFiles must contain at least one filename'
# Validate detector range
detector_range = self.getProperty('SpectraRange').value
if len(detector_range) != 2:
issues['SpectraRange'] = 'SpectraRange must be an array of 2 values only'
else:
if detector_range[0] > detector_range[1]:
issues['SpectraRange'] = 'SpectraRange must be in format [lower_index,upper_index]'
return issues
def PyExec(self):
from IndirectReductionCommon import (load_files,
get_multi_frame_rebin,
identify_bad_detectors,
unwrap_monitor,
process_monitor_efficiency,
scale_monitor,
scale_detectors,
rebin_reduction,
group_spectra,
fold_chopped,
rename_reduction)
self._setup()
load_opts = dict()
load_opts['Mode'] = 'FoilOut'
load_opts['InstrumentParFile'] = self._par_filename
self._workspace_names, self._chopped_data = load_files(self._data_files,
ipf_filename=self._ipf_filename,
spec_min=self._spectra_range[0],
spec_max=self._spectra_range[1],
sum_files=self._sum_files,
load_opts=load_opts)
for c_ws_name in self._workspace_names:
is_multi_frame = isinstance(mtd[c_ws_name], WorkspaceGroup)
# Get list of workspaces
if is_multi_frame:
workspaces = mtd[c_ws_name].getNames()
else:
workspaces = [c_ws_name]
# Process rebinning for framed data
rebin_string_2, num_bins = get_multi_frame_rebin(c_ws_name,
self._rebin_string)
masked_detectors = identify_bad_detectors(workspaces[0])
# Process workspaces
for ws_name in workspaces:
monitor_ws_name = ws_name + '_mon'
# Process monitor
if not unwrap_monitor(ws_name):
ConvertUnits(InputWorkspace=monitor_ws_name,
OutputWorkspace=monitor_ws_name,
Target='Wavelength',
EMode='Elastic')
process_monitor_efficiency(ws_name)
scale_monitor(ws_name)
# Scale detector data by monitor intensities
scale_detectors(ws_name, 'Elastic')
# Remove the no longer needed monitor workspace
DeleteWorkspace(monitor_ws_name)
# Convert to dSpacing
ConvertUnits(InputWorkspace=ws_name,
OutputWorkspace=ws_name,
Target='dSpacing',
EMode='Elastic')
# Handle rebinning
rebin_reduction(ws_name,
self._rebin_string,
rebin_string_2,
num_bins)
# Group spectra
group_spectra(ws_name,
masked_detectors,
self._grouping_method)
if is_multi_frame:
fold_chopped(c_ws_name)
# Rename output workspaces
output_workspace_names = [rename_reduction(ws_name, self._sum_files) for ws_name in self._workspace_names]
# Group result workspaces
GroupWorkspaces(InputWorkspaces=output_workspace_names,
OutputWorkspace=self._output_ws)
self.setProperty('OutputWorkspace', self._output_ws)
def _setup(self):
"""
Gets algorithm properties.
"""
self._instrument_name = 'VESUVIO'
self._mode = 'diffspec'
self._output_ws = self.getPropertyValue('OutputWorkspace')
self._data_files = self.getProperty('InputFiles').value
self._par_filename = self.getPropertyValue('InstrumentParFile')
self._spectra_range = self.getProperty('SpectraRange').value
self._rebin_string = self.getPropertyValue('RebinParam')
self._grouping_method = self.getPropertyValue('GroupingPolicy')
if self._rebin_string == '':
self._rebin_string = None
# Get the IPF filename
self._ipf_filename = self._instrument_name + '_diffraction_' + self._mode + '_Parameters.xml'
if not os.path.exists(self._ipf_filename):
self._ipf_filename = os.path.join(config['instrumentDefinition.directory'], self._ipf_filename)
logger.information('IPF filename is: %s' % (self._ipf_filename))
# Only enable sum files if we actually have more than one file
sum_files = self.getProperty('SumFiles').value
self._sum_files = False
if sum_files:
num_raw_files = len(self._data_files)
if num_raw_files > 1:
self._sum_files = True
logger.information('Summing files enabled (have %d files)' % num_raw_files)
else:
logger.information('SumFiles options is ignored when only one file is provided')
AlgorithmFactory.subscribe(EVSDiffractionReduction)
...@@ -26,6 +26,7 @@ set ( TEST_PY_FILES ...@@ -26,6 +26,7 @@ set ( TEST_PY_FILES
EnggFitPeaksTest.py EnggFitPeaksTest.py
EnggFocusTest.py EnggFocusTest.py
EnggVanadiumCorrectionsTest.py EnggVanadiumCorrectionsTest.py
EVSDiffractionReductionTest.py
FilterLogByTimeTest.py FilterLogByTimeTest.py
FindReflectometryLinesTest.py FindReflectometryLinesTest.py
FlatPlatePaalmanPingsCorrectionTest.py FlatPlatePaalmanPingsCorrectionTest.py
......
#pylint: disable=too-many-public-methods,invalid-name
import unittest
from mantid.simpleapi import *
from mantid.api import *
class EVDDiffractionReductionTest(unittest.TestCase):
def test_basic_reduction_completes(self):
"""
Sanity test to ensure the most basic reduction actually completes.
"""
wks = EVSDiffractionReduction(InputFiles=['EVS15289.raw'],
InstrumentParFIle='IP0005.dat')
self.assertTrue(isinstance(wks, WorkspaceGroup), 'Result workspace should be a workspace group.')
self.assertEqual(len(wks), 1)
self.assertEqual(wks.getNames()[0], 'EVS15289_diffspec_red')
red_ws = wks[0]
self.assertEqual(red_ws.getAxis(0).getUnit().unitID(), 'dSpacing')
self.assertEqual(red_ws.getNumberHistograms(), 1)
def test_grouping_individual(self):
"""
Test setting individual grouping, one spectrum per detector.
"""
wks = EVSDiffractionReduction(InputFiles=['EVS15289.raw'],
GroupingPolicy='Individual',
InstrumentParFIle='IP0005.dat')
self.assertTrue(isinstance(wks, WorkspaceGroup), 'Result workspace should be a workspace group.')
self.assertEqual(len(wks), 1)
red_ws = wks[0]
self.assertEqual(red_ws.getAxis(0).getUnit().unitID(), 'dSpacing')
self.assertEqual(red_ws.getNumberHistograms(), 196)
if __name__ == '__main__':
unittest.main()
ea1cb1b0d1daa9579fbeb4acf3716162
\ No newline at end of file
ea1cb1b0d1daa9579fbeb4acf3716162
\ No newline at end of file
.. algorithm::
.. summary::
.. alias::
.. properties::
Description
-----------
A version of :ref:`ISISIndirectDiffractionReduction
<algm-ISISIndirectDiffractionReduction>` specific to use with VESUVIO (EVS)
data, the reduction is performed in the same way however there is the additional
option to load a PAR file.
Usage
-----
**Example - Running EVSDiffractionReduction.**
.. testcode:: ExEVSDiffractionReductionSimple
EVSDiffractionReduction(InputFiles='EVS15289.raw',
OutputWorkspace='DiffractionReductions',
InstrumentParFile='IP0005.dat')
ws = mtd['DiffractionReductions'].getItem(0)
print 'Workspace name: %s' % ws.getName()
print 'Number of spectra: %d' % ws.getNumberHistograms()
print 'Number of bins: %s' % ws.blocksize()
Output:
.. testoutput:: ExEVSDiffractionReductionSimple
Workspace name: EVS15289_diffspec_red
Number of spectra: 1
Number of bins: 3875
.. categories::
.. sourcelink::
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