Newer
Older
# Mantid Repository : https://github.com/mantidproject/mantid
#
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
# NScD Oak Ridge National Laboratory, European Spallation Source
# & Institut Laue - Langevin
# SPDX - License - Identifier: GPL - 3.0 +
from __future__ import (absolute_import, division, print_function)
from mantid.simpleapi import *
from mantid.kernel import *
from mantid.api import *
class LiveValue():
def __init__(self, value, unit):
self.value = value
self.unit = unit
class ReflectometryReductionOneLiveData(DataProcessorAlgorithm):
def category(self):
return 'Reflectometry'
def summary(self):
return 'Run the reflectometry reduction algorithm on live data'
def seeAlso(self):
return ["ReflectometryReductionOneAuto", "StartLiveData"]
instruments = ['CRISP', 'INTER', 'OFFSPEC', 'POLREF', 'SURF']
defaultInstrument = str(config.getInstrument())
defaultInstrument = defaultInstrument if defaultInstrument in instruments else instruments[0]
self.declareProperty(name='Instrument', defaultValue=defaultInstrument, direction=Direction.Input,
validator=StringListValidator(instruments),
doc='Instrument to find live value for.')
self.declareProperty(name='GetLiveValueAlgorithm', defaultValue='GetLiveInstrumentValue',
direction=Direction.Input,
doc='The algorithm to use to get live values from the instrument')
'InputWorkspace', 'SummationType', 'ReductionType', 'IncludePartialBins',
'AnalysisMode', 'ProcessingInstructions', 'CorrectDetectors',
'DetectorCorrectionType', 'WavelengthMin', 'WavelengthMax', 'I0MonitorIndex',
'MonitorBackgroundWavelengthMin', 'MonitorBackgroundWavelengthMax',
'MonitorIntegrationWavelengthMin', 'MonitorIntegrationWavelengthMax',
'NormalizeByIntegratedMonitors', 'FirstTransmissionRun',
'SecondTransmissionRun', 'Params', 'StartOverlap', 'EndOverlap',
'StrictSpectrumChecking', 'CorrectionAlgorithm', 'Polynomial', 'C0', 'C1',
'MomentumTransferMin', 'MomentumTransferStep', 'MomentumTransferMax',
'PolarizationAnalysis', 'Pp', 'Ap', 'Rho', 'Alpha', 'Debug', 'OutputWorkspace']
self.copyProperties('ReflectometryReductionOneAuto', self._child_properties)
self._setup_workspace_for_reduction()
alg = self._setup_reduction_algorithm()
self._run_reduction_algorithm(alg)
"""Set up the workspace ready for the reduction"""
self._create_workspace_for_reduction()
self._setup_instrument()
liveValues = self._get_live_values_from_instrument()
self._setup_sample_logs(liveValues)
self._setup_slits(liveValues)
"""Set up the reduction algorithm"""
alg = AlgorithmManager.create("ReflectometryReductionOneAuto")
alg.initialize()
self._copy_property_values_to(alg)
alg.setProperty("InputWorkspace", self._ws_name)
alg.setProperty("OutputWorkspaceBinned", self._ws_name)
"""Run the reduction"""
alg.execute()
out_ws = alg.getProperty("OutputWorkspaceBinned").value
self.setProperty("OutputWorkspace", out_ws)
def _create_workspace_for_reduction(self):
"""Create a workspace for the input/output to the reduction algorithm"""
in_ws_name = self.getProperty("InputWorkspace").value.getName()
self._ws_name = self.getPropertyValue("OutputWorkspace")
CloneWorkspace(InputWorkspace=in_ws_name, OutputWorkspace=self._ws_name)
"""Sets the instrument name and loads the instrument on the workspace"""
self._instrument = self.getProperty('Instrument').value
LoadInstrument(Workspace=self._ws_name, RewriteSpectraMap=True,
InstrumentName=self._instrument)
"""Set up the sample logs based on live values from the instrument"""
logNames = [key for key in liveValues]
logValues = [liveValues[key].value for key in liveValues]
logUnits = [liveValues[key].unit for key in liveValues]
AddSampleLogMultiple(Workspace=self._ws_name, LogNames=logNames,
LogValues=logValues, LogUnits=logUnits)
"""Set up instrument parameters for the slits"""
s1 = liveValues[self._s1vg_name()].value
s2 = liveValues[self._s2vg_name()].value
SetInstrumentParameter(Workspace=self._ws_name,
ParameterName='vertical gap',
ParameterType='Number',
ComponentName='slit1',
Value=str(s1))
SetInstrumentParameter(Workspace=self._ws_name,
ParameterName='vertical gap',
ParameterType='Number',
ComponentName='slit2',
Value=str(s2))
def _copy_property_values_to(self, alg):
for prop in self._child_properties:
value = self.getPropertyValue(prop)
alg.setPropertyValue(prop, value)
def _get_live_values_from_instrument(self):
for key in liveValues:
if liveValues[key].value is None:
liveValues[key].value = self._get_block_value_from_instrument(key)
def _s1vg_name(self):
if self._instrument == 'INTER' or self._instrument == 'SURF':
return 's1vgap'
else:
return 's1vg'
def _s2vg_name(self):
if self._instrument == 'INTER' or self._instrument == 'SURF':
return 's2vgap'
else:
return 's2vg'
def _get_double_or_none(self, propertyName):
value = self.getProperty(propertyName)
if value == Property.EMPTY_DBL:
return None
return value.value
"""Get the list of required live value names and their unit type"""
liveValues = {'Theta': LiveValue(None, 'deg'),
self._s1vg_name(): LiveValue(None, 'm'),
self._s2vg_name(): LiveValue(None, 'm')}
def _get_block_value_from_instrument(self, logName):
algName = self.getProperty('GetLiveValueAlgorithm').value
alg = self.createChildAlgorithm(algName)
alg.setProperty('Instrument', self._instrument)
alg.setProperty('PropertyType', 'Block')
alg.setProperty('PropertyName', logName)
return alg.getProperty("Value").value
def _validate_live_values(self, liveValues):
for key in liveValues:
if liveValues[key].value is None:
raise RuntimeError('Required value ' + key + ' was not found for instrument')
if float(liveValues['Theta'].value) <= 1e-06:
raise RuntimeError('Theta must be greater than zero')
AlgorithmFactory.subscribe(ReflectometryReductionOneLiveData)