Skip to content
Snippets Groups Projects
Commit dd9d7eac authored by Doucet, Mathieu's avatar Doucet, Mathieu
Browse files

Re #23576 add overwrite options

parent b7b92ece
No related merge requests found
#pylint: disable=no-init,invalid-name #pylint: disable=no-init,invalid-name
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
from mantid.api import PythonAlgorithm, AlgorithmFactory, WorkspaceProperty from mantid.api import PythonAlgorithm, AlgorithmFactory, WorkspaceProperty
from mantid.kernel import Direction, FloatBoundedValidator from mantid.kernel import Direction, FloatBoundedValidator, Property
import mantid.simpleapi import mantid.simpleapi
import math import math
...@@ -27,8 +27,9 @@ class MRGetTheta(PythonAlgorithm): ...@@ -27,8 +27,9 @@ class MRGetTheta(PythonAlgorithm):
self.declareProperty("AngleOffset", 0.,FloatBoundedValidator(lower=0.), "Angle offset (rad)") self.declareProperty("AngleOffset", 0.,FloatBoundedValidator(lower=0.), "Angle offset (rad)")
self.declareProperty("UseSANGLE", False, doc="If True, use SANGLE as the scattering angle. If False, use DANGLE.") self.declareProperty("UseSANGLE", False, doc="If True, use SANGLE as the scattering angle. If False, use DANGLE.")
self.declareProperty("SpecularPixel", 0., doc="Pixel position of the specular reflectivity [optional]") self.declareProperty("SpecularPixel", 0., doc="Pixel position of the specular reflectivity [optional]")
self.declareProperty("Theta", 0., direction=Direction.Output, doc="Scattering angle theta [rad]") self.declareProperty("DirectPixelOverwrite", Property.EMPTY_DBL, doc="DIRPIX overwrite value")
self.declareProperty("DAngle0Overwrite", Property.EMPTY_DBL, doc="DANGLE0 overwrite value (degrees)")
self.declareProperty("Theta", 0., direction=Direction.Output, doc="Scattering angle theta (rad)")
return return
def PyExec(self): def PyExec(self):
...@@ -36,14 +37,23 @@ class MRGetTheta(PythonAlgorithm): ...@@ -36,14 +37,23 @@ class MRGetTheta(PythonAlgorithm):
_w=self.getProperty("Workspace").value _w=self.getProperty("Workspace").value
angle_offset = self.getProperty("AngleOffset").value angle_offset = self.getProperty("AngleOffset").value
dirpix_overwrite = self.getProperty("DirectPixelOverwrite").value
dangle0_overwrite = self.getProperty("DAngle0Overwrite").value
use_sangle = self.getProperty("UseSANGLE").value
if self.getProperty("UseSANGLE").value: if use_sangle:
theta = self.read_log(_w, 'SANGLE', target_units='rad', assumed_units='deg') theta = self.read_log(_w, 'SANGLE', target_units='rad', assumed_units='deg')
else: else:
dangle = self.read_log(_w, 'DANGLE', target_units='rad', assumed_units='deg') dangle = self.read_log(_w, 'DANGLE', target_units='rad', assumed_units='deg')
dangle0 = self.read_log(_w, 'DANGLE0', target_units='rad', assumed_units='deg') if dangle0_overwrite == Property.EMPTY_DBL:
dangle0 = self.read_log(_w, 'DANGLE0', target_units='rad', assumed_units='deg')
else:
dangle0 = dangle0_overwrite * math.pi / 180.0
det_distance = self.read_log(_w, 'SampleDetDis', target_units='m', assumed_units='mm') det_distance = self.read_log(_w, 'SampleDetDis', target_units='m', assumed_units='mm')
direct_beam_pix = _w.getRun()['DIRPIX'].getStatistics().mean if dirpix_overwrite == Property.EMPTY_DBL:
direct_beam_pix = _w.getRun()['DIRPIX'].getStatistics().mean
else:
direct_beam_pix = dirpix_overwrite
ref_pix = self.getProperty("SpecularPixel").value ref_pix = self.getProperty("SpecularPixel").value
if ref_pix == 0.: if ref_pix == 0.:
ref_pix = direct_beam_pix ref_pix = direct_beam_pix
......
...@@ -58,6 +58,8 @@ class MRInspectData(PythonAlgorithm): ...@@ -58,6 +58,8 @@ class MRInspectData(PythonAlgorithm):
"Pixel range defining the background") "Pixel range defining the background")
self.declareProperty("EventThreshold", 10000, self.declareProperty("EventThreshold", 10000,
"Minimum number of events needed to call a data set a valid direct beam") "Minimum number of events needed to call a data set a valid direct beam")
self.declareProperty("DirectPixelOverwrite", Property.EMPTY_DBL, doc="DIRPIX overwrite value")
self.declareProperty("DAngle0Overwrite", Property.EMPTY_DBL, doc="DANGLE0 overwrite value (degrees)")
def PyExec(self): def PyExec(self):
nxs_data = self.getProperty("Workspace").value nxs_data = self.getProperty("Workspace").value
...@@ -74,7 +76,9 @@ class MRInspectData(PythonAlgorithm): ...@@ -74,7 +76,9 @@ class MRInspectData(PythonAlgorithm):
low_res_roi=self.getProperty("LowResPeakROI").value, low_res_roi=self.getProperty("LowResPeakROI").value,
force_bck_roi=self.getProperty("ForceBckROI").value, force_bck_roi=self.getProperty("ForceBckROI").value,
bck_roi=self.getProperty("BckROI").value, bck_roi=self.getProperty("BckROI").value,
event_threshold=self.getProperty("EventThreshold").value) event_threshold=self.getProperty("EventThreshold").value,
dirpix_overwrite=self.getProperty("DirectPixelOverwrite").value,
dangle0_overwrite=self.getProperty("DAngle0Overwrite").value)
# Store information in logs # Store information in logs
mantid.simpleapi.AddSampleLog(Workspace=nxs_data, LogName='calculated_scatt_angle', mantid.simpleapi.AddSampleLog(Workspace=nxs_data, LogName='calculated_scatt_angle',
...@@ -146,7 +150,8 @@ class DataInfo(object): ...@@ -146,7 +150,8 @@ class DataInfo(object):
def __init__(self, ws, cross_section='', use_roi=True, update_peak_range=False, use_roi_bck=False, def __init__(self, ws, cross_section='', use_roi=True, update_peak_range=False, use_roi_bck=False,
use_tight_bck=False, bck_offset=3, force_peak_roi=False, peak_roi=[0,0], use_tight_bck=False, bck_offset=3, force_peak_roi=False, peak_roi=[0,0],
force_low_res_roi=False, low_res_roi=[0,0], force_low_res_roi=False, low_res_roi=[0,0],
force_bck_roi=False, bck_roi=[0,0], event_threshold=10000): force_bck_roi=False, bck_roi=[0,0], event_threshold=10000,
dirpix_overwrite=None, dangle0_overwrite=None):
self.cross_section = cross_section self.cross_section = cross_section
self.run_number = ws.getRunNumber() self.run_number = ws.getRunNumber()
self.is_direct_beam = False self.is_direct_beam = False
...@@ -156,6 +161,8 @@ class DataInfo(object): ...@@ -156,6 +161,8 @@ class DataInfo(object):
self.low_res_range = [0,0] self.low_res_range = [0,0]
self.background = [0,0] self.background = [0,0]
self.n_events_cutoff = event_threshold self.n_events_cutoff = event_threshold
self.dangle0_overwrite = dangle0_overwrite
self.dirpix_overwrite = dirpix_overwrite
# ROI information # ROI information
self.roi_peak = [0,0] self.roi_peak = [0,0]
...@@ -406,7 +413,11 @@ class DataInfo(object): ...@@ -406,7 +413,11 @@ class DataInfo(object):
self.background = [int(max(0, bck_range[0])), int(min(bck_range[1], NY_PIXELS))] self.background = [int(max(0, bck_range[0])), int(min(bck_range[1], NY_PIXELS))]
# Computed scattering angle # Computed scattering angle
self.calculated_scattering_angle = 180.0 / math.pi * mantid.simpleapi.MRGetTheta(ws, SpecularPixel=self.peak_position) self.calculated_scattering_angle = mantid.simpleapi.MRGetTheta(ws,
SpecularPixel=self.peak_position,
DirectPixelOverwrite=self.dirpix_overwrite,
DAngle0Overwrite=self.dangle0_overwrite)
self.calculated_scattering_angle *= 180.0 / math.pi
# Determine whether we have a direct beam # Determine whether we have a direct beam
self.is_direct_beam = self.check_direct_beam(ws, self.peak_position) self.is_direct_beam = self.check_direct_beam(ws, self.peak_position)
......
...@@ -92,7 +92,6 @@ class MagnetismReflectometryReduction(PythonAlgorithm): ...@@ -92,7 +92,6 @@ class MagnetismReflectometryReduction(PythonAlgorithm):
self.declareProperty("QMin", 0.005, doc="Minimum Q-value") self.declareProperty("QMin", 0.005, doc="Minimum Q-value")
self.declareProperty("QStep", 0.02, doc="Step size in Q. Enter a negative value to get a log scale") self.declareProperty("QStep", 0.02, doc="Step size in Q. Enter a negative value to get a log scale")
self.declareProperty("AngleOffset", 0.0, doc="angle offset (rad)") self.declareProperty("AngleOffset", 0.0, doc="angle offset (rad)")
self.declareProperty(WorkspaceProperty("OutputWorkspace", "", Direction.Output), "Output workspace")
self.declareProperty("TimeAxisStep", 40.0, self.declareProperty("TimeAxisStep", 40.0,
doc="Binning step size for the time axis. TOF for detector binning, wavelength for constant Q") doc="Binning step size for the time axis. TOF for detector binning, wavelength for constant Q")
self.declareProperty("CropFirstAndLastPoints", True, doc="If true, we crop the first and last points") self.declareProperty("CropFirstAndLastPoints", True, doc="If true, we crop the first and last points")
...@@ -100,6 +99,9 @@ class MagnetismReflectometryReduction(PythonAlgorithm): ...@@ -100,6 +99,9 @@ class MagnetismReflectometryReduction(PythonAlgorithm):
doc="With const-Q binning, cut Q bins with contributions fewer than ConstQTrim of WL bins") doc="With const-Q binning, cut Q bins with contributions fewer than ConstQTrim of WL bins")
self.declareProperty("SampleLength", 10.0, doc="Length of the sample in mm") self.declareProperty("SampleLength", 10.0, doc="Length of the sample in mm")
self.declareProperty("ConstantQBinning", False, doc="If true, we convert to Q before summing") self.declareProperty("ConstantQBinning", False, doc="If true, we convert to Q before summing")
self.declareProperty("DirectPixelOverwrite", Property.EMPTY_DBL, doc="DIRPIX overwrite value")
self.declareProperty("DAngle0Overwrite", Property.EMPTY_DBL, doc="DANGLE0 overwrite value (degrees)")
self.declareProperty(WorkspaceProperty("OutputWorkspace", "", Direction.Output), "Output workspace")
#pylint: disable=too-many-locals #pylint: disable=too-many-locals
def PyExec(self): def PyExec(self):
...@@ -554,9 +556,13 @@ class MagnetismReflectometryReduction(PythonAlgorithm): ...@@ -554,9 +556,13 @@ class MagnetismReflectometryReduction(PythonAlgorithm):
angle_offset = self.getProperty("AngleOffset").value angle_offset = self.getProperty("AngleOffset").value
use_sangle = self.getProperty("UseSANGLE").value use_sangle = self.getProperty("UseSANGLE").value
ref_pix = self.getProperty("SpecularPixel").value ref_pix = self.getProperty("SpecularPixel").value
dirpix_overwrite = self.getProperty("DirectPixelOverwrite").value
dangle0_overwrite = self.getProperty("DAngle0Overwrite").value
_theta = MRGetTheta(Workspace=ws_event_data, AngleOffset = angle_offset, _theta = MRGetTheta(Workspace=ws_event_data, AngleOffset=angle_offset,
UseSANGLE = use_sangle, SpecularPixel = ref_pix) UseSANGLE=use_sangle, SpecularPixel=ref_pix,
DirectPixelOverwrite=dirpix_overwrite,
DAngle0Overwrite=dangle0_overwrite)
return _theta return _theta
......
...@@ -230,6 +230,98 @@ class MRNormaWorkspaceTest(stresstesting.MantidStressTest): ...@@ -230,6 +230,98 @@ class MRNormaWorkspaceTest(stresstesting.MantidStressTest):
return "r_24949", 'MagnetismReflectometryReductionTest.nxs' return "r_24949", 'MagnetismReflectometryReductionTest.nxs'
class MRDIRPIXTest(stresstesting.MantidStressTest):
""" Test data loading and cross-section extraction """
def runTest(self):
wsg = MRFilterCrossSections(Filename="REF_M_24949")
ws_norm = LoadEventNexus(Filename="REF_M_24945",
NXentryName="entry-Off_Off",
OutputWorkspace="r_24945")
#sc_angle = MRGetTheta(Workspace=wsg[0])
# The logs have DANGLE0 = 4.50514 and DIRPIX = 204
# Scatt angle = 0
# 131.9: 0.00989410349765
MagnetismReflectometryReduction(InputWorkspace=wsg[0],
NormalizationWorkspace=ws_norm,
SignalPeakPixelRange=[125, 129],
SubtractSignalBackground=True,
SignalBackgroundPixelRange=[15, 105],
ApplyNormalization=True,
NormPeakPixelRange=[201, 205],
SubtractNormBackground=True,
NormBackgroundPixelRange=[10,127],
CutLowResDataAxis=True,
LowResDataAxisPixelRange=[91, 161],
CutLowResNormAxis=True,
LowResNormAxisPixelRange=[86, 174],
CutTimeAxis=True,
UseWLTimeAxis=False,
QMin=0.005,
QStep=-0.01,
TimeAxisStep=40,
TimeAxisRange=[25000, 54000],
SpecularPixel=136.9,
UseSANGLE=False,
DirectPixelOverwrite=214,
ConstantQBinning=False,
OutputWorkspace="r_24949")
def validate(self):
# Be more tolerant with the output, mainly because of the errors.
# The following tolerance check the errors up to the third digit.
self.disableChecking.append('Instrument')
self.disableChecking.append('Sample')
self.disableChecking.append('SpectraMap')
return "r_24949", 'MagnetismReflectometryReductionTest.nxs'
class MRDANGLE0Test(stresstesting.MantidStressTest):
""" Test data loading and cross-section extraction """
def runTest(self):
wsg = MRFilterCrossSections(Filename="REF_M_24949")
ws_norm = LoadEventNexus(Filename="REF_M_24945",
NXentryName="entry-Off_Off",
OutputWorkspace="r_24945")
theta = MRGetTheta(Workspace=wsg[0], UseSANGLE=False, SpecularPixel=127.9)
theta0 = MRGetTheta(Workspace=wsg[0], UseSANGLE=False, SpecularPixel=126.9)
dangle0 = wsg[0].getRun()['DANGLE0'].getStatistics().mean
dangle0 += (theta-theta0)*2.0*180./math.pi
MagnetismReflectometryReduction(InputWorkspace=wsg[0],
NormalizationWorkspace=ws_norm,
SignalPeakPixelRange=[125, 129],
SubtractSignalBackground=True,
SignalBackgroundPixelRange=[15, 105],
ApplyNormalization=True,
NormPeakPixelRange=[201, 205],
SubtractNormBackground=True,
NormBackgroundPixelRange=[10,127],
CutLowResDataAxis=True,
LowResDataAxisPixelRange=[91, 161],
CutLowResNormAxis=True,
LowResNormAxisPixelRange=[86, 174],
CutTimeAxis=True,
UseWLTimeAxis=False,
QMin=0.005,
QStep=-0.01,
TimeAxisStep=40,
TimeAxisRange=[25000, 54000],
SpecularPixel=127.9,
UseSANGLE=False,
DAngle0Overwrite=dangle0,
ConstantQBinning=False,
OutputWorkspace="r_24949")
def validate(self):
# Be more tolerant with the output, mainly because of the errors.
# The following tolerance check the errors up to the third digit.
self.disableChecking.append('Instrument')
self.disableChecking.append('Sample')
self.disableChecking.append('SpectraMap')
return "r_24949", 'MagnetismReflectometryReductionTest.nxs'
class MROutputTest(stresstesting.MantidStressTest): class MROutputTest(stresstesting.MantidStressTest):
""" Test the MR output algorithm """ """ Test the MR output algorithm """
def runTest(self): def runTest(self):
...@@ -281,6 +373,17 @@ class MRInspectionTest(stresstesting.MantidStressTest): ...@@ -281,6 +373,17 @@ class MRInspectionTest(stresstesting.MantidStressTest):
# Simple test to verify that we flagged the data correctly # Simple test to verify that we flagged the data correctly
return mtd["r_24949"].getRun().getProperty("is_direct_beam").value == "False" return mtd["r_24949"].getRun().getProperty("is_direct_beam").value == "False"
class MRInspectionOverwritesTest(stresstesting.MantidStressTest):
def runTest(self):
nxs_data = LoadEventNexus(Filename="REF_M_24949",
NXentryName="entry-Off_Off",
OutputWorkspace="r_24949")
MRInspectData(Workspace=nxs_data, DirectPixelOverwrite=208.0, DAngle0Overwrite=5.0)
def validate(self):
# Simple test to verify that we flagged the data correctly
return mtd["r_24949"].getRun().getProperty("is_direct_beam").value == "False"
class MRGetThetaTest(stresstesting.MantidStressTest): class MRGetThetaTest(stresstesting.MantidStressTest):
""" Test that the MRGetTheta algorithm produces correct results """ """ Test that the MRGetTheta algorithm produces correct results """
...@@ -294,5 +397,16 @@ class MRGetThetaTest(stresstesting.MantidStressTest): ...@@ -294,5 +397,16 @@ class MRGetThetaTest(stresstesting.MantidStressTest):
# In the present case, DANGLE = DANGLE0, so we expect 0 if nothing else is passed # In the present case, DANGLE = DANGLE0, so we expect 0 if nothing else is passed
self.assertAlmostEqual(MRGetTheta(Workspace=nxs_data), 0.0) self.assertAlmostEqual(MRGetTheta(Workspace=nxs_data), 0.0)
# The logs have DANGLE0 = 4.50514 and DIRPIX = 204
# Setting DIRPIX without setting a specular pixel shouldn't change anything
self.assertAlmostEqual(MRGetTheta(Workspace=nxs_data, DirectPixelOverwrite=145), 0.0)
# Setting DIRPIX and the specular pixel with move things
# Move everything by 4 pixels and we should get the same answer (which depends only on the difference of the two)
self.assertAlmostEqual(MRGetTheta(Workspace=nxs_data, DirectPixelOverwrite=208, SpecularPixel=130.1), 0.61249193272/180.0*math.pi)
dangle0 = nxs_data.getRun()['DANGLE0'].value[0]
self.assertAlmostEqual(MRGetTheta(Workspace=nxs_data, DAngle0Overwrite=dangle0+180.0), math.pi/2.0)
def validate(self): def validate(self):
return True return True
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