forked from AmbaPant/mantid
-
Notifications
You must be signed in to change notification settings - Fork 1
/
PDConvertReciprocalSpace.py
126 lines (108 loc) · 5.19 KB
/
PDConvertReciprocalSpace.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# 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 & CSNS, Institute of High Energy Physics, CAS
# SPDX - License - Identifier: GPL - 3.0 +
# pylint: disable=no-init,invalid-name
from mantid.api import (PythonAlgorithm, AlgorithmFactory,
WorkspaceUnitValidator, MatrixWorkspaceProperty,
WorkspaceProperty, WorkspaceFactory)
from mantid.kernel import (Direction, StringListValidator, logger)
from pystog.converter import Converter
SQ = 'S(Q)'
FQ = 'F(Q)'
FKQ = 'FK(Q)'
DCS = 'DCS(Q)'
class PDConvertReciprocalSpace(PythonAlgorithm):
"""
Convert between different reciprocal space functions
"""
def category(self):
"""
Return category
"""
return "Diffraction\\Utility"
def name(self):
"""
Return name
"""
return "PDConvertReciprocalSpace"
def seeAlso(self):
return ["PDConvertRealSpace"]
def summary(self):
return "Transforms a Workspace2D between different " + \
"reciprocal space functions."
def PyInit(self):
"""
Declare properties
"""
allowed_units = WorkspaceUnitValidator("MomentumTransfer")
self.declareProperty(MatrixWorkspaceProperty("InputWorkspace", "",
direction=Direction.Input,
validator=allowed_units),
doc="Input workspace with units of momentum transfer")
functions = [SQ, FQ, FKQ, DCS]
self.declareProperty("From", SQ, StringListValidator(functions), "Function type in the input workspace")
self.declareProperty("To", SQ, StringListValidator(functions), "Function type in the output workspace")
self.declareProperty(WorkspaceProperty('OutputWorkspace', '',
direction=Direction.Output),
doc='Output workspace')
def validateInputs(self):
result = dict()
input_ws = self.getProperty('InputWorkspace').value
from_quantity = self.getProperty('From').value
to_quantity = self.getProperty('To').value
if from_quantity != to_quantity: # noop doesn't require material
requireMaterial = True
if from_quantity == SQ and to_quantity == FQ:
requireMaterial = False
elif from_quantity == FQ and to_quantity == SQ:
requireMaterial = False
if requireMaterial:
if not input_ws.sample().getMaterial():
result['InputWorkspace'] = 'Please run SetSample or SetSampleMaterial'
else:
cohScattSqrd = input_ws.sample().getMaterial().cohScatterLengthSqrd()
if cohScattSqrd == 0.:
if from_quantity in [SQ, FQ] and to_quantity in [DCS, FKQ]:
result['To'] = 'Require non-zero coherent scattering length'
if to_quantity in [SQ, FQ] and from_quantity in [DCS, FKQ]:
result['From'] = 'Require non-zero coherent scattering length'
return result
def PyExec(self):
input_ws = self.getProperty("InputWorkspace").value
output_ws_name = self.getProperty('OutputWorkspace').valueAsStr
from_quantity = self.getProperty("From").value
to_quantity = self.getProperty("To").value
if input_ws.name() == output_ws_name:
output_ws = input_ws
else:
output_ws = WorkspaceFactory.create(input_ws)
self.setProperty('OutputWorkspace', output_ws)
if from_quantity == to_quantity:
logger.warning('The input and output functions are the same. Nothing to be done')
return
c = Converter()
transformation = {SQ: {FQ: c.S_to_F, FKQ: c.S_to_FK, DCS: c.S_to_DCS},
FQ: {SQ: c.F_to_S, FKQ: c.F_to_FK, DCS: c.F_to_DCS},
FKQ: {SQ: c.FK_to_S, FQ: c.FK_to_F, DCS: c.FK_to_DCS},
DCS: {SQ: c.DCS_to_S, FQ: c.DCS_to_F, FKQ: c.DCS_to_FK}}
if input_ws.sample().getMaterial():
sample_kwargs = {"<b_coh>^2": input_ws.sample().getMaterial().cohScatterLengthSqrd(),
"<b_tot^2>": input_ws.sample().getMaterial().totalScatterLengthSqrd(),
"rho": input_ws.sample().getMaterial().numberDensity}
else:
sample_kwargs = dict()
for sp_num in range(input_ws.getNumberHistograms()):
x = input_ws.readX(sp_num)
output_ws.setX(sp_num, x)
y = input_ws.readY(sp_num)
e = input_ws.readE(sp_num)
if len(x) == len(y) + 1:
x = 0.5 * (x[:-1] + x[1:])
new_y, new_e = transformation[from_quantity][to_quantity](x, y, e, **sample_kwargs)
output_ws.setY(sp_num, new_y)
output_ws.setE(sp_num, new_e)
# Register algorithm with Mantid.
AlgorithmFactory.subscribe(PDConvertReciprocalSpace)