scipion-pyworkflow 3.10.5__py3-none-any.whl → 3.11.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyworkflow/config.py +131 -67
- pyworkflow/constants.py +12 -2
- pyworkflow/object.py +3 -2
- pyworkflow/plugin.py +93 -44
- pyworkflow/project/scripts/fix_links.py +4 -1
- pyworkflow/resources/showj/arrowDown.png +0 -0
- pyworkflow/resources/showj/arrowUp.png +0 -0
- pyworkflow/resources/showj/background_section.png +0 -0
- pyworkflow/resources/showj/colRowModeOff.png +0 -0
- pyworkflow/resources/showj/colRowModeOn.png +0 -0
- pyworkflow/resources/showj/delete.png +0 -0
- pyworkflow/resources/showj/doc_icon.png +0 -0
- pyworkflow/resources/showj/download_icon.png +0 -0
- pyworkflow/resources/showj/enabled_gallery.png +0 -0
- pyworkflow/resources/showj/galleryViewOff.png +0 -0
- pyworkflow/resources/showj/galleryViewOn.png +0 -0
- pyworkflow/resources/showj/goto.png +0 -0
- pyworkflow/resources/showj/menu.png +0 -0
- pyworkflow/resources/showj/separator.png +0 -0
- pyworkflow/resources/showj/tableViewOff.png +0 -0
- pyworkflow/resources/showj/tableViewOn.png +0 -0
- pyworkflow/resources/showj/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- pyworkflow/resources/showj/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- pyworkflow/resources/showj/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- pyworkflow/resources/showj/volumeOff.png +0 -0
- pyworkflow/resources/showj/volumeOn.png +0 -0
- pyworkflow/viewer.py +23 -1
- pyworkflowtests/objects.py +2 -2
- pyworkflowtests/protocols.py +1 -3
- {scipion_pyworkflow-3.10.5.dist-info → scipion_pyworkflow-3.11.0.dist-info}/METADATA +21 -25
- scipion_pyworkflow-3.11.0.dist-info/RECORD +71 -0
- {scipion_pyworkflow-3.10.5.dist-info → scipion_pyworkflow-3.11.0.dist-info}/WHEEL +1 -1
- scipion_pyworkflow-3.11.0.dist-info/entry_points.txt +2 -0
- pyworkflow/apps/__init__.py +0 -29
- pyworkflow/apps/pw_manager.py +0 -37
- pyworkflow/apps/pw_plot.py +0 -51
- pyworkflow/apps/pw_project.py +0 -113
- pyworkflow/apps/pw_protocol_list.py +0 -143
- pyworkflow/apps/pw_protocol_run.py +0 -51
- pyworkflow/apps/pw_run_tests.py +0 -267
- pyworkflow/apps/pw_schedule_run.py +0 -322
- pyworkflow/apps/pw_sleep.py +0 -37
- pyworkflow/apps/pw_sync_data.py +0 -439
- pyworkflow/apps/pw_viewer.py +0 -78
- pyworkflow/gui/__init__.py +0 -36
- pyworkflow/gui/browser.py +0 -726
- pyworkflow/gui/canvas.py +0 -1190
- pyworkflow/gui/dialog.py +0 -977
- pyworkflow/gui/form.py +0 -2637
- pyworkflow/gui/graph.py +0 -247
- pyworkflow/gui/graph_layout.py +0 -271
- pyworkflow/gui/gui.py +0 -566
- pyworkflow/gui/matplotlib_image.py +0 -233
- pyworkflow/gui/plotter.py +0 -247
- pyworkflow/gui/project/__init__.py +0 -25
- pyworkflow/gui/project/base.py +0 -192
- pyworkflow/gui/project/constants.py +0 -139
- pyworkflow/gui/project/labels.py +0 -205
- pyworkflow/gui/project/project.py +0 -492
- pyworkflow/gui/project/searchprotocol.py +0 -154
- pyworkflow/gui/project/searchrun.py +0 -181
- pyworkflow/gui/project/steps.py +0 -171
- pyworkflow/gui/project/utils.py +0 -332
- pyworkflow/gui/project/variables.py +0 -179
- pyworkflow/gui/project/viewdata.py +0 -472
- pyworkflow/gui/project/viewprojects.py +0 -510
- pyworkflow/gui/project/viewprotocols.py +0 -2093
- pyworkflow/gui/project/viewprotocols_extra.py +0 -560
- pyworkflow/gui/text.py +0 -771
- pyworkflow/gui/tooltip.py +0 -185
- pyworkflow/gui/tree.py +0 -684
- pyworkflow/gui/widgets.py +0 -307
- pyworkflow/mapper/__init__.py +0 -26
- pyworkflow/mapper/mapper.py +0 -222
- pyworkflow/mapper/sqlite.py +0 -1578
- pyworkflow/mapper/sqlite_db.py +0 -145
- pyworkflow/project/__init__.py +0 -31
- pyworkflow/project/config.py +0 -454
- pyworkflow/project/manager.py +0 -180
- pyworkflow/project/project.py +0 -2010
- pyworkflow/protocol/__init__.py +0 -38
- pyworkflow/protocol/bibtex.py +0 -48
- pyworkflow/protocol/constants.py +0 -87
- pyworkflow/protocol/executor.py +0 -455
- pyworkflow/protocol/hosts.py +0 -313
- pyworkflow/protocol/launch.py +0 -270
- pyworkflow/protocol/package.py +0 -42
- pyworkflow/protocol/params.py +0 -741
- pyworkflow/protocol/protocol.py +0 -2582
- pyworkflow/tests/__init__.py +0 -29
- pyworkflow/tests/test_utils.py +0 -25
- pyworkflow/tests/tests.py +0 -341
- pyworkflow/utils/__init__.py +0 -38
- pyworkflow/utils/dataset.py +0 -414
- pyworkflow/utils/echo.py +0 -104
- pyworkflow/utils/graph.py +0 -169
- pyworkflow/utils/log.py +0 -284
- pyworkflow/utils/path.py +0 -528
- pyworkflow/utils/process.py +0 -132
- pyworkflow/utils/profiler.py +0 -92
- pyworkflow/utils/progressbar.py +0 -154
- pyworkflow/utils/properties.py +0 -631
- pyworkflow/utils/reflection.py +0 -129
- pyworkflow/utils/utils.py +0 -879
- pyworkflow/utils/which.py +0 -229
- pyworkflow/webservices/__init__.py +0 -8
- pyworkflow/webservices/config.py +0 -11
- pyworkflow/webservices/notifier.py +0 -162
- pyworkflow/webservices/repository.py +0 -59
- pyworkflow/webservices/workflowhub.py +0 -74
- pyworkflowtests/tests/__init__.py +0 -0
- pyworkflowtests/tests/test_canvas.py +0 -72
- pyworkflowtests/tests/test_domain.py +0 -45
- pyworkflowtests/tests/test_logs.py +0 -74
- pyworkflowtests/tests/test_mappers.py +0 -392
- pyworkflowtests/tests/test_object.py +0 -507
- pyworkflowtests/tests/test_project.py +0 -42
- pyworkflowtests/tests/test_protocol_execution.py +0 -135
- pyworkflowtests/tests/test_protocol_export.py +0 -78
- pyworkflowtests/tests/test_protocol_output.py +0 -158
- pyworkflowtests/tests/test_streaming.py +0 -47
- pyworkflowtests/tests/test_utils.py +0 -210
- scipion_pyworkflow-3.10.5.dist-info/RECORD +0 -140
- scipion_pyworkflow-3.10.5.dist-info/dependency_links.txt +0 -1
- scipion_pyworkflow-3.10.5.dist-info/entry_points.txt +0 -5
- {scipion_pyworkflow-3.10.5.dist-info → scipion_pyworkflow-3.11.0.dist-info/licenses}/LICENSE.txt +0 -0
- {scipion_pyworkflow-3.10.5.dist-info → scipion_pyworkflow-3.11.0.dist-info}/top_level.txt +0 -0
pyworkflow/protocol/params.py
DELETED
@@ -1,741 +0,0 @@
|
|
1
|
-
# **************************************************************************
|
2
|
-
# *
|
3
|
-
# * Authors: J.M. De la Rosa Trevin (delarosatrevin@scilifelab.se) [1]
|
4
|
-
# *
|
5
|
-
# * [1] SciLifeLab, Stockholm University
|
6
|
-
# *
|
7
|
-
# * This program is free software: you can redistribute it and/or modify
|
8
|
-
# * it under the terms of the GNU General Public License as published by
|
9
|
-
# * the Free Software Foundation, either version 3 of the License, or
|
10
|
-
# * (at your option) any later version.
|
11
|
-
# *
|
12
|
-
# * This program is distributed in the hope that it will be useful,
|
13
|
-
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
-
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
-
# * GNU General Public License for more details.
|
16
|
-
# *
|
17
|
-
# * You should have received a copy of the GNU General Public License
|
18
|
-
# * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
19
|
-
# *
|
20
|
-
# * All comments concerning this program package may be sent to the
|
21
|
-
# * e-mail address 'scipion@cnb.csic.es'
|
22
|
-
# *
|
23
|
-
# **************************************************************************
|
24
|
-
|
25
|
-
|
26
|
-
import re
|
27
|
-
import collections
|
28
|
-
|
29
|
-
from pyworkflow.object import *
|
30
|
-
from .constants import *
|
31
|
-
|
32
|
-
|
33
|
-
class FormElement(Object):
|
34
|
-
"""Base for any element on the form"""
|
35
|
-
ATTRIBUTES = ['label', 'expertLevel', 'condition', 'important', 'help',
|
36
|
-
'default', 'paramClass']
|
37
|
-
|
38
|
-
def __init__(self, **args):
|
39
|
-
super().__init__(**args)
|
40
|
-
self.label = String(args.get('label', None))
|
41
|
-
self.expertLevel = Integer(args.get('expertLevel', LEVEL_NORMAL))
|
42
|
-
self.condition = String(args.get('condition', None))
|
43
|
-
self._isImportant = Boolean(args.get('important', False))
|
44
|
-
self.help = String(args.get('help', None))
|
45
|
-
# This two list will be filled by the Form
|
46
|
-
# which have a global-view of all parameters
|
47
|
-
# All param names in which condition appears this param
|
48
|
-
self._dependants = []
|
49
|
-
# All param names that appears in the condition
|
50
|
-
self._conditionParams = []
|
51
|
-
|
52
|
-
def isExpert(self):
|
53
|
-
return self.expertLevel > LEVEL_NORMAL
|
54
|
-
|
55
|
-
def setExpert(self):
|
56
|
-
self.expertLevel.set(LEVEL_ADVANCED)
|
57
|
-
|
58
|
-
def isImportant(self):
|
59
|
-
return self._isImportant.get()
|
60
|
-
|
61
|
-
def setImportant(self, value):
|
62
|
-
self._isImportant.set(value)
|
63
|
-
|
64
|
-
def hasCondition(self):
|
65
|
-
return self.condition.hasValue()
|
66
|
-
|
67
|
-
def getLabel(self):
|
68
|
-
return self.label.get()
|
69
|
-
|
70
|
-
def getHelp(self):
|
71
|
-
return self.help.get()
|
72
|
-
|
73
|
-
def config(self, **kwargs):
|
74
|
-
""" Configure the object and set attributes
|
75
|
-
coming in the keyword-arguments, the
|
76
|
-
same as in the __init__
|
77
|
-
"""
|
78
|
-
for key in self.ATTRIBUTES:
|
79
|
-
if key in kwargs:
|
80
|
-
self.setAttributeValue(key, kwargs.get(key))
|
81
|
-
|
82
|
-
|
83
|
-
class Param(FormElement):
|
84
|
-
"""Definition of a protocol parameter"""
|
85
|
-
def __init__(self, **args):
|
86
|
-
FormElement.__init__(self, **args)
|
87
|
-
# This should be defined in subclasses
|
88
|
-
self.paramClass = args.get('paramClass', None)
|
89
|
-
self.default = String(args.get('default', None))
|
90
|
-
|
91
|
-
# Allow pointers (used for scalars)
|
92
|
-
self.allowsPointers = args.get('allowsPointers', False)
|
93
|
-
self.validators = args.get('validators', [])
|
94
|
-
self.readOnly = args.get("readOnly", False)
|
95
|
-
|
96
|
-
def __str__(self):
|
97
|
-
return " label: %s" % self.label.get()
|
98
|
-
|
99
|
-
def addValidator(self, validator):
|
100
|
-
""" Validators should be callables that
|
101
|
-
receive a value and return a list of errors if so.
|
102
|
-
If everything is ok, the result should be an empty list.
|
103
|
-
"""
|
104
|
-
self.validators.append(validator)
|
105
|
-
|
106
|
-
def validate(self, value):
|
107
|
-
errors = []
|
108
|
-
for val in self.validators:
|
109
|
-
errors += val(value)
|
110
|
-
return errors
|
111
|
-
|
112
|
-
def getDefault(self):
|
113
|
-
return self.default.get()
|
114
|
-
|
115
|
-
def setDefault(self, newDefault):
|
116
|
-
self.default.set(newDefault)
|
117
|
-
|
118
|
-
|
119
|
-
class ElementGroup(FormElement):
|
120
|
-
""" Class to group some params in the form.
|
121
|
-
Such as: Labeled group or params in the same line.
|
122
|
-
"""
|
123
|
-
def __init__(self, form=None, **args):
|
124
|
-
FormElement.__init__(self, **args)
|
125
|
-
self._form = form
|
126
|
-
self._paramList = []
|
127
|
-
|
128
|
-
def iterParams(self):
|
129
|
-
""" Return key and param for every child param. """
|
130
|
-
for name in self._paramList:
|
131
|
-
yield name, self._form.getParam(name)
|
132
|
-
|
133
|
-
def addParam(self, paramName, ParamClass, **kwargs):
|
134
|
-
"""Add a new param to the group"""
|
135
|
-
param = ParamClass(**kwargs)
|
136
|
-
self._paramList.append(paramName)
|
137
|
-
self._form.registerParam(paramName, param)
|
138
|
-
return param
|
139
|
-
|
140
|
-
def addHidden(self, paramName, ParamClass, **kwargs):
|
141
|
-
"""Add a hidden parameter to be used in conditions. """
|
142
|
-
kwargs.update({'label': '', 'condition': 'False'})
|
143
|
-
self.addParam(paramName, ParamClass, **kwargs)
|
144
|
-
|
145
|
-
def addLine(self, lineName, **kwargs):
|
146
|
-
|
147
|
-
labelName = lineName
|
148
|
-
for symbol in ' ()':
|
149
|
-
labelName = labelName.replace(symbol, '_')
|
150
|
-
|
151
|
-
return self.addParam(labelName, Line, form=self._form,
|
152
|
-
label=lineName, **kwargs)
|
153
|
-
|
154
|
-
|
155
|
-
# ----------- Some type of ElementGroup --------------------------
|
156
|
-
|
157
|
-
class Line(ElementGroup):
|
158
|
-
""" Group to put some parameters in the same line. """
|
159
|
-
pass
|
160
|
-
|
161
|
-
|
162
|
-
class Group(ElementGroup):
|
163
|
-
""" Group some parameters with a labeled frame. """
|
164
|
-
pass
|
165
|
-
|
166
|
-
|
167
|
-
class Section(ElementGroup):
|
168
|
-
"""Definition of a section to hold other params"""
|
169
|
-
def __init__(self, form, **args):
|
170
|
-
ElementGroup.__init__(self, form, **args)
|
171
|
-
self.questionParam = String(args.get('questionParam', ''))
|
172
|
-
|
173
|
-
def hasQuestion(self):
|
174
|
-
"""Return True if a question param was set"""
|
175
|
-
return self.questionParam.get() in self._paramList
|
176
|
-
|
177
|
-
def getQuestionName(self):
|
178
|
-
""" Return the name of the question param. """
|
179
|
-
return self.questionParam.get()
|
180
|
-
|
181
|
-
def getQuestion(self):
|
182
|
-
""" Return the question param"""
|
183
|
-
return self._form.getParam(self.questionParam.get())
|
184
|
-
|
185
|
-
def addGroup(self, groupName, **kwargs):
|
186
|
-
labelName = groupName
|
187
|
-
for symbol in ' ()':
|
188
|
-
labelName = labelName.replace(symbol, '_')
|
189
|
-
|
190
|
-
return self.addParam(labelName, Group, form=self._form,
|
191
|
-
label=groupName, **kwargs)
|
192
|
-
|
193
|
-
|
194
|
-
class Form(object):
|
195
|
-
"""Store all sections and parameters"""
|
196
|
-
def __init__(self, protocol):
|
197
|
-
""" Build a Form from a given protocol. """
|
198
|
-
object.__init__(self)
|
199
|
-
self._sectionList = [] # Store list of sections
|
200
|
-
# Dictionary to store all params, grouped by sections
|
201
|
-
self._paramsDict = collections.OrderedDict()
|
202
|
-
self._lastSection = None
|
203
|
-
self._protocol = protocol
|
204
|
-
self.addGeneralSection()
|
205
|
-
|
206
|
-
def getClass(self):
|
207
|
-
return type(self)
|
208
|
-
|
209
|
-
def addSection(self, label='', **kwargs):
|
210
|
-
"""Add a new section"""
|
211
|
-
self.lastSection = Section(self, label=label, **kwargs)
|
212
|
-
self._sectionList.append(self.lastSection)
|
213
|
-
return self.lastSection
|
214
|
-
|
215
|
-
def getSection(self, label):
|
216
|
-
""" get section by label from _sectionList"""
|
217
|
-
for s in self._sectionList:
|
218
|
-
if s.label == label:
|
219
|
-
return s
|
220
|
-
return
|
221
|
-
|
222
|
-
def addGroup(self, *args, **kwargs):
|
223
|
-
return self.lastSection.addGroup(*args, **kwargs)
|
224
|
-
|
225
|
-
def addLine(self, *args, **kwargs):
|
226
|
-
return self.lastSection.addLine(*args, **kwargs)
|
227
|
-
|
228
|
-
def registerParam(self, paramName, param):
|
229
|
-
""" Register a given param in the form. """
|
230
|
-
self._paramsDict[paramName] = param
|
231
|
-
self._analizeCondition(paramName, param)
|
232
|
-
|
233
|
-
def addParam(self, *args, **kwargs):
|
234
|
-
"""Add a new param to last section"""
|
235
|
-
return self.lastSection.addParam(*args, **kwargs)
|
236
|
-
|
237
|
-
# Adhoc method for specific params
|
238
|
-
def addBooleanParam(self, name, label, help, default=True, **kwargs):
|
239
|
-
return self.addParam(name, BooleanParam, label=label, help=help, default=default, **kwargs)
|
240
|
-
|
241
|
-
def addHidden(self, *args, **kwargs):
|
242
|
-
return self.lastSection.addHidden(*args, **kwargs)
|
243
|
-
|
244
|
-
def _analizeCondition(self, paramName, param):
|
245
|
-
if param.hasCondition():
|
246
|
-
param._conditionParams = []
|
247
|
-
tokens = re.split(r'\W+', param.condition.get())
|
248
|
-
for t in tokens:
|
249
|
-
if self.hasParam(t):
|
250
|
-
self.getParam(t)._dependants.append(paramName)
|
251
|
-
param._conditionParams.append(t)
|
252
|
-
if self._protocol.hasAttribute(t):
|
253
|
-
param._conditionParams.append(t)
|
254
|
-
|
255
|
-
def evalParamCondition(self, paramName):
|
256
|
-
"""Evaluate if a condition is True for a give param
|
257
|
-
with the values of a particular Protocol"""
|
258
|
-
param = self.getParam(paramName)
|
259
|
-
|
260
|
-
if not param.hasCondition():
|
261
|
-
return True
|
262
|
-
condStr = param.condition.get()
|
263
|
-
localDict = {}
|
264
|
-
globalDict = dict(globals())
|
265
|
-
# FIXME: Check why this import is here
|
266
|
-
from pyworkflow import Config
|
267
|
-
globalDict.update(Config.getDomain().getObjects())
|
268
|
-
|
269
|
-
for t in param._conditionParams:
|
270
|
-
if self.hasParam(t) or self._protocol.hasAttribute(t):
|
271
|
-
localDict[t] = self._protocol.getAttributeValue(t)
|
272
|
-
|
273
|
-
return eval(condStr, globalDict, localDict)
|
274
|
-
|
275
|
-
def validateParams(self, protocol):
|
276
|
-
""" Check that all validations of the params in the form
|
277
|
-
are met for the protocol param values.
|
278
|
-
It will return a list with errors, just in the same
|
279
|
-
way of the Protocol.validate function
|
280
|
-
"""
|
281
|
-
errors = []
|
282
|
-
|
283
|
-
for name, param in self.iterParams():
|
284
|
-
value = protocol.getAttributeValue(name)
|
285
|
-
errors += param.validate(value)
|
286
|
-
|
287
|
-
return errors
|
288
|
-
|
289
|
-
def getParam(self, paramName):
|
290
|
-
"""Retrieve a param given a the param name
|
291
|
-
None is returned if not found
|
292
|
-
"""
|
293
|
-
return self._paramsDict.get(paramName, None)
|
294
|
-
|
295
|
-
def hasParam(self, paramName):
|
296
|
-
return paramName in self._paramsDict
|
297
|
-
|
298
|
-
def __str__(self):
|
299
|
-
s = "Form: \n"
|
300
|
-
for section in self.iterSections():
|
301
|
-
s += str(section)
|
302
|
-
return s
|
303
|
-
|
304
|
-
def iterSections(self):
|
305
|
-
return self._sectionList
|
306
|
-
|
307
|
-
def iterAllParams(self):
|
308
|
-
""" Iter all parameters, including ElementGroups. """
|
309
|
-
return self._paramsDict.items()
|
310
|
-
|
311
|
-
def iterParams(self):
|
312
|
-
""" Iter parameters disregarding the ElementGroups. """
|
313
|
-
for k, v in self._paramsDict.items():
|
314
|
-
if not isinstance(v, ElementGroup):
|
315
|
-
yield k, v
|
316
|
-
|
317
|
-
def iterPointerParams(self):
|
318
|
-
for paramName, param in self._paramsDict.items():
|
319
|
-
if isinstance(param, PointerParam):
|
320
|
-
yield paramName, param
|
321
|
-
|
322
|
-
def addGeneralSection(self):
|
323
|
-
self.addSection(label='General')
|
324
|
-
self.addParam('runName', StringParam, label="Run name:", important=True,
|
325
|
-
help='Select run name label to identify this run.')
|
326
|
-
self.addParam('runMode', EnumParam, choices=['resume', 'restart'],
|
327
|
-
label="Run mode", display=EnumParam.DISPLAY_COMBO, default=0,
|
328
|
-
help='The <resume> mode will try to start the execution'
|
329
|
-
'from the last successfully finished step if possible.'
|
330
|
-
'On the contrary, <restart> will delete all previous results'
|
331
|
-
'of this particular run and start from the beginning. This option'
|
332
|
-
'should be used carefully.'
|
333
|
-
)
|
334
|
-
|
335
|
-
def addParallelSection(self, threads=1, mpi=8, condition="",
|
336
|
-
hours=72, jobsize=0):
|
337
|
-
|
338
|
-
""" Adds the parallelization section to the form
|
339
|
-
pass threads=0 to disable threads parameter and mpi=0 to disable mpi params
|
340
|
-
|
341
|
-
:param threads: default value for of threads, defaults to 1
|
342
|
-
:param mpi: default value for mpi, defaults to 8"""
|
343
|
-
|
344
|
-
self.addSection(label='Parallelization')
|
345
|
-
self.addParam('hostName', StringParam, default="localhost",
|
346
|
-
label='Execution host',
|
347
|
-
help='Select in which of the available do you want to launch this protocol.')
|
348
|
-
|
349
|
-
# NOTE: help messages for these parameters is defined at HELP_MPI_THREADS and used in form.py.
|
350
|
-
|
351
|
-
if threads > 0:
|
352
|
-
self.addParam('numberOfThreads', IntParam, default=threads,
|
353
|
-
label='Threads')
|
354
|
-
if mpi > 0:
|
355
|
-
self.addParam('numberOfMpi', IntParam, default=mpi,
|
356
|
-
label='MPI processes')
|
357
|
-
if jobsize > 0:
|
358
|
-
self.addParam('mpiJobSize', IntParam, default=jobsize,
|
359
|
-
label='MPI job size', condition="numberOfMpi>1",
|
360
|
-
help='Minimum size of jobs in mpi processes.'
|
361
|
-
'Set to 1 for large images (e.g. 500x500)'
|
362
|
-
'and to 10 for small images (e.g. 100x100)')
|
363
|
-
|
364
|
-
|
365
|
-
class StringParam(Param):
|
366
|
-
"""Param with underlying String value"""
|
367
|
-
def __init__(self, **args):
|
368
|
-
Param.__init__(self, paramClass=String, **args)
|
369
|
-
|
370
|
-
|
371
|
-
class TextParam(StringParam):
|
372
|
-
"""Long string params"""
|
373
|
-
def __init__(self, **args):
|
374
|
-
StringParam.__init__(self, **args)
|
375
|
-
self.height = args.get('height', 5)
|
376
|
-
self.width = args.get('width', 30)
|
377
|
-
|
378
|
-
|
379
|
-
class RegexParam(StringParam):
|
380
|
-
"""Regex based string param"""
|
381
|
-
pass
|
382
|
-
|
383
|
-
|
384
|
-
class PathParam(StringParam):
|
385
|
-
"""Param for path strings"""
|
386
|
-
pass
|
387
|
-
|
388
|
-
|
389
|
-
# TODO: Handle filter pattern
|
390
|
-
class FileParam(PathParam):
|
391
|
-
"""Filename path"""
|
392
|
-
pass
|
393
|
-
|
394
|
-
|
395
|
-
class FolderParam(PathParam):
|
396
|
-
"""Folder path"""
|
397
|
-
pass
|
398
|
-
|
399
|
-
|
400
|
-
class LabelParam(StringParam):
|
401
|
-
""" Just the same as StringParam, but to be rendered
|
402
|
-
as a label and can not be directly edited by the user
|
403
|
-
in the Protocol Form.
|
404
|
-
"""
|
405
|
-
pass
|
406
|
-
|
407
|
-
|
408
|
-
class IntParam(Param):
|
409
|
-
def __init__(self, **args):
|
410
|
-
Param.__init__(self, paramClass=Integer, **args)
|
411
|
-
self.addValidator(Format(int, error="should be an integer",
|
412
|
-
allowsNull=args.get('allowsNull', False)))
|
413
|
-
|
414
|
-
|
415
|
-
class EnumParam(IntParam):
|
416
|
-
"""Select from a list of values, separated by comma"""
|
417
|
-
# Possible values for display
|
418
|
-
DISPLAY_LIST = 0
|
419
|
-
DISPLAY_COMBO = 1
|
420
|
-
DISPLAY_HLIST = 2 # horizontal list, save space
|
421
|
-
|
422
|
-
def __init__(self, **args):
|
423
|
-
IntParam.__init__(self, **args)
|
424
|
-
self.choices = args.get('choices', [])
|
425
|
-
self.display = Integer(args.get('display', EnumParam.DISPLAY_COMBO))
|
426
|
-
|
427
|
-
|
428
|
-
class FloatParam(Param):
|
429
|
-
def __init__(self, **args):
|
430
|
-
Param.__init__(self, paramClass=Float, **args)
|
431
|
-
self.addValidator(Format(float, error="should be a float",
|
432
|
-
allowsNull=args.get('allowsNull', False)))
|
433
|
-
|
434
|
-
|
435
|
-
class BooleanParam(Param):
|
436
|
-
""" Param to store boolean values. By default it will be displayed as 2 radio buttons with Yes/no labels.
|
437
|
-
Alternatively, if you pass checkbox it will be displayed as a checkbox.
|
438
|
-
|
439
|
-
:param display: (Optional) default DISPLAY_YES_NO. (Yes /no)
|
440
|
-
Alternatively use BooleanParam.DISPLAY_CHECKBOX to use checkboxes """
|
441
|
-
DISPLAY_YES_NO = 1
|
442
|
-
DISPLAY_CHECKBOX = 2
|
443
|
-
|
444
|
-
def __init__(self, display=DISPLAY_YES_NO, **args):
|
445
|
-
Param.__init__(self, paramClass=Boolean, **args)
|
446
|
-
self.display = display
|
447
|
-
self.addValidator(NonEmptyBool)
|
448
|
-
|
449
|
-
|
450
|
-
class HiddenBooleanParam(BooleanParam):
|
451
|
-
def __init__(self, **args):
|
452
|
-
Param.__init__(self, paramClass=Boolean, **args)
|
453
|
-
|
454
|
-
|
455
|
-
class PointerParam(Param):
|
456
|
-
""" This type of Param will serve to select existing objects
|
457
|
-
in the database that will be input for some protocol.
|
458
|
-
"""
|
459
|
-
def __init__(self, paramClass=Pointer, **args):
|
460
|
-
Param.__init__(self, paramClass=paramClass, **args)
|
461
|
-
# This will be the class to be pointed
|
462
|
-
self.setPointerClass(args['pointerClass'])
|
463
|
-
# Some conditions on the pointed candidates
|
464
|
-
self.pointerCondition = String(args.get('pointerCondition', None))
|
465
|
-
self.allowsNull = Boolean(args.get('allowsNull', False))
|
466
|
-
|
467
|
-
def setPointerClass(self, newPointerClass):
|
468
|
-
|
469
|
-
# Tolerate passing classes instead of their names
|
470
|
-
if isinstance(newPointerClass, list):
|
471
|
-
self.pointerClass = CsvList()
|
472
|
-
self.pointerClass.set(",". join([clazz.__name__ for clazz in newPointerClass]))
|
473
|
-
|
474
|
-
elif(isinstance(newPointerClass, str)):
|
475
|
-
if ',' in newPointerClass:
|
476
|
-
self.pointerClass = CsvList()
|
477
|
-
self.pointerClass.set(newPointerClass)
|
478
|
-
else:
|
479
|
-
self.pointerClass = String(newPointerClass)
|
480
|
-
|
481
|
-
# Single class item, not the string
|
482
|
-
else:
|
483
|
-
self.pointerClass = String(newPointerClass.__name__)
|
484
|
-
|
485
|
-
|
486
|
-
class MultiPointerParam(PointerParam):
|
487
|
-
""" This type of Param will serve to select objects
|
488
|
-
with DIFFERENT types from the database to be input for some protocol.
|
489
|
-
"""
|
490
|
-
def __init__(self, **args):
|
491
|
-
PointerParam.__init__(self, paramClass=PointerList, **args)
|
492
|
-
self.maxNumObjects = Integer(args.get('maxNumObjects', 100))
|
493
|
-
self.minNumObjects = Integer(args.get('minNumObjects', 2))
|
494
|
-
|
495
|
-
|
496
|
-
class RelationParam(Param):
|
497
|
-
""" This type of Param is very similar to PointerParam, since it will
|
498
|
-
hold a pointer to another object. But, in the PointerParam, we search
|
499
|
-
for objects of some Class (maybe with some conditions).
|
500
|
-
Here, we search for objects related to a given attribute of a protocol
|
501
|
-
by a given relation.
|
502
|
-
"""
|
503
|
-
def __init__(self, **args):
|
504
|
-
Param.__init__(self, paramClass=Pointer, **args)
|
505
|
-
# This will be the name of the relation
|
506
|
-
self._relationName = String(args.get('relationName'))
|
507
|
-
# We will store the attribute name in the protocol to be
|
508
|
-
# used as the object for which relations will be search
|
509
|
-
self._attributeName = String(args.get('attributeName'))
|
510
|
-
# This specify if we want to search for childs or parents
|
511
|
-
# of the given attribute of the protocol
|
512
|
-
self._direction = Integer(args.get('direction', RELATION_CHILDS))
|
513
|
-
self.allowsNull = Boolean(args.get('allowsNull', False))
|
514
|
-
|
515
|
-
def getName(self):
|
516
|
-
return self._relationName.get()
|
517
|
-
|
518
|
-
def getAttributeName(self):
|
519
|
-
return self._attributeName.get()
|
520
|
-
|
521
|
-
def getDirection(self):
|
522
|
-
return self._direction.get()
|
523
|
-
|
524
|
-
|
525
|
-
class ProtocolClassParam(StringParam):
|
526
|
-
def __init__(self, **args):
|
527
|
-
StringParam.__init__(self, **args)
|
528
|
-
self.protocolClassName = String(args.get('protocolClassName'))
|
529
|
-
self.allowSubclasses = Boolean(args.get('allowSubclasses', False))
|
530
|
-
|
531
|
-
|
532
|
-
class DigFreqParam(FloatParam):
|
533
|
-
""" Digital frequency param. """
|
534
|
-
def __init__(self, **args):
|
535
|
-
FloatParam.__init__(self, **args)
|
536
|
-
self.addValidator(FreqValidator)
|
537
|
-
|
538
|
-
|
539
|
-
class NumericListParam(StringParam):
|
540
|
-
""" This class will serve to have list representations as strings.
|
541
|
-
Possible notation are:
|
542
|
-
1000 10 1 1 -> to define a list with 4 values [1000, 10, 1, 1], or
|
543
|
-
10x2 5x3 -> to define a list with 5 values [10, 10, 5, 5, 5]
|
544
|
-
If you ask for more elements than in the list, the last one is repeated
|
545
|
-
"""
|
546
|
-
def __init__(self, **args):
|
547
|
-
StringParam.__init__(self, **args)
|
548
|
-
self.addValidator(NumericListValidator())
|
549
|
-
|
550
|
-
|
551
|
-
class NumericRangeParam(StringParam):
|
552
|
-
""" This class will serve to specify range of numbers with a string representation.
|
553
|
-
Possible notation are::
|
554
|
-
|
555
|
-
"1,5-8,10" -> [1,5,6,7,8,10]
|
556
|
-
"2,6,9-11" -> [2,6,9,10,11]
|
557
|
-
"2 5, 6-8" -> [2,5,6,7,8]
|
558
|
-
|
559
|
-
"""
|
560
|
-
def __init__(self, **args):
|
561
|
-
StringParam.__init__(self, **args)
|
562
|
-
self.addValidator(NumericRangeValidator())
|
563
|
-
|
564
|
-
|
565
|
-
class TupleParam(Param):
|
566
|
-
""" This class will condense a tuple of several
|
567
|
-
other params of the same type and related concept.
|
568
|
-
For example: min and max, low and high.
|
569
|
-
"""
|
570
|
-
def __init__(self, **args):
|
571
|
-
Param.__init__(self, **args)
|
572
|
-
|
573
|
-
|
574
|
-
class DeprecatedParam:
|
575
|
-
""" Deprecated param. To be used when you want to rename an existing param
|
576
|
-
and still be able to recover old param value. It acts like a redirector, passing the
|
577
|
-
value received when its value is set to the new renamed parameter
|
578
|
-
|
579
|
-
usage: In defineParams method, before the renamed param definition line add the following:
|
580
|
-
|
581
|
-
self.oldName = DeprecatedParam("newName", self)
|
582
|
-
form.addParam('newName', ...)
|
583
|
-
|
584
|
-
"""
|
585
|
-
def __init__(self, newParamName, prot):
|
586
|
-
"""
|
587
|
-
|
588
|
-
:param newParamName: Name of the renamed param
|
589
|
-
:param prot: Protocol hosting this and the renamed param
|
590
|
-
|
591
|
-
"""
|
592
|
-
self._newParamName = newParamName
|
593
|
-
self.prot = prot
|
594
|
-
# Need to fake being a Object at loading time
|
595
|
-
self._objId = None
|
596
|
-
self._objIsPointer = False
|
597
|
-
|
598
|
-
def set(self, value, cleanExtended=False):
|
599
|
-
if hasattr(self.prot, self._newParamName):
|
600
|
-
newParam = self._getNewParam()
|
601
|
-
if newParam.isPointer():
|
602
|
-
newParam.set(value, cleanExtended)
|
603
|
-
self._extended = newParam._extended
|
604
|
-
else:
|
605
|
-
newParam.set(value)
|
606
|
-
|
607
|
-
def isPointer(self):
|
608
|
-
return self._getNewParam().isPointer()
|
609
|
-
|
610
|
-
def getObjValue(self):
|
611
|
-
return None
|
612
|
-
|
613
|
-
def _getNewParam(self):
|
614
|
-
return getattr(self.prot, self._newParamName)
|
615
|
-
|
616
|
-
# -----------------------------------------------------------------------------
|
617
|
-
# Validators
|
618
|
-
# -----------------------------------------------------------------------------
|
619
|
-
class Validator(object):
|
620
|
-
pass
|
621
|
-
|
622
|
-
|
623
|
-
class Conditional(Validator):
|
624
|
-
""" Simple validation based on a condition.
|
625
|
-
If the value doesn't meet the condition,
|
626
|
-
the error will be returned.
|
627
|
-
"""
|
628
|
-
def __init__(self, error, allowsNull=False):
|
629
|
-
self.error = error
|
630
|
-
self._allowsNull = allowsNull
|
631
|
-
|
632
|
-
def __call__(self, value):
|
633
|
-
errors = []
|
634
|
-
if value is not None or not self._allowsNull:
|
635
|
-
if not self._condition(value):
|
636
|
-
errors.append(self.error)
|
637
|
-
return errors
|
638
|
-
|
639
|
-
|
640
|
-
class Format(Conditional):
|
641
|
-
""" Check if the format is right. """
|
642
|
-
def __init__(self, valueType, error='Value have not a correct format',
|
643
|
-
allowsNull=False):
|
644
|
-
Conditional.__init__(self, error, allowsNull)
|
645
|
-
self.valueType = valueType
|
646
|
-
|
647
|
-
def _condition(self, value):
|
648
|
-
try:
|
649
|
-
self.valueType(value)
|
650
|
-
return True
|
651
|
-
except Exception:
|
652
|
-
return False
|
653
|
-
|
654
|
-
|
655
|
-
class NonEmptyCondition(Conditional):
|
656
|
-
def __init__(self, error='Value cannot be empty'):
|
657
|
-
Conditional.__init__(self, error)
|
658
|
-
self._condition = lambda value: len(value) > 0
|
659
|
-
|
660
|
-
|
661
|
-
class LT(Conditional):
|
662
|
-
def __init__(self, threshold,
|
663
|
-
error='Value should be less than the threshold'):
|
664
|
-
Conditional.__init__(self, error)
|
665
|
-
self._condition = lambda value: value < threshold
|
666
|
-
|
667
|
-
|
668
|
-
class LE(Conditional):
|
669
|
-
def __init__(self, threshold,
|
670
|
-
error='Value should be less or equal than the threshold'):
|
671
|
-
Conditional.__init__(self, error)
|
672
|
-
self._condition = lambda value: value <= threshold
|
673
|
-
|
674
|
-
|
675
|
-
class GT(Conditional):
|
676
|
-
def __init__(self, threshold,
|
677
|
-
error='Value should be greater than the threshold'):
|
678
|
-
Conditional.__init__(self, error)
|
679
|
-
self._condition = lambda value: value > threshold
|
680
|
-
|
681
|
-
|
682
|
-
class GE(Conditional):
|
683
|
-
def __init__(self, thresold, error='Value should be greater or equal than the threshold'):
|
684
|
-
Conditional.__init__(self, error)
|
685
|
-
self._condition = lambda value: value is not None and value >= thresold
|
686
|
-
|
687
|
-
|
688
|
-
class Range(Conditional):
|
689
|
-
def __init__(self, minValue, maxValue, error='Value is outside range'):
|
690
|
-
Conditional.__init__(self, error)
|
691
|
-
self._condition = lambda value: minValue <= value <= maxValue
|
692
|
-
|
693
|
-
|
694
|
-
class NumericListValidator(Conditional):
|
695
|
-
""" Validator for ListParam. See ListParam. """
|
696
|
-
def __init__(self, error='Incorrect format for numeric list param'):
|
697
|
-
Conditional.__init__(self, error)
|
698
|
-
|
699
|
-
def _condition(self, value):
|
700
|
-
try:
|
701
|
-
parts = re.split(r"[x\s]", value)
|
702
|
-
parts = list(filter(None, parts))
|
703
|
-
for p in parts:
|
704
|
-
float(p)
|
705
|
-
return True
|
706
|
-
except Exception:
|
707
|
-
return False
|
708
|
-
|
709
|
-
|
710
|
-
class NumericRangeValidator(Conditional):
|
711
|
-
""" Validator for RangeParam. See RangeParam. """
|
712
|
-
|
713
|
-
def __init__(self, error='Incorrect format for numeric range param'):
|
714
|
-
Conditional.__init__(self, error)
|
715
|
-
|
716
|
-
def _condition(self, value):
|
717
|
-
try:
|
718
|
-
parts = re.split(r"[-,\s]", value)
|
719
|
-
parts = list(filter(None, parts))
|
720
|
-
for p in parts:
|
721
|
-
float(p)
|
722
|
-
return True
|
723
|
-
except Exception:
|
724
|
-
return False
|
725
|
-
|
726
|
-
|
727
|
-
class NonEmptyBoolCondition(Conditional):
|
728
|
-
def __init__(self, error='Boolean param needs to be set.'):
|
729
|
-
Conditional.__init__(self, error)
|
730
|
-
self._condition = lambda value: value is not None
|
731
|
-
|
732
|
-
|
733
|
-
# --------- Some constants validators ---------------------
|
734
|
-
|
735
|
-
Positive = GT(0.0, error='Value should be greater than zero')
|
736
|
-
|
737
|
-
FreqValidator = Range(0.001, 0.5,
|
738
|
-
error="Digital frequencies should be between 0.001 and 0.5")
|
739
|
-
|
740
|
-
NonEmpty = NonEmptyCondition()
|
741
|
-
NonEmptyBool = NonEmptyBoolCondition()
|