forked from AmbaPant/mantid
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSANSSubtract.py
185 lines (157 loc) · 6.89 KB
/
SANSSubtract.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# 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 *
from mantid.kernel import Direction, FloatBoundedValidator
import mantid.simpleapi
import os
class SANSSubtract(PythonAlgorithm):
"""
I(Q) subtraction
"""
def category(self):
"""
Return category
"""
return "SANS"
def seeAlso(self):
return [ "SANSStitch","SANSFitShiftScale" ]
def name(self):
"""
Return name
"""
return "SANSSubtract"
def summary(self):
return "Subtract background from an I(Q) distribution."
def PyInit(self):
"""
Declare properties
"""
self.declareProperty('DataDistribution', '', direction = Direction.Input,
doc='Name of the input workspace or file path')
self.declareProperty('Background', '', direction = Direction.Input,
doc='Name of the background workspace or file path')
self.declareProperty("ScaleFactor", 1., FloatBoundedValidator(),
doc="Scaling factor [Default: 1]")
self.declareProperty("Constant", 0., FloatBoundedValidator(),
doc="Additive constant [Default:0]")
self.declareProperty(FileProperty("OutputDirectory","", FileAction.OptionalDirectory),
doc="Directory to write the output files in [optional]")
self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", "", Direction.Output),
doc="Workspace containing data from detectors")
return
def _find_or_load(self, data_str):
"""
Determine whether the input data string is the name
of an existing workspace or is a file to be loaded.
Return the workspace and its name.
@param data_str: input string for the data
"""
if AnalysisDataService.doesExist(data_str):
data = AnalysisDataService.retrieve(data_str)
data_ws_name = data_str
else:
data_ws_name = os.path.basename(data_str)
load_alg = mantid.api.AlgorithmManager.createUnmanaged('Load')
load_alg.setChild(True)
load_alg.initialize()
load_alg.setProperty("Filename", data_str)
load_alg.setProperty("OutputWorkspace", data_ws_name)
load_alg.execute()
data = load_alg.getProperty("OutputWorkspace").value
# Keep track of dQ
dq = data.extractDx()[0]
# Make sure we have histogram data for rebinning purposes
op = mantid.api.AlgorithmManager.createUnmanaged("ConvertToHistogram")
op.initialize()
op.setChild(True)
op.setProperty("InputWorkspace", data)
op.setProperty("OutputWorkspace", "__histo_data_%s" % data_ws_name)
op.execute()
data = op.getProperty("OutputWorkspace").value
# Make sure we have the correct units, especially important
# if the data was loaded from an ASCII file
data.getAxis(0).setUnit('MomentumTransfer')
# Set the "distribution" flag on the matrix workspace
data.setDistribution(False)
return data, data_ws_name, dq
def PyExec(self):
"""
Main execution body
"""
data_str = self.getProperty("DataDistribution").value
background_str = self.getProperty("Background").value
scale = self.getProperty("ScaleFactor").value
constant = self.getProperty("Constant").value
output_dir = self.getPropertyValue("OutputDirectory")
# Load data or get it from the ADS
data, data_ws_name, dq = self._find_or_load(data_str)
# Load background or get it from the ADS
background, _, _ = self._find_or_load(background_str)
# Rebin background to data workspace
op = mantid.api.AlgorithmManager.createUnmanaged("RebinToWorkspace")
op.initialize()
op.setChild(True)
op.setProperty("WorkspaceToRebin", background)
op.setProperty("WorkspaceToMatch", data)
op.setProperty("OutputWorkspace", "__rebinned_bck")
op.execute()
rebinned_bck = op.getProperty("OutputWorkspace").value
# Output = data - scale * background + constant
op = mantid.api.AlgorithmManager.createUnmanaged('Scale')
op.initialize()
op.setChild(True)
op.setProperty("InputWorkspace", rebinned_bck)
op.setProperty("OutputWorkspace", '__scaled_bck')
op.setProperty("Factor", scale)
op.setProperty("Operation", "Multiply")
op.execute()
scaled_bck = op.getProperty("OutputWorkspace").value
op = mantid.api.AlgorithmManager.createUnmanaged('Minus')
op.initialize()
op.setChild(True)
op.setProperty("LHSWorkspace", data)
op.setProperty("RHSWorkspace", scaled_bck)
op.setProperty("OutputWorkspace", '__bck_substracted')
op.execute()
bck_subtr = op.getProperty("OutputWorkspace").value
op = mantid.api.AlgorithmManager.createUnmanaged('Scale')
op.initialize()
op.setChild(True)
op.setProperty("InputWorkspace", bck_subtr)
op.setProperty("OutputWorkspace", '__corrected_output')
op.setProperty("Factor", constant)
op.setProperty("Operation", "Add")
op.execute()
output = op.getProperty("OutputWorkspace").value
# Put back dQ
dq_scaled = output.dataDx(0)
for i in range(len(dq)):
dq_scaled[i] = dq[i]
self.setProperty("OutputWorkspace", output)
# Save the output to disk as needed
if len(output_dir)>0:
root_name, _ = os.path.splitext(data_ws_name)
op = mantid.api.AlgorithmManager.createUnmanaged('SaveCanSAS1D')
op.initialize()
op.setChild(True)
op.setProperty("InputWorkspace", output)
op.setProperty("Filename", os.path.join(output_dir, root_name+'_corr.xml'))
op.setProperty("RadiationSource", "Spallation Neutron Source")
op.execute()
op = mantid.api.AlgorithmManager.createUnmanaged("SaveAscii")
op.initialize()
op.setChild(True)
op.setProperty("Filename", os.path.join(output_dir, root_name+'_corr.txt'))
op.setProperty("InputWorkspace", output)
op.setProperty("Separator", "Tab")
op.setProperty("CommentIndicator", "# ")
op.setProperty("WriteXError", True)
op.setProperty("WriteSpectrumID", False)
op.execute()
return
AlgorithmFactory.subscribe(SANSSubtract)