-
Notifications
You must be signed in to change notification settings - Fork 122
/
WANDPowderReduction.py
159 lines (127 loc) · 8.51 KB
/
WANDPowderReduction.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
# 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 +
from mantid.api import (DataProcessorAlgorithm, AlgorithmFactory,
MatrixWorkspaceProperty, PropertyMode,
IEventWorkspace)
from mantid.dataobjects import MaskWorkspaceProperty
from mantid.simpleapi import (ConvertSpectrumAxis, Transpose,
ResampleX, CopyInstrumentParameters,
Divide, DeleteWorkspace, Scale,
MaskAngle, ExtractMask, Minus,
ExtractUnmaskedSpectra, mtd,
BinaryOperateMasks, Integration)
from mantid.kernel import StringListValidator, Direction, Property, FloatBoundedValidator
class WANDPowderReduction(DataProcessorAlgorithm):
temp_workspace_list = ['__data_tmp', '__cal_tmp', '__mask_tmp', '__bkg_tmp']
def category(self):
return "Diffraction\\Reduction"
def seeAlso(self):
return ['LoadWAND','SaveFocusedXYE']
def summary(self):
return 'Performs powder diffraction data reduction for WAND'
def name(self):
return "WANDPowderReduction"
def validateInputs(self):
issues = dict()
return issues
def PyInit(self):
self.declareProperty(MatrixWorkspaceProperty("InputWorkspace", '',
direction=Direction.Input),
doc='The main input workspace.')
self.declareProperty(MatrixWorkspaceProperty("CalibrationWorkspace", '',
optional=PropertyMode.Optional,
direction=Direction.Input),
doc='The calibration (vandiaum) workspace.')
self.declareProperty(MatrixWorkspaceProperty("BackgroundWorkspace", '',
optional=PropertyMode.Optional,
direction=Direction.Input),
doc='The background workspace to be subtracted.')
self.declareProperty("BackgroundScale", 1.0,
validator=FloatBoundedValidator(0.0),
doc="The background will be scaled by this number before being subtracted.")
self.declareProperty(MaskWorkspaceProperty("MaskWorkspace", '',
optional=PropertyMode.Optional,
direction=Direction.Input),
doc='The mask from this workspace will be applied before reduction')
self.copyProperties('ConvertSpectrumAxis', ['Target', 'EFixed'])
self.copyProperties('ResampleX', ['XMin', 'XMax', 'NumberBins', 'LogBinning'])
self.declareProperty('NormaliseBy', 'Monitor', StringListValidator(['None', 'Time', 'Monitor']), "Normalise to monitor or time. ")
self.declareProperty('MaskAngle', Property.EMPTY_DBL,
"Phi angle above which will be masked. See :ref:`MaskAngle <algm-MaskAngle>` for details.")
self.declareProperty(MatrixWorkspaceProperty("OutputWorkspace", "",
direction=Direction.Output),
doc="Output Workspace")
def PyExec(self):
data = self.getProperty("InputWorkspace").value
cal = self.getProperty("CalibrationWorkspace").value
bkg = self.getProperty("BackgroundWorkspace").value
mask = self.getProperty("MaskWorkspace").value
target = self.getProperty("Target").value
eFixed = self.getProperty("EFixed").value
xMin = self.getProperty("XMin").value
xMax = self.getProperty("XMax").value
numberBins = self.getProperty("NumberBins").value
normaliseBy = self.getProperty("NormaliseBy").value
maskAngle = self.getProperty("MaskAngle").value
outWS = self.getPropertyValue("OutputWorkspace")
data_scale = 1
cal_scale = 1
bkg_scale = 1
if normaliseBy == "Monitor":
data_scale = data.run().getProtonCharge()
elif normaliseBy == "Time":
data_scale = data.run().getLogData('duration').value
ExtractMask(data, OutputWorkspace='__mask_tmp', EnableLogging=False)
if maskAngle != Property.EMPTY_DBL:
MaskAngle(Workspace='__mask_tmp', MinAngle=maskAngle, Angle='Phi', EnableLogging=False)
if mask is not None:
BinaryOperateMasks(InputWorkspace1='__mask_tmp', InputWorkspace2=mask,
OperationType='OR', OutputWorkspace='__mask_tmp', EnableLogging=False)
ExtractUnmaskedSpectra(InputWorkspace=data, MaskWorkspace='__mask_tmp', OutputWorkspace='__data_tmp', EnableLogging=False)
if isinstance(mtd['__data_tmp'], IEventWorkspace):
Integration(InputWorkspace='__data_tmp', OutputWorkspace='__data_tmp', EnableLogging=False)
ConvertSpectrumAxis(InputWorkspace='__data_tmp', Target=target, EFixed=eFixed, OutputWorkspace=outWS, EnableLogging=False)
Transpose(InputWorkspace=outWS, OutputWorkspace=outWS, EnableLogging=False)
ResampleX(InputWorkspace=outWS, OutputWorkspace=outWS, XMin=xMin, XMax=xMax, NumberBins=numberBins, EnableLogging=False)
if cal is not None:
ExtractUnmaskedSpectra(InputWorkspace=cal, MaskWorkspace='__mask_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False)
if isinstance(mtd['__cal_tmp'], IEventWorkspace):
Integration(InputWorkspace='__cal_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False)
CopyInstrumentParameters(data, '__cal_tmp', EnableLogging=False)
ConvertSpectrumAxis(InputWorkspace='__cal_tmp', Target=target, EFixed=eFixed, OutputWorkspace='__cal_tmp', EnableLogging=False)
Transpose(InputWorkspace='__cal_tmp', OutputWorkspace='__cal_tmp', EnableLogging=False)
ResampleX(InputWorkspace='__cal_tmp', OutputWorkspace='__cal_tmp', XMin=xMin, XMax=xMax, NumberBins=numberBins,
EnableLogging=False)
Divide(LHSWorkspace=outWS, RHSWorkspace='__cal_tmp', OutputWorkspace=outWS, EnableLogging=False)
if normaliseBy == "Monitor":
cal_scale = cal.run().getProtonCharge()
elif normaliseBy == "Time":
cal_scale = cal.run().getLogData('duration').value
Scale(InputWorkspace=outWS, OutputWorkspace=outWS, Factor=cal_scale/data_scale, EnableLogging=False)
if bkg is not None:
ExtractUnmaskedSpectra(InputWorkspace=bkg, MaskWorkspace='__mask_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False)
if isinstance(mtd['__bkg_tmp'], IEventWorkspace):
Integration(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False)
CopyInstrumentParameters(data, '__bkg_tmp', EnableLogging=False)
ConvertSpectrumAxis(InputWorkspace='__bkg_tmp', Target=target, EFixed=eFixed, OutputWorkspace='__bkg_tmp', EnableLogging=False)
Transpose(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False)
ResampleX(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', XMin=xMin, XMax=xMax, NumberBins=numberBins,
EnableLogging=False)
if cal is not None:
Divide(LHSWorkspace='__bkg_tmp', RHSWorkspace='__cal_tmp', OutputWorkspace='__bkg_tmp', EnableLogging=False)
if normaliseBy == "Monitor":
bkg_scale = bkg.run().getProtonCharge()
elif normaliseBy == "Time":
bkg_scale = bkg.run().getLogData('duration').value
Scale(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp', Factor=cal_scale/bkg_scale, EnableLogging=False)
Scale(InputWorkspace='__bkg_tmp', OutputWorkspace='__bkg_tmp',
Factor=self.getProperty('BackgroundScale').value, EnableLogging=False)
Minus(LHSWorkspace=outWS, RHSWorkspace='__bkg_tmp', OutputWorkspace=outWS, EnableLogging=False)
self.setProperty("OutputWorkspace", outWS)
# remove temp workspaces
[DeleteWorkspace(ws, EnableLogging=False) for ws in self.temp_workspace_list if mtd.doesExist(ws)]
AlgorithmFactory.subscribe(WANDPowderReduction)