scipion-pyworkflow 3.7.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/__init__.py +33 -0
- pyworkflow/apps/__init__.py +29 -0
- pyworkflow/apps/pw_manager.py +37 -0
- pyworkflow/apps/pw_plot.py +51 -0
- pyworkflow/apps/pw_project.py +113 -0
- pyworkflow/apps/pw_protocol_list.py +143 -0
- pyworkflow/apps/pw_protocol_run.py +51 -0
- pyworkflow/apps/pw_run_tests.py +267 -0
- pyworkflow/apps/pw_schedule_run.py +322 -0
- pyworkflow/apps/pw_sleep.py +37 -0
- pyworkflow/apps/pw_sync_data.py +439 -0
- pyworkflow/apps/pw_viewer.py +78 -0
- pyworkflow/config.py +536 -0
- pyworkflow/constants.py +212 -0
- pyworkflow/exceptions.py +18 -0
- pyworkflow/gui/__init__.py +36 -0
- pyworkflow/gui/browser.py +726 -0
- pyworkflow/gui/canvas.py +1190 -0
- pyworkflow/gui/dialog.py +976 -0
- pyworkflow/gui/form.py +2627 -0
- pyworkflow/gui/graph.py +247 -0
- pyworkflow/gui/graph_layout.py +271 -0
- pyworkflow/gui/gui.py +566 -0
- pyworkflow/gui/matplotlib_image.py +233 -0
- pyworkflow/gui/plotter.py +247 -0
- pyworkflow/gui/project/__init__.py +25 -0
- pyworkflow/gui/project/base.py +192 -0
- pyworkflow/gui/project/constants.py +139 -0
- pyworkflow/gui/project/labels.py +205 -0
- pyworkflow/gui/project/project.py +484 -0
- pyworkflow/gui/project/searchprotocol.py +154 -0
- pyworkflow/gui/project/searchrun.py +181 -0
- pyworkflow/gui/project/steps.py +166 -0
- pyworkflow/gui/project/utils.py +332 -0
- pyworkflow/gui/project/variables.py +179 -0
- pyworkflow/gui/project/viewdata.py +472 -0
- pyworkflow/gui/project/viewprojects.py +510 -0
- pyworkflow/gui/project/viewprotocols.py +2093 -0
- pyworkflow/gui/project/viewprotocols_extra.py +560 -0
- pyworkflow/gui/text.py +771 -0
- pyworkflow/gui/tooltip.py +185 -0
- pyworkflow/gui/tree.py +684 -0
- pyworkflow/gui/widgets.py +307 -0
- pyworkflow/mapper/__init__.py +26 -0
- pyworkflow/mapper/mapper.py +222 -0
- pyworkflow/mapper/sqlite.py +1578 -0
- pyworkflow/mapper/sqlite_db.py +145 -0
- pyworkflow/object.py +1512 -0
- pyworkflow/plugin.py +712 -0
- pyworkflow/project/__init__.py +31 -0
- pyworkflow/project/config.py +451 -0
- pyworkflow/project/manager.py +179 -0
- pyworkflow/project/project.py +1990 -0
- pyworkflow/project/scripts/clean_projects.py +77 -0
- pyworkflow/project/scripts/config.py +92 -0
- pyworkflow/project/scripts/create.py +77 -0
- pyworkflow/project/scripts/edit_workflow.py +90 -0
- pyworkflow/project/scripts/fix_links.py +39 -0
- pyworkflow/project/scripts/load.py +87 -0
- pyworkflow/project/scripts/refresh.py +83 -0
- pyworkflow/project/scripts/schedule.py +111 -0
- pyworkflow/project/scripts/stack2volume.py +41 -0
- pyworkflow/project/scripts/stop.py +81 -0
- pyworkflow/protocol/__init__.py +38 -0
- pyworkflow/protocol/bibtex.py +48 -0
- pyworkflow/protocol/constants.py +86 -0
- pyworkflow/protocol/executor.py +334 -0
- pyworkflow/protocol/hosts.py +313 -0
- pyworkflow/protocol/launch.py +270 -0
- pyworkflow/protocol/package.py +42 -0
- pyworkflow/protocol/params.py +744 -0
- pyworkflow/protocol/protocol.py +2554 -0
- pyworkflow/resources/Imagej.png +0 -0
- pyworkflow/resources/chimera.png +0 -0
- pyworkflow/resources/fa-exclamation-triangle_alert.png +0 -0
- pyworkflow/resources/fa-info-circle_alert.png +0 -0
- pyworkflow/resources/fa-search.png +0 -0
- pyworkflow/resources/fa-times-circle_alert.png +0 -0
- pyworkflow/resources/file_vol.png +0 -0
- pyworkflow/resources/loading.gif +0 -0
- pyworkflow/resources/no-image128.png +0 -0
- pyworkflow/resources/scipion_bn.png +0 -0
- pyworkflow/resources/scipion_icon.png +0 -0
- pyworkflow/resources/scipion_icon.svg +397 -0
- pyworkflow/resources/scipion_icon_proj.png +0 -0
- pyworkflow/resources/scipion_icon_projs.png +0 -0
- pyworkflow/resources/scipion_icon_prot.png +0 -0
- pyworkflow/resources/scipion_logo.png +0 -0
- pyworkflow/resources/scipion_logo_normal.png +0 -0
- pyworkflow/resources/scipion_logo_small.png +0 -0
- pyworkflow/resources/sprites.png +0 -0
- pyworkflow/resources/sprites.xcf +0 -0
- pyworkflow/resources/wait.gif +0 -0
- pyworkflow/template.py +322 -0
- pyworkflow/tests/__init__.py +29 -0
- pyworkflow/tests/test_utils.py +25 -0
- pyworkflow/tests/tests.py +341 -0
- pyworkflow/utils/__init__.py +38 -0
- pyworkflow/utils/dataset.py +414 -0
- pyworkflow/utils/echo.py +104 -0
- pyworkflow/utils/graph.py +196 -0
- pyworkflow/utils/log.py +284 -0
- pyworkflow/utils/path.py +527 -0
- pyworkflow/utils/process.py +132 -0
- pyworkflow/utils/profiler.py +92 -0
- pyworkflow/utils/progressbar.py +154 -0
- pyworkflow/utils/properties.py +627 -0
- pyworkflow/utils/reflection.py +129 -0
- pyworkflow/utils/utils.py +877 -0
- pyworkflow/utils/which.py +229 -0
- pyworkflow/viewer.py +328 -0
- pyworkflow/webservices/__init__.py +8 -0
- pyworkflow/webservices/config.py +11 -0
- pyworkflow/webservices/notifier.py +162 -0
- pyworkflow/webservices/repository.py +59 -0
- pyworkflow/webservices/workflowhub.py +74 -0
- pyworkflow/wizard.py +64 -0
- pyworkflowtests/__init__.py +51 -0
- pyworkflowtests/bibtex.py +51 -0
- pyworkflowtests/objects.py +830 -0
- pyworkflowtests/protocols.py +154 -0
- pyworkflowtests/tests/__init__.py +0 -0
- pyworkflowtests/tests/test_canvas.py +72 -0
- pyworkflowtests/tests/test_domain.py +45 -0
- pyworkflowtests/tests/test_logs.py +74 -0
- pyworkflowtests/tests/test_mappers.py +392 -0
- pyworkflowtests/tests/test_object.py +507 -0
- pyworkflowtests/tests/test_project.py +42 -0
- pyworkflowtests/tests/test_protocol_execution.py +72 -0
- pyworkflowtests/tests/test_protocol_export.py +78 -0
- pyworkflowtests/tests/test_protocol_output.py +158 -0
- pyworkflowtests/tests/test_streaming.py +47 -0
- pyworkflowtests/tests/test_utils.py +210 -0
- scipion_pyworkflow-3.7.0.dist-info/LICENSE.txt +674 -0
- scipion_pyworkflow-3.7.0.dist-info/METADATA +107 -0
- scipion_pyworkflow-3.7.0.dist-info/RECORD +140 -0
- scipion_pyworkflow-3.7.0.dist-info/WHEEL +5 -0
- scipion_pyworkflow-3.7.0.dist-info/dependency_links.txt +1 -0
- scipion_pyworkflow-3.7.0.dist-info/entry_points.txt +5 -0
- scipion_pyworkflow-3.7.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,414 @@
|
|
1
|
+
# **************************************************************************
|
2
|
+
# *
|
3
|
+
# * Authors: J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es)
|
4
|
+
# *
|
5
|
+
# * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
|
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, write to the Free Software
|
19
|
+
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
20
|
+
# * 02111-1307 USA
|
21
|
+
# *
|
22
|
+
# * All comments concerning this program package may be sent to the
|
23
|
+
# * e-mail address 'scipion@cnb.csic.es'
|
24
|
+
# *
|
25
|
+
# **************************************************************************
|
26
|
+
"""
|
27
|
+
# JMRT (2018-12-11) This module is almost not used at all. Maybe it
|
28
|
+
can be removed in a future. Just kept here for the moment inside
|
29
|
+
pw.utils and not imported by default
|
30
|
+
"""
|
31
|
+
|
32
|
+
import os
|
33
|
+
from collections import OrderedDict, namedtuple
|
34
|
+
|
35
|
+
from pyworkflow.mapper import SqliteFlatDb, SqliteDb
|
36
|
+
|
37
|
+
|
38
|
+
class DataSet(object):
|
39
|
+
""" Holds several Tables
|
40
|
+
All tables should have an unique tableName.
|
41
|
+
"""
|
42
|
+
|
43
|
+
def __init__(self, tables, tableName=None, volumeName=None, numberSlices=0):
|
44
|
+
self._tables = list(tables)
|
45
|
+
self._tableName = tableName
|
46
|
+
# FIXME: You have to see if the volumeName is used anywhere
|
47
|
+
self._volumeName = volumeName
|
48
|
+
self._numberSlices = numberSlices
|
49
|
+
self.projectPath = None
|
50
|
+
|
51
|
+
def currentTable(self):
|
52
|
+
""" Returns the name of the last selected table. """
|
53
|
+
return self._tableName
|
54
|
+
|
55
|
+
def setVolumeName(self, volumeName):
|
56
|
+
self._volumeName = volumeName
|
57
|
+
|
58
|
+
def getVolumeName(self):
|
59
|
+
return self._volumeName
|
60
|
+
|
61
|
+
def setNumberSlices(self, numberSlices):
|
62
|
+
self._numberSlices = numberSlices
|
63
|
+
|
64
|
+
def getNumberSlices(self):
|
65
|
+
return self._numberSlices
|
66
|
+
|
67
|
+
def getNumberSlicesForTemplate(self):
|
68
|
+
return range(self._numberSlices)
|
69
|
+
|
70
|
+
def listTables(self):
|
71
|
+
""" List the actual table names on the DataSet. """
|
72
|
+
return self._tables
|
73
|
+
|
74
|
+
def getTable(self, tableName=None):
|
75
|
+
if tableName is None:
|
76
|
+
tableName = self.listTables()[0]
|
77
|
+
if tableName not in self._tables:
|
78
|
+
raise Exception("DataSet: table '%s' not found.\n Current tables: %s" %
|
79
|
+
(tableName, self._tables))
|
80
|
+
|
81
|
+
table = self._loadTable(tableName)
|
82
|
+
self._tableName = tableName
|
83
|
+
|
84
|
+
return table
|
85
|
+
|
86
|
+
def getTypeOfColumn(self, label):
|
87
|
+
""" this method should be implemented by subclasses. """
|
88
|
+
pass
|
89
|
+
|
90
|
+
def _loadTable(self, tableName):
|
91
|
+
""" this method should be implemented by subclasses. """
|
92
|
+
pass
|
93
|
+
|
94
|
+
|
95
|
+
class Table(object):
|
96
|
+
""" Table to hold rows of data.
|
97
|
+
A table contains a list of columns. """
|
98
|
+
def __init__(self, *columns):
|
99
|
+
self._columns = OrderedDict()
|
100
|
+
self._rowDict = OrderedDict()
|
101
|
+
self._addColumn(Column('id', int))
|
102
|
+
|
103
|
+
for col in columns:
|
104
|
+
self._addColumn(col)
|
105
|
+
|
106
|
+
colNames = [col.getName() for col in self.iterColumns()]
|
107
|
+
# This imply that columns can only be added in __init__
|
108
|
+
self.Row = namedtuple('Row', colNames)
|
109
|
+
|
110
|
+
def setLabelToRender(self, labelToRender):
|
111
|
+
self._labelToRender = labelToRender
|
112
|
+
|
113
|
+
def _addColumn(self, col):
|
114
|
+
self._columns[col.getName()] = col
|
115
|
+
|
116
|
+
def getColumnValues(self, columnName):
|
117
|
+
if self.hasColumn(columnName):
|
118
|
+
return [getattr(row, columnName) for row in self.iterRows()]
|
119
|
+
else:
|
120
|
+
return [None] * self.getSize()
|
121
|
+
|
122
|
+
def iterColumns(self):
|
123
|
+
return self._columns.values()
|
124
|
+
|
125
|
+
def hasColumn(self, columnName):
|
126
|
+
""" Return true if column exists """
|
127
|
+
return columnName in self._columns
|
128
|
+
|
129
|
+
def getColumn(self, columnName):
|
130
|
+
if columnName not in self._columns:
|
131
|
+
raise Exception('Table: column "%s" not found.\nCurrent columns: %s' % (
|
132
|
+
columnName, '\n'.join(self._columns.keys())))
|
133
|
+
return self._columns[columnName]
|
134
|
+
|
135
|
+
def hasEnabledColumn(self):
|
136
|
+
""" Return true if enabled column exists """
|
137
|
+
return self.hasColumn('enabled')
|
138
|
+
|
139
|
+
def getColumns(self):
|
140
|
+
""" Return all columns. """
|
141
|
+
return self._columns.values()
|
142
|
+
|
143
|
+
def getNumberOfColumns(self):
|
144
|
+
return len(self._columns)
|
145
|
+
|
146
|
+
def getSize(self):
|
147
|
+
""" Return the number of rows. """
|
148
|
+
return len(self._rowDict)
|
149
|
+
|
150
|
+
def getRows(self):
|
151
|
+
""" Return all rows. """
|
152
|
+
return [row for row in self.iterRows()]
|
153
|
+
|
154
|
+
def getRow(self, rowId):
|
155
|
+
return self._rowDict[rowId]
|
156
|
+
|
157
|
+
def _setRow(self, rowId, row):
|
158
|
+
self._rowDict[rowId] = row
|
159
|
+
|
160
|
+
def getDataToRenderAndExtra(self):
|
161
|
+
return zip(self.getIdColumn(),
|
162
|
+
self.getColumnValues("enabled"),
|
163
|
+
self.getDataToRender(),
|
164
|
+
self.getTransformationMatrix())
|
165
|
+
|
166
|
+
def getDataToRender(self):
|
167
|
+
return self.getColumnValues(self._labelToRender)
|
168
|
+
|
169
|
+
def getIdColumn(self):
|
170
|
+
return self.getColumnValues("id")
|
171
|
+
|
172
|
+
def getTransformationMatrix(self):
|
173
|
+
return self.getColumnValues(self._labelToRender+"_transformationMatrix")
|
174
|
+
|
175
|
+
def _convertValues(self, values):
|
176
|
+
""" Convert the input values to the actual
|
177
|
+
expected type of each column.
|
178
|
+
"""
|
179
|
+
cValues = {}
|
180
|
+
for k, v in values.items():
|
181
|
+
col = self.getColumn(k)
|
182
|
+
cValues[k] = col.convert(v)
|
183
|
+
|
184
|
+
return cValues
|
185
|
+
|
186
|
+
def addRow(self, rowId, **values):
|
187
|
+
""" With this implementation the rowId should be provided.
|
188
|
+
We need to work around to also allow automatic generation of id's
|
189
|
+
"""
|
190
|
+
values['id'] = rowId
|
191
|
+
|
192
|
+
for col in self.iterColumns():
|
193
|
+
if col.getName() not in values:
|
194
|
+
if col.hasDefault():
|
195
|
+
values[col.getName()] = col.getDefault()
|
196
|
+
else:
|
197
|
+
raise Exception('Table: value for column "%s" not provided.' % col.getName())
|
198
|
+
|
199
|
+
row = self.Row(**self._convertValues(values))
|
200
|
+
self._setRow(rowId, row)
|
201
|
+
|
202
|
+
def updateRow(self, rowId, **values):
|
203
|
+
""" Update a row given its rowId and some values to update. """
|
204
|
+
row = self.getRow(rowId)
|
205
|
+
self._setRow(rowId, row._replace(**self._convertValues(values)))
|
206
|
+
|
207
|
+
def iterRows(self):
|
208
|
+
""" Iterate over the rows. """
|
209
|
+
return self._rowDict.values()
|
210
|
+
|
211
|
+
def getValueFromIndex(self, index, label):
|
212
|
+
""" Return the value of the property 'label'
|
213
|
+
in the element that has this 'index'.
|
214
|
+
"""
|
215
|
+
value = list(self._rowDict.values())[index]._asdict()[label]
|
216
|
+
return value
|
217
|
+
|
218
|
+
def getIndexFromValue(self, value, label):
|
219
|
+
""" Search the element that has property 'label'
|
220
|
+
equals to value and returns its index.
|
221
|
+
"""
|
222
|
+
for index, row in enumerate(self.iterRows()):
|
223
|
+
if value == row._asdict()[label]:
|
224
|
+
return index
|
225
|
+
return -1
|
226
|
+
|
227
|
+
def __str__(self):
|
228
|
+
return '\n'.join([str(row) for row in self.iterRows()])
|
229
|
+
|
230
|
+
|
231
|
+
# JMRT (2018-12-11) This constants are duplicated in showj, since this module
|
232
|
+
# is not widely used I don't find convenient such a dependency
|
233
|
+
COL_RENDER_NONE = 0
|
234
|
+
COL_RENDER_ID = 1
|
235
|
+
COL_RENDER_TEXT = 2
|
236
|
+
COL_RENDER_IMAGE = 3
|
237
|
+
COL_RENDER_CHECKBOX = 4
|
238
|
+
COL_RENDER_VOLUME = 5
|
239
|
+
|
240
|
+
|
241
|
+
class Column(object):
|
242
|
+
def __init__(self, colName, colType=None, default=None,
|
243
|
+
label=None, renderType=COL_RENDER_NONE):
|
244
|
+
self._name = colName
|
245
|
+
self._type = colType
|
246
|
+
self._default = default
|
247
|
+
self._label = label or colName
|
248
|
+
self._renderType = renderType
|
249
|
+
|
250
|
+
def getName(self):
|
251
|
+
return self._name
|
252
|
+
|
253
|
+
def getLabel(self):
|
254
|
+
return self._label
|
255
|
+
|
256
|
+
def getType(self):
|
257
|
+
return self._type
|
258
|
+
|
259
|
+
def convert(self, value):
|
260
|
+
""" Try to convert the value to the column type. """
|
261
|
+
return self._type(value)
|
262
|
+
|
263
|
+
def hasDefault(self):
|
264
|
+
return self._default is not None
|
265
|
+
|
266
|
+
def getDefault(self):
|
267
|
+
return self._default
|
268
|
+
|
269
|
+
def getRenderType(self):
|
270
|
+
return self._renderType
|
271
|
+
|
272
|
+
def setRenderType(self, renderType):
|
273
|
+
self._renderType = renderType
|
274
|
+
|
275
|
+
|
276
|
+
class SqliteDataSet(DataSet):
|
277
|
+
""" Provide a DataSet implementation based on sqlite file.
|
278
|
+
The tables of the dataset will be the object tables in database.
|
279
|
+
Each block is a table on the dataset.
|
280
|
+
"""
|
281
|
+
|
282
|
+
def __init__(self, filename):
|
283
|
+
self._dbName = filename
|
284
|
+
db = SqliteDb()
|
285
|
+
db._createConnection(filename, 1000)
|
286
|
+
# Tables should be at pairs:
|
287
|
+
# PREFIX_Classes
|
288
|
+
# PREFIX_Objects
|
289
|
+
# where PREFIX can be empty
|
290
|
+
self.tablePrefixes = OrderedDict()
|
291
|
+
tables = db.getTables()
|
292
|
+
for t in tables:
|
293
|
+
if t.endswith('Classes'):
|
294
|
+
prefix = t.replace('Classes', '')
|
295
|
+
to = prefix + 'Objects'
|
296
|
+
if to not in tables:
|
297
|
+
raise Exception('SqliteDataSet: table "%s" found, but not "%s"' % (t, to))
|
298
|
+
flatDb = SqliteFlatDb(filename, tablePrefix=prefix)
|
299
|
+
tableName = prefix + self._getPlural(flatDb.getSelfClassName())
|
300
|
+
self.tablePrefixes[tableName] = prefix
|
301
|
+
# tablePrefixes.append(prefix)
|
302
|
+
DataSet.__init__(self, self.tablePrefixes.keys())
|
303
|
+
db.close()
|
304
|
+
|
305
|
+
def _getPlural(self, className):
|
306
|
+
""" Get the plural of word for tables labels. """
|
307
|
+
if className.startswith('Class'):
|
308
|
+
return className.replace('Class', 'Classes')
|
309
|
+
return className + 's'
|
310
|
+
|
311
|
+
def _loadTable(self, tableName):
|
312
|
+
""" Load information from tables PREFIX_Classes, PREFIX_Objects. """
|
313
|
+
|
314
|
+
tableName = self.tablePrefixes[tableName]
|
315
|
+
|
316
|
+
BASIC_COLUMNS = [Column('id', int, renderType=COL_RENDER_ID),
|
317
|
+
Column('enabled', bool, renderType=COL_RENDER_CHECKBOX),
|
318
|
+
Column('label', str),
|
319
|
+
Column('comment', str),
|
320
|
+
Column('creation', str)]
|
321
|
+
# Load columns from PREFIX_Classes table
|
322
|
+
columns = list(BASIC_COLUMNS)
|
323
|
+
db = SqliteDb()
|
324
|
+
db._createConnection(self._dbName, 1000)
|
325
|
+
db.executeCommand("SELECT * FROM %sClasses;" % tableName)
|
326
|
+
# This will store the images columns to join
|
327
|
+
# the _index and the _filename
|
328
|
+
imgCols = {}
|
329
|
+
for row in db._iterResults():
|
330
|
+
renderType = COL_RENDER_NONE
|
331
|
+
colName = row['column_name']
|
332
|
+
colLabel = row['label_property']
|
333
|
+
|
334
|
+
if colLabel != 'self':
|
335
|
+
# Keep track of _index and _filename pairs to mark as renderable images
|
336
|
+
if colLabel.endswith('_index'):
|
337
|
+
imgCols[colLabel.replace('_index', '')] = colName
|
338
|
+
|
339
|
+
elif colLabel.endswith('_filename'):
|
340
|
+
|
341
|
+
# TODO: Maybe not all the labels endswith "_filename"
|
342
|
+
# have to be rendered.
|
343
|
+
# for example in the RotSpectra with '_representative._filename'
|
344
|
+
|
345
|
+
prefix = colLabel.replace('_filename', '')
|
346
|
+
if prefix in imgCols:
|
347
|
+
renderType = COL_RENDER_IMAGE
|
348
|
+
imgCols[colName] = imgCols[prefix]
|
349
|
+
|
350
|
+
# CTF FIX
|
351
|
+
elif (colLabel.endswith('_psdFile') or
|
352
|
+
colLabel.endswith('_enhanced_psd') or
|
353
|
+
colLabel.endswith('_ctfmodel_quadrant') or
|
354
|
+
colLabel.endswith('_ctfmodel_halfplane')):
|
355
|
+
|
356
|
+
renderType = COL_RENDER_IMAGE
|
357
|
+
|
358
|
+
if row['class_name'] == 'Boolean':
|
359
|
+
renderType = COL_RENDER_CHECKBOX
|
360
|
+
columns.append(Column(colName, str, label=colLabel, renderType=renderType))
|
361
|
+
table = Table(*columns)
|
362
|
+
|
363
|
+
checkedImgCols = {} # Check if the image columns are volumes
|
364
|
+
# FIXME: Move this to scipion-em? Maybe remove the whole module that is not used?
|
365
|
+
from pwem.emlib.image import ImageHandler
|
366
|
+
ih = ImageHandler()
|
367
|
+
|
368
|
+
# Populate the table in the DataSet
|
369
|
+
db.executeCommand("SELECT * FROM %sObjects;" % tableName)
|
370
|
+
for row in db._iterResults():
|
371
|
+
rowDict = dict(row)
|
372
|
+
for k, v in rowDict.items():
|
373
|
+
if v is None:
|
374
|
+
rowDict[k] = ''
|
375
|
+
# Set the index@filename for images columns values
|
376
|
+
if k in imgCols:
|
377
|
+
colName = imgCols[k]
|
378
|
+
index = rowDict[colName]
|
379
|
+
|
380
|
+
filename = os.path.join(self.projectPath, rowDict[k])
|
381
|
+
filepath = filename.replace(":mrc", "")
|
382
|
+
if not checkedImgCols.get(colName, False):
|
383
|
+
if os.path.exists(filepath):
|
384
|
+
# print "Fn to get dims: %s@%s" % (index,filename)
|
385
|
+
x, y, z, n = ih.getDimensions((index, filename))
|
386
|
+
if z > 1:
|
387
|
+
table.getColumn(k).setRenderType(COL_RENDER_VOLUME)
|
388
|
+
checkedImgCols[colName] = True
|
389
|
+
if index:
|
390
|
+
rowDict[k] = '%06d@%s' % (index, filename)
|
391
|
+
table.addRow(row['id'], **rowDict)
|
392
|
+
|
393
|
+
return table
|
394
|
+
|
395
|
+
|
396
|
+
class SingleFileDataSet(DataSet):
|
397
|
+
""" DataSet implementation for single files such as Images or Volumes.
|
398
|
+
"""
|
399
|
+
|
400
|
+
def __init__(self, filename):
|
401
|
+
self._filename = filename
|
402
|
+
self._tableName = ""
|
403
|
+
DataSet.__init__(self, [self._tableName])
|
404
|
+
self._table = self._createSingleTable()
|
405
|
+
|
406
|
+
def _createSingleTable(self):
|
407
|
+
table = Table(Column('filename', str,
|
408
|
+
renderType=COL_RENDER_VOLUME)) # FIXME: for single images we need to read the dimensions
|
409
|
+
table.addRow(1, filename=self._filename)
|
410
|
+
|
411
|
+
return table
|
412
|
+
|
413
|
+
def _loadTable(self, tableName):
|
414
|
+
return self._table
|
pyworkflow/utils/echo.py
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# **************************************************************************
|
2
|
+
# *
|
3
|
+
# * Authors: J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es)
|
4
|
+
# *
|
5
|
+
# * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
|
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, write to the Free Software
|
19
|
+
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
20
|
+
# * 02111-1307 USA
|
21
|
+
# *
|
22
|
+
# * All comments concerning this program package may be sent to the
|
23
|
+
# * e-mail address 'scipion@cnb.csic.es'
|
24
|
+
# *
|
25
|
+
# **************************************************************************
|
26
|
+
"""
|
27
|
+
This module trace through printing
|
28
|
+
module and class functions...
|
29
|
+
Code from: http://wordaligned.org/articles/echo
|
30
|
+
"""
|
31
|
+
|
32
|
+
|
33
|
+
import inspect
|
34
|
+
import sys
|
35
|
+
|
36
|
+
|
37
|
+
def name(item):
|
38
|
+
""" Return an item's name. """
|
39
|
+
return item.__name__
|
40
|
+
|
41
|
+
|
42
|
+
def is_classmethod(instancemethod):
|
43
|
+
""" Determine if an instancemethod is a classmethod. """
|
44
|
+
return instancemethod.im_self is not None
|
45
|
+
|
46
|
+
|
47
|
+
def is_class_private_name(name):
|
48
|
+
""" Determine if a name is a class private name. """
|
49
|
+
# Exclude system defined names such as __init__, __add__ etc
|
50
|
+
return name.startswith("__") and not name.endswith("__")
|
51
|
+
|
52
|
+
|
53
|
+
def method_name(method):
|
54
|
+
""" Return a method's name.
|
55
|
+
|
56
|
+
This function returns the name the method is accessed by from
|
57
|
+
outside the class (i.e. it prefixes "private" methods appropriately).
|
58
|
+
"""
|
59
|
+
mname = name(method)
|
60
|
+
if is_class_private_name(mname):
|
61
|
+
mname = "_%s%s" % (name(method.im_class), mname)
|
62
|
+
return mname
|
63
|
+
|
64
|
+
|
65
|
+
def format_args(args):
|
66
|
+
print(args)
|
67
|
+
|
68
|
+
|
69
|
+
def echo(fn, write=sys.stdout.write):
|
70
|
+
print(fn)
|
71
|
+
|
72
|
+
|
73
|
+
def echo_instancemethod(klass, method, write=sys.stdout.write):
|
74
|
+
""" Change an instancemethod so that calls to it are echoed.
|
75
|
+
|
76
|
+
Replacing a classmethod is a little more tricky.
|
77
|
+
See: http://www.python.org/doc/current/ref/types.html
|
78
|
+
"""
|
79
|
+
mname = method_name(method)
|
80
|
+
never_echo = "__str__", "__repr__", # Avoid recursion printing method calls
|
81
|
+
if mname in never_echo:
|
82
|
+
pass
|
83
|
+
elif is_classmethod(method):
|
84
|
+
setattr(klass, mname, classmethod(echo(method.im_func, write)))
|
85
|
+
else:
|
86
|
+
setattr(klass, mname, echo(method, write))
|
87
|
+
|
88
|
+
|
89
|
+
def echo_class(klass, write=sys.stdout.write):
|
90
|
+
""" Echo calls to class methods and static functions
|
91
|
+
"""
|
92
|
+
for _, method in inspect.getmembers(klass, inspect.ismethod):
|
93
|
+
echo_instancemethod(klass, method, write)
|
94
|
+
for _, fn in inspect.getmembers(klass, inspect.isfunction):
|
95
|
+
setattr(klass, name(fn), staticmethod(echo(fn, write)))
|
96
|
+
|
97
|
+
|
98
|
+
def echo_module(mod, write=sys.stdout.write):
|
99
|
+
""" Echo calls to functions and methods in a module.
|
100
|
+
"""
|
101
|
+
for fname, fn in inspect.getmembers(mod, inspect.isfunction):
|
102
|
+
setattr(mod, fname, echo(fn, write))
|
103
|
+
for _, klass in inspect.getmembers(mod, inspect.isclass):
|
104
|
+
echo_class(klass, write)
|