forked from AmbaPant/mantid
-
Notifications
You must be signed in to change notification settings - Fork 1
/
UpdatePeakParameterTableValue.py
226 lines (179 loc) · 7.95 KB
/
UpdatePeakParameterTableValue.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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# 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,redefined-builtin
import mantid
import mantid.api
import mantid.kernel
import mantid.simpleapi
class UpdatePeakParameterTableValue(mantid.api.PythonAlgorithm):
""" Class to generate grouping file
"""
tableColNames = None
parameternames = None
def category(self):
""" Mantid required
"""
return "Inelastic\\Utility;Transforms\\Grouping"
def name(self):
""" Mantid require
"""
return "UpdatePeakParameterTableValue"
def summary(self):
return "Update cell value(s) in a TableWorkspace containing instrument peak profile parameters."
def PyInit(self):
""" Property definition
"""
tableprop = mantid.api.ITableWorkspaceProperty("InputWorkspace", "", mantid.kernel.Direction.InOut)
self.declareProperty(tableprop, "TableWorkspace containing peak profile parameters")
colchoices = ["Value", "FitOrTie", "Min", "Max", "StepSize"]
self.declareProperty("Column", "Value", mantid.kernel.StringListValidator(colchoices),
"Column name of the cell to have value updated. Choices include 'FitOrTie', "
+ "'Max', 'Min', 'StepSize' and 'Value'")
rowprop = mantid.kernel.IntArrayProperty("Rows", [])
self.declareProperty(rowprop, "List of row numbers of the cell to have value updated")
parnameprop = mantid.kernel.StringArrayProperty("ParameterNames", [])
self.declareProperty(parnameprop, "List of names of parameters that will have their values updated")
self.declareProperty("NewFloatValue", 0.0, "New value for the specified cell of type 'float'.")
self.declareProperty("NewStringValue", "", "New value for the specified cell of type 'string'.")
return
def PyExec(self):
""" Main Execution Body
"""
# 1. Process input parameter TableWorkspace
tableWS = self.getProperty("InputWorkspace").value
result = self.parseTableWorkspace(tableWS)
paramnamedict = result[0]
colnamedict = result[1]
# 2. Process input row (to change) information
rownumberlist = list(self.getProperty("Rows").value)
parameterlist = self.getProperty("ParameterNames").value
for parametername in parameterlist:
rows = self.convertParameterNameToTableRows(parametername, paramnamedict)
rownumberlist.extend(rows)
# ENDFOR
if len(rownumberlist) > 1:
rownumberlist = sorted(rownumberlist)
elif len(rownumberlist) == 0:
# if no input row number/parameter name, set the value to all rows
numrows = tableWS.rowCount()
rownumberlist = list(range(0, numrows))
# ENDIF
# for irow in rownumberlist:
# print "Update value on row %d" % (irow)
# 3. Process column (to change) information
colname = self.getProperty("Column").value
if colname in colnamedict:
icolumn = colnamedict[colname]
else:
raise NotImplementedError("Column name %s does not exist in TableWorkspace %s"
% (colname, tableWS.name()))
# 3. Set value
if colname in ["FitOrTie", "Name"]:
# string value
value = self.getProperty("NewStringValue").value.lower()
else:
# float value
value = self.getProperty("NewFloatValue").value
# print "Input Value = %s. Type = %s" % (str(value), type(value))
for irow in rownumberlist:
irow = int(irow)
if irow >= 0:
tableWS.setCell(irow, icolumn, value)
# 4.
self.setProperty("InputWorkspace", tableWS)
return
def convertParameterNameToTableRows(self, parametername, paramnamedict):
""" Convert parameter name (incomplete might be) to row number(s)
An algorithm to recognize parameter with blurred definition will be use such as
(1) exactly same and case insensitive;
(2) *partialname
(3) partialname*
(4) *partialname*
(5) partialname?
Argument:
- parametername: parameter name to change value
- paramnamedict: dictionary key = parameter name, value = row number in table workspace
Return: List of row numbers (integer), a negative value might exit to represent a non-existing parameter name
"""
rownumbers= []
# 1. make case insensitive
parnametofit = parametername.lower()
for parname in self.parameternames:
parname_low = parname.lower()
ismatch = False
if parname_low == parnametofit:
# exactly match
ismatch = True
elif parnametofit.startswith("*") and parnametofit.endswith("*"):
# *XXXX*
corestr = parnametofit.split("*")[1]
if parname_low.count(corestr) >= 1:
ismatch = True
elif parnametofit.startswith("*"):
# *NNNNN
corestr = parnametofit.split("*")[1]
if parname_low.endswith(parnametofit):
ismatch = True
self.parametersToFit.append(corestr)
elif parnametofit.endswith("*"):
# NNNNN*
corestr = parnametofit.split("*")[0]
if parname_low.startswith(corestr):
ismatch = True
elif parnametofit.endswith("?"):
# NNNNN?
corestr = parnametofit.split("?")[0]
if parname_low.startswith(corestr) and len(parname_low) == len(parnametofit):
ismatch = True
# ENDIFELSE
if ismatch is True:
rownumber = paramnamedict[parname]
rownumbers.append(rownumber)
# ENDFOR:
# 2. Take in the case that there is no match
if len(rownumbers) == 0:
# No Match
mantid.logger.warning("Warning! There is no match for parameter %s" % (parnametofit))
rownumbers.append(-1000)
# ENDIFELSE
return rownumbers
def parseTableWorkspace(self, tablews):
""" Get information from table workspace
Return: dictionary, key = row number, value = name
"""
parameterdict = {}
# 1. Column name information
colnames = tablews.getColumnNames()
self.tableColNames = colnames
colnamedict = {}
for ic in range( len(colnames) ):
colnamedict[colnames[ic]] = ic
# 2. Check validity of workspace
if len(colnames) < 2:
raise NotImplementedError("Input table workspace is not supported due to column size.")
if colnames[0] != "Name" or colnames[1] != "Value":
raise NotImplementedError("Input table workspace is not supported due to column name.")
# 3. Parse!
parnamedict = {}
self.parameternames = []
numrows = tablews.rowCount()
for irow in range(numrows):
parname = tablews.cell(irow, 0)
parname = parname.lower().strip()
parnamedict[parname] = irow
self.parameternames.append(parname)
# NEW! Collect each variable in
valuelist = []
for icol in range(len(colnames)):
value = tablews.cell(irow, icol)
valuelist.append(value)
parameterdict[parname] = valuelist
# ENDFOR
# ENDFOR
return (parnamedict, colnamedict, parameterdict)
# ENDCLASS
mantid.api.AlgorithmFactory.subscribe(UpdatePeakParameterTableValue)