scipion-pyworkflow 3.8.0__py3-none-any.whl → 3.9.1__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.
Files changed (38) hide show
  1. pyworkflow/config.py +8 -2
  2. pyworkflow/constants.py +6 -1
  3. pyworkflow/gui/canvas.py +6 -6
  4. pyworkflow/gui/dialog.py +3 -2
  5. pyworkflow/gui/form.py +12 -2
  6. pyworkflow/gui/graph.py +6 -6
  7. pyworkflow/gui/graph_layout.py +2 -2
  8. pyworkflow/gui/project/base.py +7 -7
  9. pyworkflow/gui/project/project.py +36 -28
  10. pyworkflow/gui/project/steps.py +8 -3
  11. pyworkflow/gui/project/viewdata.py +1 -1
  12. pyworkflow/gui/project/viewprotocols.py +9 -9
  13. pyworkflow/gui/project/viewprotocols_extra.py +3 -3
  14. pyworkflow/gui/widgets.py +2 -2
  15. pyworkflow/mapper/sqlite.py +5 -5
  16. pyworkflow/object.py +1 -1
  17. pyworkflow/plugin.py +1 -0
  18. pyworkflow/project/config.py +4 -1
  19. pyworkflow/project/manager.py +4 -3
  20. pyworkflow/project/project.py +37 -21
  21. pyworkflow/project/scripts/create.py +14 -4
  22. pyworkflow/project/scripts/schedule.py +1 -1
  23. pyworkflow/protocol/constants.py +1 -0
  24. pyworkflow/protocol/executor.py +133 -19
  25. pyworkflow/protocol/params.py +5 -8
  26. pyworkflow/protocol/protocol.py +36 -36
  27. pyworkflow/template.py +1 -1
  28. pyworkflow/utils/graph.py +24 -51
  29. pyworkflow/utils/properties.py +16 -12
  30. pyworkflowtests/protocols.py +3 -3
  31. pyworkflowtests/tests/test_protocol_execution.py +63 -0
  32. {scipion_pyworkflow-3.8.0.dist-info → scipion_pyworkflow-3.9.1.dist-info}/METADATA +1 -1
  33. {scipion_pyworkflow-3.8.0.dist-info → scipion_pyworkflow-3.9.1.dist-info}/RECORD +38 -38
  34. {scipion_pyworkflow-3.8.0.dist-info → scipion_pyworkflow-3.9.1.dist-info}/WHEEL +1 -1
  35. {scipion_pyworkflow-3.8.0.dist-info → scipion_pyworkflow-3.9.1.dist-info}/LICENSE.txt +0 -0
  36. {scipion_pyworkflow-3.8.0.dist-info → scipion_pyworkflow-3.9.1.dist-info}/dependency_links.txt +0 -0
  37. {scipion_pyworkflow-3.8.0.dist-info → scipion_pyworkflow-3.9.1.dist-info}/entry_points.txt +0 -0
  38. {scipion_pyworkflow-3.8.0.dist-info → scipion_pyworkflow-3.9.1.dist-info}/top_level.txt +0 -0
pyworkflow/utils/graph.py CHANGED
@@ -26,6 +26,8 @@
26
26
  """
27
27
  This module define a Graph class and some utilities
28
28
  """
29
+ import logging
30
+ logger = logging.getLogger(__name__)
29
31
 
30
32
 
31
33
  class Node(object):
@@ -33,7 +35,7 @@ class Node(object):
33
35
  _count = 1
34
36
 
35
37
  def __init__(self, name=None, label=None):
36
- self._childs = []
38
+ self._children = []
37
39
  self._parents = []
38
40
 
39
41
  if name is None:
@@ -44,6 +46,7 @@ class Node(object):
44
46
  if label is None:
45
47
  label = name
46
48
  self._label = label
49
+ self._fixed = False
47
50
 
48
51
  def getName(self):
49
52
  return self._name
@@ -57,13 +60,13 @@ class Node(object):
57
60
  def isRoot(self):
58
61
  return len(self._parents) == 0
59
62
 
60
- def getChilds(self):
61
- return self._childs
63
+ def getChildren(self):
64
+ return self._children
62
65
 
63
66
  def addChild(self, *nodes):
64
67
  for n in nodes:
65
- if n not in self._childs:
66
- self._childs.append(n)
68
+ if n not in self._children:
69
+ self._children.append(n)
67
70
  n._parents.append(self)
68
71
 
69
72
  def getParent(self):
@@ -78,36 +81,36 @@ class Node(object):
78
81
  def getParents(self):
79
82
  return self._parents
80
83
 
81
- def iterChilds(self):
82
- """ Iterate over all childs and subchilds.
83
- Nodes can be visited more than once if have
84
+ def iterChildren(self):
85
+ """ Iterate over all children and sub-children.
86
+ Nodes can be visited more than once if it has
84
87
  more than one parent.
85
88
  """
86
- for child in self._childs:
87
- for c in child.iterChilds():
89
+ for child in self._children:
90
+ for c in child.iterChildren():
88
91
  yield c
89
92
 
90
93
  yield self
91
94
 
92
- def countChilds(self, visitedNode=None, count=0):
95
+ def countChildren(self, visitedNode=None, count=0):
93
96
  """ Iterate over all childs and subchilds.
94
97
  Nodes can be visited once
95
98
  """
96
- for child in self._childs:
99
+ for child in self._children:
97
100
  if child._name not in visitedNode:
98
101
  visitedNode[child._name] = True
99
- child.countChilds(visitedNode)
102
+ child.countChildren(visitedNode)
100
103
  return len(visitedNode)
101
104
 
102
105
 
103
- def iterChildsBreadth(self):
106
+ def iterChildrenBreadth(self):
104
107
  """ Iter child nodes in a breadth-first order
105
108
  """
106
- for child in self._childs:
109
+ for child in self._children:
107
110
  yield child
108
111
 
109
- for child in self._childs:
110
- for child2 in child.iterChildsBreadth():
112
+ for child in self._children:
113
+ for child2 in child.iterChildrenBreadth():
111
114
  yield child2
112
115
 
113
116
  def __str__(self):
@@ -133,13 +136,13 @@ class Graph(object):
133
136
  def _registerNode(self, node):
134
137
  self._nodes.append(node)
135
138
  self._nodesDict[node.getName()] = node
136
- for child in node.getChilds():
139
+ for child in node.getChildren():
137
140
  self._registerNode(child)
138
141
 
139
- def getRoot(self):
142
+ def getRoot(self) -> Node:
140
143
  return self._root
141
144
 
142
- def createNode(self, nodeName, nodeLabel=None):
145
+ def createNode(self, nodeName, nodeLabel=None) -> Node:
143
146
  """ Add a node to the graph """
144
147
  node = Node(nodeName, nodeLabel)
145
148
  self._registerNode(node)
@@ -150,7 +153,7 @@ class Graph(object):
150
153
  """ Register an alias name for the node. """
151
154
  self._nodesDict[aliasName] = node
152
155
 
153
- def getNode(self, nodeName):
156
+ def getNode(self, nodeName) -> Node:
154
157
  return self._nodesDict.get(nodeName, None)
155
158
 
156
159
  def getNodeNames(self):
@@ -164,33 +167,3 @@ class Graph(object):
164
167
  """ Return all nodes that have no parent. """
165
168
  return [n for n in self._nodes if n.isRoot()]
166
169
 
167
- def printNodes(self):
168
- for node in self.getNodes():
169
- print("Node: ", node)
170
- print(" Childs: ", ','.join([c.getLabel()
171
- for c in node.getChilds()]))
172
-
173
- def _escape(self, label):
174
- return label.replace('.', '_').replace(' ', '_').replace('-', '_').replace('___', '_')
175
-
176
- def printDot(self, useId=True):
177
- """ If useId is True, use the node id for label the graph.
178
- If not, use the run name.
179
- """
180
-
181
- def getLabel(node):
182
- if useId:
183
- return node.getName()
184
- else:
185
- return node.getLabel()
186
-
187
- dotStr = "\ndigraph {\n"
188
-
189
- for node in self.getNodes():
190
- for child in node.getChilds():
191
- nodeLabel = self._escape(getLabel(node))
192
- childLabel = self._escape(getLabel(child))
193
- dotStr += " %s -> %s;\n" % (nodeLabel, childLabel)
194
- dotStr += "}"
195
- print(dotStr)
196
- return dotStr
@@ -29,7 +29,7 @@
29
29
  This module defines the text used in the application.
30
30
  """
31
31
  # NOTE: DO NOT REMOVE UNTIL plugin manager uses Config.SCIPION_MAIN_COLOR and is released
32
- from pyworkflow.constants import Color
32
+ from pyworkflow.constants import Color, DOCSITEURLS
33
33
  from PIL import Image
34
34
 
35
35
  class Message:
@@ -124,6 +124,7 @@ class Message:
124
124
  LABEL_PARALLEL = 'Parallel'
125
125
  LABEL_HOST = 'Host'
126
126
  LABEL_THREADS = 'Threads'
127
+ LABEL_SCIPION_THREADS = 'Scipion threads'
127
128
  LABEL_MPI = 'MPI'
128
129
  LABEL_QUEUE = 'Use a queue engine?'
129
130
 
@@ -140,18 +141,21 @@ Each step could be computationally intensive, that's why
140
141
  the *Continue* execution mode will try to continue from the
141
142
  last completed step. On the other hand, the *Restart* mode
142
143
  will clean the whole run directory and start from scratch.
143
- """
144
-
145
- HELP_MPI_THREADS = """
146
- Define the number of processors to be used in the execution.
147
- *MPI*: This is a number of independent processes
148
- that communicate through message passing
149
- over the network (or the same computer).
150
- *Threads*: This refers to different execution threads
151
- in the same process that can share memory. They run in
152
- the same computer.
153
144
  """
154
145
 
146
+ HELP_PARALLEL_HEADER = 'Define the number of processors to be used in the execution.\nCheck %s for more detailed info.\n\n' % DOCSITEURLS.THREADS_MPIS_AND_GPUS
147
+ HELP_PARALLEL_MPI = ("*MPI*:\nThis is a number of independent processes"
148
+ " that communicate through message passing "
149
+ "over the network (or the same computer).\n")
150
+ HELP_PARALLEL_THREADS = ("*Threads*:\nThis refers to different execution threads in the same process that "
151
+ "can share memory. They run in the same computer. This value is an argument"
152
+ " passed to the program integrated")
153
+
154
+ HELP_SCIPION_THREADS = ("*Scipion threads*:\n threads created by Scipion to run the steps."
155
+ " 1 thread is always used by the master/main process. Then extra threads will allow"
156
+ " this protocol to run several steps at the same time, taking always into account "
157
+ "restrictions to previous steps and 'theoretical GPU availability'")
158
+
155
159
  HELP_USEQUEUE = """
156
160
  Click Yes if you want to send this execution to a queue engine like Slurm, Torque, ...
157
161
  The queue commands to launch and stop jobs should be configured at
@@ -446,7 +450,7 @@ class Sprite:
446
450
  @classmethod
447
451
  def getSpritesFile(cls):
448
452
  from pyworkflow import Config
449
- return Config.SCIPION_SPRITES_FILE
453
+ return Config.getSpritesFile()
450
454
  @classmethod
451
455
  def loadSprites(cls):
452
456
  """ Loads the image of the sprite"""
@@ -55,16 +55,16 @@ class SleepingProtocol(pwprot.Protocol):
55
55
  def _insertAllSteps(self):
56
56
  print("Inserting all steps...")
57
57
  for i in range(self.numberOfSleeps.get()):
58
- self._insertFunctionStep('sleepStep', i + 1)
58
+ self._insertFunctionStep(self.sleepStep, i + 1)
59
59
 
60
60
 
61
61
  class ParallelSleepingProtocol(SleepingProtocol):
62
62
  def _insertAllSteps(self):
63
- step1 = self._insertFunctionStep('sleepStep', 1)
63
+ step1 = self._insertFunctionStep(self.sleepStep, 1)
64
64
  n = 2
65
65
  deps = [step1]
66
66
  for i in range(n):
67
- self._insertFunctionStep('sleepStep')
67
+ self._insertFunctionStep(self.sleepStep)
68
68
 
69
69
  class ConcurrencyProtocol(SleepingProtocol):
70
70
  """ Protocol to test concurrency access to sets"""
@@ -22,11 +22,13 @@
22
22
  # * e-mail address 'scipion@cnb.csic.es'
23
23
  # *
24
24
  # **************************************************************************
25
+ import threading
25
26
 
26
27
  import pyworkflow.tests as pwtests
27
28
  import pyworkflow.mapper as pwmapper
28
29
  import pyworkflow.protocol as pwprot
29
30
  from pyworkflow.project import Project
31
+ from pyworkflow.protocol.constants import VOID_GPU
30
32
 
31
33
 
32
34
  # TODO: this test seems not to be finished.
@@ -70,3 +72,64 @@ class TestProtocolExecution(pwtests.BaseTest):
70
72
  prot2 = mapper2.selectById(prot.getObjId())
71
73
 
72
74
  self.assertEqual(prot.endTime.get(), prot2.endTime.get())
75
+
76
+ def test_gpuSlots(self):
77
+ """ Test gpu slots are properly composed in combination of threads"""
78
+
79
+ # Test basic GPU setu methods
80
+ stepExecutor = pwprot.ThreadStepExecutor(None, 1, gpuList=None)
81
+
82
+
83
+ self.assertEqual(stepExecutor.cleanVoidGPUs([0,1]), [0,1],
84
+ "CleanVoidGpus does not work in absence of void GPUS")
85
+
86
+ self.assertEqual(stepExecutor.cleanVoidGPUs([0, VOID_GPU]), [0],
87
+ "CleanVoidGpus does not work with a void GPU")
88
+
89
+ self.assertEqual(stepExecutor.cleanVoidGPUs([VOID_GPU, VOID_GPU]), [],
90
+ "CleanVoidGpus does not work with all void GPU")
91
+
92
+
93
+ currThread = threading.currentThread()
94
+ currThread.thId = 1
95
+ self.assertEqual(stepExecutor.getGpuList(),[], "Gpu list should be empty")
96
+
97
+ # 2 threads 1 GPU
98
+ stepExecutor = pwprot.ThreadStepExecutor(None, 2, gpuList=[1])
99
+ self.assertEqual(stepExecutor.getGpuList(),[1], "Gpu list should be [1]")
100
+
101
+ currThread.thId = 2
102
+ self.assertEqual(stepExecutor.getGpuList(),[], "Gpu list should be empty after a second request")
103
+
104
+
105
+ # 2 threads 3 GPUs
106
+ stepExecutor = pwprot.ThreadStepExecutor(None, 2, gpuList=[0,1,2])
107
+ self.assertEqual(stepExecutor.getGpuList(),[0,1], "Gpu list should be [0,1]")
108
+
109
+ currThread.thId = 1
110
+ self.assertEqual(stepExecutor.getGpuList(),[2], "Gpu list should be [2] after a second request")
111
+
112
+
113
+ # 2 threads 4 GPUs with void gpus
114
+ stepExecutor = pwprot.ThreadStepExecutor(None, 2, gpuList=[0,1,2, VOID_GPU])
115
+ self.assertEqual(stepExecutor.getGpuList(),[0,1], "Gpu list should be [0,1]")
116
+
117
+ currThread.thId = 2
118
+ self.assertEqual(stepExecutor.getGpuList(),[2], "Gpu list should be [2] after a second request without the void gpu")
119
+
120
+ # less GPUs than threads. No extension should happen
121
+ stepExecutor = pwprot.ThreadStepExecutor(None, 4, gpuList=[0, VOID_GPU, 2])
122
+ self.assertEqual(stepExecutor.getGpuList(), [0], "Gpu list should not be extended")
123
+
124
+ currThread.thId = 1
125
+ self.assertEqual(stepExecutor.getGpuList(), [2],
126
+ "Gpu list should be [2] after a second request, skipping the VOID gpu")
127
+
128
+ currThread.thId = 3
129
+ self.assertEqual(stepExecutor.getGpuList(), [], "Gpu list should be empty ather all GPU slots are busy")
130
+
131
+
132
+
133
+
134
+
135
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: scipion-pyworkflow
3
- Version: 3.8.0
3
+ Version: 3.9.1
4
4
  Summary: Simple workflow platform used in scientific applications, initially developed within the Scipion framework for image processing in Electron Microscopy.
5
5
  Home-page: https://github.com/scipion-em/scipion-pyworkflow
6
6
  Author: J.M. De la Rosa Trevin, Roberto Marabini, Grigory Sharov, Josue Gomez Blanco, Pablo Conesa, Yunior Fonseca Reyna
@@ -1,10 +1,10 @@
1
1
  pyworkflow/__init__.py,sha256=Wr-MVKMQJy_Cy-rpPPB0-pyv8-8tx7GPPaLSNBrV1AI,1246
2
- pyworkflow/config.py,sha256=a6TyBwKFvq79dQMamA4D5dPULWfSKfIBbsRT4NdlA94,22048
3
- pyworkflow/constants.py,sha256=LEuEXv7rXBSl2YyTQ27X4iK4-NJYPHWi3ibLXkt4F1k,7319
2
+ pyworkflow/config.py,sha256=_sq6YCRfcfE4WUNXLShgbICbBeTSLpD2KmPVapR1Wos,22306
3
+ pyworkflow/constants.py,sha256=nBscFi3ZRqUZA6daTMWVM2_xbStXn98BNC659zN_UNM,7447
4
4
  pyworkflow/exceptions.py,sha256=3VFxuNJHcIWxRnLPR0vYg0RFAQMmxPBJZLZSi87VI8E,507
5
- pyworkflow/object.py,sha256=D5pLvHezEIXB1J_Lxc1CXF_s5ZEZ1r-pj1QAI1CQL24,55070
6
- pyworkflow/plugin.py,sha256=wl1n-qxBZitm5CHm6uiUIp99eOv6TxxRKLxygxcK1KM,28805
7
- pyworkflow/template.py,sha256=JtdK2AKgaAdu-SuovqNqn5W-ojmtw3SfaP2bOzSy_IA,10460
5
+ pyworkflow/object.py,sha256=yX3tBUuBssCI8aWGlTmyEKzFE59dJq_7NqllouVzMk0,55069
6
+ pyworkflow/plugin.py,sha256=JJm5plPyOnPAR4To6I5rXVIBda-1Dg-53zicdnLSrac,28858
7
+ pyworkflow/template.py,sha256=uScWMZCR3U6ishDlx7QGDDr8B_aLpKXoh8zOhqAirCY,10463
8
8
  pyworkflow/viewer.py,sha256=vA6VxYuxmCwMjIxCIdrp_G-R-nVo-0TA8p1rSl24EOY,11386
9
9
  pyworkflow/wizard.py,sha256=nXuk_qMUVlQNa6nB6GCt0CoFQ_P2dnJbGWdwtpDG2tQ,2633
10
10
  pyworkflow/apps/__init__.py,sha256=doupoWHiPmpEwa7o7ro7suxYYjj7h-912kc-fxwnhfE,1187
@@ -20,59 +20,59 @@ pyworkflow/apps/pw_sync_data.py,sha256=rwAShzTuVlCDaLKMLeuY1cPSLyWSP9-1mNTgIgCX4
20
20
  pyworkflow/apps/pw_viewer.py,sha256=dlvIPzBa_citucezBd0Cl0uCND4eXWYgXF-lZpXWzBc,2595
21
21
  pyworkflow/gui/__init__.py,sha256=D7PVYky81yTcqvkGEtw1CIxRkICpsn4TO5z5lJg84yM,1373
22
22
  pyworkflow/gui/browser.py,sha256=Be4keeCLl32t5HzrqOdMhk_6oJ93Q5WX5FKy8iO9hYU,25590
23
- pyworkflow/gui/canvas.py,sha256=UXJvAZO1BDbDEUwn-o9S5dEY9zi-tg3eidpV3edVKPU,42094
24
- pyworkflow/gui/dialog.py,sha256=HMtS3hD9VmfmGGH3mp8OJHD5FkUQ3en4DHLXKXdG0hw,35260
25
- pyworkflow/gui/form.py,sha256=wwldS8YDCT_z5Ixi9N_Oed1hfEJT1hpaqDzUDgNyx-k,103714
26
- pyworkflow/gui/graph.py,sha256=t1NwCr8dJxCr8iSQRB-HT3jwG9x_t8ryM5i2WnGY45E,8735
27
- pyworkflow/gui/graph_layout.py,sha256=imsZibqNj_5JfRq70PLvWoZ-VNZeMTMnxyRpz7SNey4,9516
23
+ pyworkflow/gui/canvas.py,sha256=M_pD7QbqnYq9MY145WN6BYzeIAo0cIkbxLrZKNE80yg,42106
24
+ pyworkflow/gui/dialog.py,sha256=35YpyOmUsmiVqdjU-k4AFDG7PKq0te4AUR-oTofhxEk,35329
25
+ pyworkflow/gui/form.py,sha256=ho_HeqB4e4lPaM1WclVYzfYYMpnwZm_xYCRrlXDQf0E,104000
26
+ pyworkflow/gui/graph.py,sha256=HSZ5PfFKkhv3tzl0o9UtSU_FfDevKR2M3L9HgU9_Gkc,8747
27
+ pyworkflow/gui/graph_layout.py,sha256=R9uTc_Ei4oWAeCkZ3d78JjC1QKV7HPJaDLyhvSfK7NE,9520
28
28
  pyworkflow/gui/gui.py,sha256=pEtBYo0bf5grDX8e6Ju920aSDGiWno85pxrSxcMrSTY,20627
29
29
  pyworkflow/gui/matplotlib_image.py,sha256=vGD5LKp-AZvu_kXa7Mf_jtOQfZ-QcRUoTMnicNrMqUk,7821
30
30
  pyworkflow/gui/plotter.py,sha256=E9ld43B-AzYhV1PIEPBy2TQWyzoia4y5lD5rqJOQlZY,8464
31
31
  pyworkflow/gui/text.py,sha256=cmAhCm_gCJMi5UDl9br8FoexHeDQjby8dplw9ZiUIgM,28576
32
32
  pyworkflow/gui/tooltip.py,sha256=OceYHesQQ7vSH7FRJmbvDBXjVG1IKkX1A8vocb64ljE,8531
33
33
  pyworkflow/gui/tree.py,sha256=TglyZ-snZHp6hTIRRp4o5Fvzf8Z7hogpFaZ4DVgMGvo,23084
34
- pyworkflow/gui/widgets.py,sha256=LK61vmojXUKL-M72rkRdN_TlurDTqiZOMeRDRa0KI08,11141
34
+ pyworkflow/gui/widgets.py,sha256=Zz69960wUO_Lu0_37j_IcUTTN70XiF_XKu5f2hoOx7g,11137
35
35
  pyworkflow/gui/project/__init__.py,sha256=rZmTvqocYhsD2PH1owu7Dkgs7dMrGx7VbKOCpaqvLzM,1118
36
- pyworkflow/gui/project/base.py,sha256=rr6hFRZ8N_ey0smw_UePDlk1prMWBRmQJ-hZUyV-MSs,8045
36
+ pyworkflow/gui/project/base.py,sha256=N64UXy5ep7RFweyBWTDro9UESgKRRAIvlRuotWIaO_w,7871
37
37
  pyworkflow/gui/project/constants.py,sha256=rORDaNCdAFRFcBmjRt2PJ1cXpSmYgDLfbvrbqZh1Bb0,4943
38
38
  pyworkflow/gui/project/labels.py,sha256=7m4heNcN3zXe0BHuFJyQrPD5hC8LiHnlu1sizRc8l_Y,7680
39
- pyworkflow/gui/project/project.py,sha256=xL7jNTU6gHfgm9UaxORfwZAy8ytg40yadE-s9WaHOQE,18280
39
+ pyworkflow/gui/project/project.py,sha256=LgpwqnOIr6RPqBb76fOoWrPrpdBzQCQev7JuRLj4lEA,18852
40
40
  pyworkflow/gui/project/searchprotocol.py,sha256=xv1nDk7tigQ4M7SLc_ZqGY8c6kG1crjP_xCp9KJjVZ0,5753
41
41
  pyworkflow/gui/project/searchrun.py,sha256=xCGxs7L9PMk48ei9Gi3HI2PAOYEM-zXR5vRfAQRLHKI,7269
42
- pyworkflow/gui/project/steps.py,sha256=jF-G7KmSu28xzv0QSixq4-srDL38PTlnUXCzAbLwylo,5965
42
+ pyworkflow/gui/project/steps.py,sha256=fq0WhPBoByFs8Lr-qmGZ-aFC4lx3XCF2zM2DOBd_KAc,6053
43
43
  pyworkflow/gui/project/utils.py,sha256=H9oFPzz9lAjAI4PRYSYyYniTBn98Y6YSs0bE0qXpMEM,11923
44
44
  pyworkflow/gui/project/variables.py,sha256=UczW6yQqzssj3eETEKaae5GSpsWr04ItPrr5o2WBnu4,7496
45
- pyworkflow/gui/project/viewdata.py,sha256=tDsvWkOi0IqNloZoGS6O-J1fsreF7PFVJq8po0_SnLM,18185
45
+ pyworkflow/gui/project/viewdata.py,sha256=Xoxy1YTqKGSU2DUiM7j23gf-yv4ToNmX_zWgRpVZDo4,18187
46
46
  pyworkflow/gui/project/viewprojects.py,sha256=ZcWzfFLVeCKzVsFboxquzBsOagEoPW0CpVUQ8ZLpvQE,22516
47
- pyworkflow/gui/project/viewprotocols.py,sha256=hZXfCIxNDlb3qcp8F4bDvSCupEaAqdN19e1WWO9pIo0,83928
48
- pyworkflow/gui/project/viewprotocols_extra.py,sha256=riF1XK8UcfjmPyJiFqTidx0izIryxdQKVk6JfqxITcI,21213
47
+ pyworkflow/gui/project/viewprotocols.py,sha256=sykimCQUHCUG5Irjr8__sIZJgJEzG-wgZb7SrdpzkVE,84014
48
+ pyworkflow/gui/project/viewprotocols_extra.py,sha256=d3YZ3KAU8wMdn8psOvDxUDxcN0prruRNdb31bMa8_M0,21250
49
49
  pyworkflow/mapper/__init__.py,sha256=HM7tMMd1r2BZ8hbPGryUQ80E4evY46zIVjiZ3edg_Mg,1186
50
50
  pyworkflow/mapper/mapper.py,sha256=YGVlBK3btHL-jLID6v2jLy7Mb9Wu47lxfZjHdzz0hMg,7726
51
- pyworkflow/mapper/sqlite.py,sha256=hpnn5DntDqip3CxeMx32aR9_wtAgqX_vM5KGfO-pjfk,65216
51
+ pyworkflow/mapper/sqlite.py,sha256=II53wccWx7kRWLFEKyHKTyX9yr5Qz5-d_IxmSdgjdVc,65269
52
52
  pyworkflow/mapper/sqlite_db.py,sha256=HYSXe_fRX1NBKDs6l2zefdO4PMEajnoDMXPjmoFs8Kc,5602
53
53
  pyworkflow/project/__init__.py,sha256=05l9tvr3FfBNL3XNZSbFCs6yO-1HbFlmFu204w7yyKk,1369
54
- pyworkflow/project/config.py,sha256=5dDprBMIxhWNoN4kY8eAfhsyU8mGtMFNrlk76G3hUG4,13519
55
- pyworkflow/project/manager.py,sha256=gPotIuk6IRQwAmsNq410LJmuxvfWSvhObbg88bPsN-M,6706
56
- pyworkflow/project/project.py,sha256=FYTH0S2sahM5yIMQsre7DVLF6oKrjeJsFkRjrXU43DE,83346
54
+ pyworkflow/project/config.py,sha256=F9H1vLJJ9vPyT6zeSqHX69o-wbaN8hWueOuDn53evjc,13692
55
+ pyworkflow/project/manager.py,sha256=bk5hFDuIJqEgELU0plFG-RycGhhFfcJxmPp_qhFj1mE,6758
56
+ pyworkflow/project/project.py,sha256=NGiD0vLZTsPP5vCLh4ddD0D3mmPScnNnbd71IyfWXX4,83818
57
57
  pyworkflow/project/scripts/clean_projects.py,sha256=5qsLHIyJk7sZJUrfSp8sbMRYTkbZ2purtc-5JJb8awM,2600
58
58
  pyworkflow/project/scripts/config.py,sha256=VF4NMsykWzQjCQHRwnfFwxFq2PSk57Ni3TpgTh3nF3w,2933
59
- pyworkflow/project/scripts/create.py,sha256=tlQ3ic9w29lMybPAlZnULIAObHzlhGQgyzp7-OBDLg8,2508
59
+ pyworkflow/project/scripts/create.py,sha256=cmyYJoKP4J9goPRRtQRM9jrsfp-DARHS0XeKJ0ObSCE,2781
60
60
  pyworkflow/project/scripts/edit_workflow.py,sha256=AhwwEFjEgTRR8LUZ4tBSoY2jprDgUmmgFR3FcIU5uno,2940
61
61
  pyworkflow/project/scripts/fix_links.py,sha256=i6hRbczKk3A6GpRtBSp357nT4p7fdbW84enaPx0ueAI,958
62
62
  pyworkflow/project/scripts/load.py,sha256=oA_xZjO94N-hZohLZQXBKEdmE7BZuWxH7x9gPx9lMj8,2696
63
63
  pyworkflow/project/scripts/refresh.py,sha256=-uw41ouFgEzIF4iBXFRzAI79Lna7fqMmEKhRciSUpTA,2603
64
- pyworkflow/project/scripts/schedule.py,sha256=Pi0RtTJ08r1niRoP1b1tfwBbcMyfQV0WFTcHbF82wLY,3987
64
+ pyworkflow/project/scripts/schedule.py,sha256=mUUlaUSiMvA_skES6WOL0Mg-j7-S9Cx6dN-6wx5ZM6Y,3989
65
65
  pyworkflow/project/scripts/stack2volume.py,sha256=ZV8qtPj4qWg2LJSXHBnx-S8L8pyGGQiWuRcWu3OP8qI,940
66
66
  pyworkflow/project/scripts/stop.py,sha256=vCeCxkwPCoUkLbna5HCxKWJ1hrsI4U19Sg9JD4ksXj8,2427
67
67
  pyworkflow/protocol/__init__.py,sha256=bAdIpvUW4GAYdIuv92DZ44-OEkZ7lTtnp1S9T5cwtVs,1413
68
68
  pyworkflow/protocol/bibtex.py,sha256=mCUk1Hp5Vp_i2lozDM1BQNOw10e_RSu86oXvrR63sOA,2122
69
- pyworkflow/protocol/constants.py,sha256=xLtJDUc441YcssGpDEirbX4P2KERhNAdPP6EP_bA3QU,3378
70
- pyworkflow/protocol/executor.py,sha256=QGY-_ALWcE3l3P9Tgg9ugEJWSAkIlK_fg65ftdruAzE,13202
69
+ pyworkflow/protocol/constants.py,sha256=DfuCs7eub-mLHJjEpHlIG9BW3fUpRwfTVwMYytNWv6U,3392
70
+ pyworkflow/protocol/executor.py,sha256=OxnRGZeJI8vYJ6ZfSWifN043pvdw1vV_x9sjQd57fi8,17745
71
71
  pyworkflow/protocol/hosts.py,sha256=B9ENNclqYe75CPqAMOoPjwn-r3ST6HxTewXtsK_zWks,10453
72
72
  pyworkflow/protocol/launch.py,sha256=7WKAiHma2tSuhqK4xVnxD_SnVt7Y5qyDFdQwTo8BLF0,11267
73
73
  pyworkflow/protocol/package.py,sha256=L6x3HHKtbrhDQRJHD07SG3DQKNMGaRQ0ROoLEY3SuRQ,1444
74
- pyworkflow/protocol/params.py,sha256=DRpeNIi_uQQ_JbqORq8A7P7yMBQpoj8r-8oBfroNtYI,26338
75
- pyworkflow/protocol/protocol.py,sha256=xlq3_K7RmuatL-KM9m2K364P6Ft0dPG5r9Fgt0-pI0U,96993
74
+ pyworkflow/protocol/params.py,sha256=gP6QImgULvzCr-f0iseArIp1bjXm1JuUr9padmuMs7M,25901
75
+ pyworkflow/protocol/protocol.py,sha256=Uwa5AT26wlIogPHLgmvqOTcs3tdV-CB88duE1GJKzvc,97219
76
76
  pyworkflow/resources/Imagej.png,sha256=nU2nWI1wxZB_xlOKsZzdUjj-qiCTjO6GwEKYgZ5Risg,14480
77
77
  pyworkflow/resources/chimera.png,sha256=AKCuwMqmZo0Cg2sddMUjBWUhmAq-nPsAVCBpVrYNeiQ,815
78
78
  pyworkflow/resources/fa-exclamation-triangle_alert.png,sha256=31_XvRu0CkJ2dvHSpcBAR43378lIJTWwiag_A7SuUQc,585
@@ -100,13 +100,13 @@ pyworkflow/tests/tests.py,sha256=KgBh_eNHrg3VcYHu-zGye7ot5DzGKFyH8ZI-xABjs98,117
100
100
  pyworkflow/utils/__init__.py,sha256=UEd4SxmVd9zv0JElz1J0Sva7klJw3HEKSzwf5a0c-Xc,1429
101
101
  pyworkflow/utils/dataset.py,sha256=141u2xb-FTe8nF6OVJBJtTNHWz7eDWd24veBWX7eoTI,14943
102
102
  pyworkflow/utils/echo.py,sha256=ZXJRrmxUaTT4Xxf7_pQwg7Th341iFafTs66VEKNOZmE,3442
103
- pyworkflow/utils/graph.py,sha256=Lozs3Q8rmwKnXMbYYyLLgiN6_lpXSA_tEjgh_bX4BRo,5849
103
+ pyworkflow/utils/graph.py,sha256=z3Hcj0I38du97DQEqNT5gk--SCDTRPlKotaCszoZfX8,4981
104
104
  pyworkflow/utils/log.py,sha256=8SIg1jwOKMQzGgDqutB7ZD42ZzLHslxULPvK-f1sDD0,10693
105
105
  pyworkflow/utils/path.py,sha256=k689N4OpN8stfZf1KSyF8U2JjELloxymwrsgyu9y2eI,16770
106
106
  pyworkflow/utils/process.py,sha256=m6gZ_9vHTJyzXOCGGIIwFCbXXoH7XC-Okn5SJzs1P1U,4717
107
107
  pyworkflow/utils/profiler.py,sha256=BC0KkAgfYqf-CV40zLcRxo5Td79f5jw1gzvaDH8iqt8,2218
108
108
  pyworkflow/utils/progressbar.py,sha256=VntEF_FTdQHjMKawfR1R4IoNgYNTEMmnLUIDvUXurxk,5903
109
- pyworkflow/utils/properties.py,sha256=qHakj30QT1twkj71u1JVyHdEiFPUZXWSRVR5_R-GQ1E,23213
109
+ pyworkflow/utils/properties.py,sha256=D1LHkVn0cbxCHhedJE4XAw5ZwOufb_4z48IeJ0L0fWc,23960
110
110
  pyworkflow/utils/reflection.py,sha256=48cvIDO73JinBsFn3XMiVR56AcivfdJoiMXGM7ZwUDY,4429
111
111
  pyworkflow/utils/utils.py,sha256=t5QVNEI2-RJ1B457mozwJj3c_nwwoT_n4cYT23zoNy8,26205
112
112
  pyworkflow/utils/which.py,sha256=KuyKYE4GnkwMpBJoKgOMnx-hNZjHf6OTyqxEsdHIftI,8627
@@ -118,7 +118,7 @@ pyworkflow/webservices/workflowhub.py,sha256=hA4RETMXmxUF-l605INS1TCT2nWnUwOIjrY
118
118
  pyworkflowtests/__init__.py,sha256=RoXNgyShL7moVEXaimTDdfY1fU26dgGKtdjO4JfBQOk,1686
119
119
  pyworkflowtests/bibtex.py,sha256=1f9PjkRO937PB2b-ax-eKLwjU4YY11M5px3dk3xWQzw,2102
120
120
  pyworkflowtests/objects.py,sha256=f4lRHxKg6A23tAhF-8qHXslDPaHBdy4qk72TfR5g_dg,26651
121
- pyworkflowtests/protocols.py,sha256=pNU5wAJuKLzjE449QLi1uemHqxSFTXTyU0JFifK2o0o,5520
121
+ pyworkflowtests/protocols.py,sha256=gSCtA5IuG0a_rvAjZ8uZQIxOr6gmrjfvaaqFnpGY2ds,5529
122
122
  pyworkflowtests/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
123
123
  pyworkflowtests/tests/test_canvas.py,sha256=_d3Xccp7BuwdbkNC5cTTNVXH425V4k1hKYuhUsn4JtU,2685
124
124
  pyworkflowtests/tests/test_domain.py,sha256=8IvVTZllgtqNT66rYLlaHKka9zt-0_tuNQ_69pZDFeE,1624
@@ -126,15 +126,15 @@ pyworkflowtests/tests/test_logs.py,sha256=lNHPtvPIWk_nRy3L3B2GriroMwgNmTZ_-RHRw0
126
126
  pyworkflowtests/tests/test_mappers.py,sha256=2DBzZaM8rIKQTSU9xWAsNGwZkpUPB1FBwgwMmNNbVkg,15423
127
127
  pyworkflowtests/tests/test_object.py,sha256=WVWP11oXNeOTUDJ5BLFR32MmQi6C5Y6KjfVRBf9fu3w,18577
128
128
  pyworkflowtests/tests/test_project.py,sha256=RBrhpIs45dWLrciHqzpj4ORyLZCNvjm8fytIolOZ9Ko,1685
129
- pyworkflowtests/tests/test_protocol_execution.py,sha256=vpjoy__CoWOHt9xmqYXCf6qEWEYZz8qidGTaLYVm3Iw,2607
129
+ pyworkflowtests/tests/test_protocol_execution.py,sha256=uOokU-bgbd-1GqnEKNPcr02vJsAJvjHQ7I3vXNH9jCw,5081
130
130
  pyworkflowtests/tests/test_protocol_export.py,sha256=z18nKPkOnrYLMU8KqcnVsF6-ylQ8d9mw-qFJWRn4Qdw,3291
131
131
  pyworkflowtests/tests/test_protocol_output.py,sha256=8gnIFMRNmwPnIBRCG29WHJB6mqK4FLGn1jiXHtTD6pY,5980
132
132
  pyworkflowtests/tests/test_streaming.py,sha256=vOH-bKCM-fVUSsejqNnCX5TPXhdUayk9ZtJHsNVcfCY,1615
133
133
  pyworkflowtests/tests/test_utils.py,sha256=_pTYGCuXC7YNMdCBzUYNfSBCR3etrHsxHfIhsQi4VPc,7465
134
- scipion_pyworkflow-3.8.0.dist-info/LICENSE.txt,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
135
- scipion_pyworkflow-3.8.0.dist-info/METADATA,sha256=A-juSUF4DN1a1bGPKIfEBkhU8HJTaNa2Bo-y6CvoG_Q,4681
136
- scipion_pyworkflow-3.8.0.dist-info/WHEEL,sha256=UvcQYKBHoFqaQd6LKyqHw9fxEolWLQnlzP0h_LgJAfI,91
137
- scipion_pyworkflow-3.8.0.dist-info/dependency_links.txt,sha256=D7r_CPRjYRtBb3q_OBocTdsaeXI5TwnYMu5ri0JFtzs,84
138
- scipion_pyworkflow-3.8.0.dist-info/entry_points.txt,sha256=oR-zwsOICjEPINm-FWVPp-RfnpXZanVal4_XG6BWkkQ,127
139
- scipion_pyworkflow-3.8.0.dist-info/top_level.txt,sha256=PzyJteyenJwLjAeSFP7oYrTN_U71GABQwET8oLZkh9k,27
140
- scipion_pyworkflow-3.8.0.dist-info/RECORD,,
134
+ scipion_pyworkflow-3.9.1.dist-info/LICENSE.txt,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
135
+ scipion_pyworkflow-3.9.1.dist-info/METADATA,sha256=bZIJBBArE8J_ILTTWYZrB76dEJqP0bjut66guo2JT0s,4681
136
+ scipion_pyworkflow-3.9.1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
137
+ scipion_pyworkflow-3.9.1.dist-info/dependency_links.txt,sha256=D7r_CPRjYRtBb3q_OBocTdsaeXI5TwnYMu5ri0JFtzs,84
138
+ scipion_pyworkflow-3.9.1.dist-info/entry_points.txt,sha256=oR-zwsOICjEPINm-FWVPp-RfnpXZanVal4_XG6BWkkQ,127
139
+ scipion_pyworkflow-3.9.1.dist-info/top_level.txt,sha256=PzyJteyenJwLjAeSFP7oYrTN_U71GABQwET8oLZkh9k,27
140
+ scipion_pyworkflow-3.9.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (74.0.0)
2
+ Generator: setuptools (75.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5