forked from AmbaPant/mantid
-
Notifications
You must be signed in to change notification settings - Fork 1
/
ConvertQtoHKLMDHisto.py
146 lines (113 loc) · 7.45 KB
/
ConvertQtoHKLMDHisto.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
# Mantid Repository : https://github.com/mantidproject/mantid
#
# Copyright © 2020 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 AlgorithmFactory, IMDEventWorkspaceProperty, IMDHistoWorkspaceProperty, IPeaksWorkspaceProperty,\
PythonAlgorithm, PropertyMode
from mantid.kernel import Direction, FloatArrayLengthValidator, FloatArrayProperty, IntArrayProperty
from mantid.simpleapi import BinMD, CloneMDWorkspace, DeleteWorkspace, SetMDFrame, mtd
import numpy as np
class ConvertQtoHKLMDHisto(PythonAlgorithm):
_lattice = None
def category(self):
return "MDAlgorithms\\Creation"
def seeAlso(self):
return ["ConvertWANDSCDtoQ", "BinMD", "MDNorm"]
def name(self):
return "ConvertQtoHKLMDHisto"
def summary(self):
return 'Converts a workspace from Q sample to a MDHisto in HKL; the UB matrix can be used from the input, ' \
'or calculated from peaks found from the input.'
def PyInit(self):
self.declareProperty(IMDEventWorkspaceProperty("InputWorkspace", defaultValue="",
optional=PropertyMode.Mandatory,
direction=Direction.Input),
doc="Input MDEvent workspace to convert to a MDHisto in HKL")
self.declareProperty(IPeaksWorkspaceProperty("PeaksWorkspace", defaultValue="", optional=PropertyMode.Optional,
direction=Direction.Input),
doc="Optional peaks workspace to retrieve the UB matrix from, instead of InputWorkspace.")
self.declareProperty(FloatArrayProperty("Uproj", [1, 0, 0], validator=FloatArrayLengthValidator(3),
direction=Direction.Input),
doc="Defines the first projection vector of the target Q coordinate system in HKL mode")
self.declareProperty(FloatArrayProperty("Vproj", [0, 1, 0], validator=FloatArrayLengthValidator(3),
direction=Direction.Input),
doc="Defines the second projection vector of the target Q coordinate system in HKL mode")
self.declareProperty(FloatArrayProperty("Wproj", [0, 0, 1], validator=FloatArrayLengthValidator(3),
direction=Direction.Input),
doc="Defines the third projection vector of the target Q coordinate system in HKL mode")
self.declareProperty(FloatArrayProperty("Extents", [-6.02, 6.02, -6.02, 6.02, -6.02, 6.02],
direction=Direction.Input),
"Binning parameters for each dimension. Enter it as a"
"comma-separated list of values with the"
"format: 'minimum,maximum,'.")
self.declareProperty(IntArrayProperty("Bins", [301, 301, 301],
direction=Direction.Input),
"Number of bins to use for each dimension, Enter it as a"
"comma-separated list of integers.")
self.declareProperty(IMDHistoWorkspaceProperty("OutputWorkspace", "",
optional=PropertyMode.Mandatory,
direction=Direction.Output),
doc="Output MDWorkspace in Q-space, name is prefix if multiple input files were provided.")
def validateInputs(self):
issues = dict()
input_ws = self.getProperty("InputWorkspace").value
if input_ws.getSpecialCoordinateSystem().name != "QSample":
issues["InputWorkspace"] = "Input workspace expected to be in QSample, " \
"workspace is in '{}'".format(input_ws.getSpecialCoordinateSystem().name)
ndims = input_ws.getNumDims()
if ndims != 3:
issues["InputWorkspace"] = "Input workspace needs 3 dimensions, it has {} dimensions.".format(ndims)
# Check that extents and bins were provided for every dimension
extents = self.getProperty("Extents").value
bins = self.getProperty("Bins").value
if len(extents) != ndims * 2:
issues["Extents"] = "Expected a min and max value for each " \
"dimension (got {}, expected {}).".format(len(extents), ndims*2)
if len(bins) != ndims:
issues["Bins"] = "Expected a number of bins for each dimension."
# Check if a PeaksWorkspace was provided
peak_ws = self.getProperty("PeaksWorkspace")
if not peak_ws.isDefault:
if not mtd.doesExist(self.getPropertyValue("PeaksWorkspace")):
issues["PeaksWorkspace"] = "Provided peaks workspace does not exist in the ADS."
else:
# Check that the workspace has a UB matrix
if not (input_ws.getNumExperimentInfo() > 0 and input_ws.getExperimentInfo(0).sample().hasOrientedLattice()):
issues["InputWorkspace"] = "Could not find a UB matrix in this workspace."
return issues
def PyExec(self):
input_ws = self.getProperty("InputWorkspace").value
extents = self.getProperty("Extents").value
bins = self.getProperty("Bins").value
# Get the UB from either the PeaksWS if provided, or from the input workspace
if not self.getProperty("PeaksWorkspace").isDefault:
peak_ws = self.getProperty("PeaksWorkspace").value
self._lattice = peak_ws.sample().getOrientedLattice()
else:
self._lattice = input_ws.getExperimentInfo(0).sample().getOrientedLattice()
# Get axis names and units from u,v,w projections, as done in ConvertWANDSCDtoQ:
w = np.eye(3)
w[:, 0] = self.getProperty("Uproj").value
w[:, 1] = self.getProperty("Vproj").value
w[:, 2] = self.getProperty("Wproj").value
char_dict = {0: '0', 1: '{1}', -1: '-{1}'}
chars = ['H', 'K', 'L']
names = ['[' + ','.join(char_dict.get(j, '{0}{1}')
.format(j, chars[np.argmax(np.abs(w[:, i]))]) for j in w[:, i]) + ']' for i in range(3)]
q = [self._lattice.qFromHKL(w[:,i]) for i in range(3)]
units = ['in {:.3f} A^-1'.format(q[i].norm()) for i in range(3)]
output_name = self.getPropertyValue("OutputWorkspace")
CloneMDWorkspace(InputWorkspace=input_ws, OutputWorkspace=output_name)
SetMDFrame(InputWorkspace=output_name, MDFrame='HKL', Axes='0,1,2')
mdhist = BinMD(InputWorkspace=output_name, AxisAligned=False, NormalizeBasisVectors=False,
BasisVector0='{},{},{},{},{}'.format(names[0], units[0], q[0].X(), q[0].Y(), q[0].Z()),
BasisVector1='{},{},{},{},{}'.format(names[1], units[1], q[1].X(), q[1].Y(), q[1].Z()),
BasisVector2='{},{},{},{},{}'.format(names[2], units[2], q[2].X(), q[2].Y(), q[2].Z()),
OutputExtents=extents,
OutputBins=bins)
self.setProperty("OutputWorkspace", mdhist)
mdhist.clearOriginalWorkspaces()
DeleteWorkspace(mdhist)
AlgorithmFactory.subscribe(ConvertQtoHKLMDHisto)