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.
Files changed (140) hide show
  1. pyworkflow/__init__.py +33 -0
  2. pyworkflow/apps/__init__.py +29 -0
  3. pyworkflow/apps/pw_manager.py +37 -0
  4. pyworkflow/apps/pw_plot.py +51 -0
  5. pyworkflow/apps/pw_project.py +113 -0
  6. pyworkflow/apps/pw_protocol_list.py +143 -0
  7. pyworkflow/apps/pw_protocol_run.py +51 -0
  8. pyworkflow/apps/pw_run_tests.py +267 -0
  9. pyworkflow/apps/pw_schedule_run.py +322 -0
  10. pyworkflow/apps/pw_sleep.py +37 -0
  11. pyworkflow/apps/pw_sync_data.py +439 -0
  12. pyworkflow/apps/pw_viewer.py +78 -0
  13. pyworkflow/config.py +536 -0
  14. pyworkflow/constants.py +212 -0
  15. pyworkflow/exceptions.py +18 -0
  16. pyworkflow/gui/__init__.py +36 -0
  17. pyworkflow/gui/browser.py +726 -0
  18. pyworkflow/gui/canvas.py +1190 -0
  19. pyworkflow/gui/dialog.py +976 -0
  20. pyworkflow/gui/form.py +2627 -0
  21. pyworkflow/gui/graph.py +247 -0
  22. pyworkflow/gui/graph_layout.py +271 -0
  23. pyworkflow/gui/gui.py +566 -0
  24. pyworkflow/gui/matplotlib_image.py +233 -0
  25. pyworkflow/gui/plotter.py +247 -0
  26. pyworkflow/gui/project/__init__.py +25 -0
  27. pyworkflow/gui/project/base.py +192 -0
  28. pyworkflow/gui/project/constants.py +139 -0
  29. pyworkflow/gui/project/labels.py +205 -0
  30. pyworkflow/gui/project/project.py +484 -0
  31. pyworkflow/gui/project/searchprotocol.py +154 -0
  32. pyworkflow/gui/project/searchrun.py +181 -0
  33. pyworkflow/gui/project/steps.py +166 -0
  34. pyworkflow/gui/project/utils.py +332 -0
  35. pyworkflow/gui/project/variables.py +179 -0
  36. pyworkflow/gui/project/viewdata.py +472 -0
  37. pyworkflow/gui/project/viewprojects.py +510 -0
  38. pyworkflow/gui/project/viewprotocols.py +2093 -0
  39. pyworkflow/gui/project/viewprotocols_extra.py +560 -0
  40. pyworkflow/gui/text.py +771 -0
  41. pyworkflow/gui/tooltip.py +185 -0
  42. pyworkflow/gui/tree.py +684 -0
  43. pyworkflow/gui/widgets.py +307 -0
  44. pyworkflow/mapper/__init__.py +26 -0
  45. pyworkflow/mapper/mapper.py +222 -0
  46. pyworkflow/mapper/sqlite.py +1578 -0
  47. pyworkflow/mapper/sqlite_db.py +145 -0
  48. pyworkflow/object.py +1512 -0
  49. pyworkflow/plugin.py +712 -0
  50. pyworkflow/project/__init__.py +31 -0
  51. pyworkflow/project/config.py +451 -0
  52. pyworkflow/project/manager.py +179 -0
  53. pyworkflow/project/project.py +1990 -0
  54. pyworkflow/project/scripts/clean_projects.py +77 -0
  55. pyworkflow/project/scripts/config.py +92 -0
  56. pyworkflow/project/scripts/create.py +77 -0
  57. pyworkflow/project/scripts/edit_workflow.py +90 -0
  58. pyworkflow/project/scripts/fix_links.py +39 -0
  59. pyworkflow/project/scripts/load.py +87 -0
  60. pyworkflow/project/scripts/refresh.py +83 -0
  61. pyworkflow/project/scripts/schedule.py +111 -0
  62. pyworkflow/project/scripts/stack2volume.py +41 -0
  63. pyworkflow/project/scripts/stop.py +81 -0
  64. pyworkflow/protocol/__init__.py +38 -0
  65. pyworkflow/protocol/bibtex.py +48 -0
  66. pyworkflow/protocol/constants.py +86 -0
  67. pyworkflow/protocol/executor.py +334 -0
  68. pyworkflow/protocol/hosts.py +313 -0
  69. pyworkflow/protocol/launch.py +270 -0
  70. pyworkflow/protocol/package.py +42 -0
  71. pyworkflow/protocol/params.py +744 -0
  72. pyworkflow/protocol/protocol.py +2554 -0
  73. pyworkflow/resources/Imagej.png +0 -0
  74. pyworkflow/resources/chimera.png +0 -0
  75. pyworkflow/resources/fa-exclamation-triangle_alert.png +0 -0
  76. pyworkflow/resources/fa-info-circle_alert.png +0 -0
  77. pyworkflow/resources/fa-search.png +0 -0
  78. pyworkflow/resources/fa-times-circle_alert.png +0 -0
  79. pyworkflow/resources/file_vol.png +0 -0
  80. pyworkflow/resources/loading.gif +0 -0
  81. pyworkflow/resources/no-image128.png +0 -0
  82. pyworkflow/resources/scipion_bn.png +0 -0
  83. pyworkflow/resources/scipion_icon.png +0 -0
  84. pyworkflow/resources/scipion_icon.svg +397 -0
  85. pyworkflow/resources/scipion_icon_proj.png +0 -0
  86. pyworkflow/resources/scipion_icon_projs.png +0 -0
  87. pyworkflow/resources/scipion_icon_prot.png +0 -0
  88. pyworkflow/resources/scipion_logo.png +0 -0
  89. pyworkflow/resources/scipion_logo_normal.png +0 -0
  90. pyworkflow/resources/scipion_logo_small.png +0 -0
  91. pyworkflow/resources/sprites.png +0 -0
  92. pyworkflow/resources/sprites.xcf +0 -0
  93. pyworkflow/resources/wait.gif +0 -0
  94. pyworkflow/template.py +322 -0
  95. pyworkflow/tests/__init__.py +29 -0
  96. pyworkflow/tests/test_utils.py +25 -0
  97. pyworkflow/tests/tests.py +341 -0
  98. pyworkflow/utils/__init__.py +38 -0
  99. pyworkflow/utils/dataset.py +414 -0
  100. pyworkflow/utils/echo.py +104 -0
  101. pyworkflow/utils/graph.py +196 -0
  102. pyworkflow/utils/log.py +284 -0
  103. pyworkflow/utils/path.py +527 -0
  104. pyworkflow/utils/process.py +132 -0
  105. pyworkflow/utils/profiler.py +92 -0
  106. pyworkflow/utils/progressbar.py +154 -0
  107. pyworkflow/utils/properties.py +627 -0
  108. pyworkflow/utils/reflection.py +129 -0
  109. pyworkflow/utils/utils.py +877 -0
  110. pyworkflow/utils/which.py +229 -0
  111. pyworkflow/viewer.py +328 -0
  112. pyworkflow/webservices/__init__.py +8 -0
  113. pyworkflow/webservices/config.py +11 -0
  114. pyworkflow/webservices/notifier.py +162 -0
  115. pyworkflow/webservices/repository.py +59 -0
  116. pyworkflow/webservices/workflowhub.py +74 -0
  117. pyworkflow/wizard.py +64 -0
  118. pyworkflowtests/__init__.py +51 -0
  119. pyworkflowtests/bibtex.py +51 -0
  120. pyworkflowtests/objects.py +830 -0
  121. pyworkflowtests/protocols.py +154 -0
  122. pyworkflowtests/tests/__init__.py +0 -0
  123. pyworkflowtests/tests/test_canvas.py +72 -0
  124. pyworkflowtests/tests/test_domain.py +45 -0
  125. pyworkflowtests/tests/test_logs.py +74 -0
  126. pyworkflowtests/tests/test_mappers.py +392 -0
  127. pyworkflowtests/tests/test_object.py +507 -0
  128. pyworkflowtests/tests/test_project.py +42 -0
  129. pyworkflowtests/tests/test_protocol_execution.py +72 -0
  130. pyworkflowtests/tests/test_protocol_export.py +78 -0
  131. pyworkflowtests/tests/test_protocol_output.py +158 -0
  132. pyworkflowtests/tests/test_streaming.py +47 -0
  133. pyworkflowtests/tests/test_utils.py +210 -0
  134. scipion_pyworkflow-3.7.0.dist-info/LICENSE.txt +674 -0
  135. scipion_pyworkflow-3.7.0.dist-info/METADATA +107 -0
  136. scipion_pyworkflow-3.7.0.dist-info/RECORD +140 -0
  137. scipion_pyworkflow-3.7.0.dist-info/WHEEL +5 -0
  138. scipion_pyworkflow-3.7.0.dist-info/dependency_links.txt +1 -0
  139. scipion_pyworkflow-3.7.0.dist-info/entry_points.txt +5 -0
  140. scipion_pyworkflow-3.7.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,154 @@
1
+ # -*- coding: utf-8 -*-
2
+ # **************************************************************************
3
+ # *
4
+ # * Authors: J.M. De la Rosa Trevin (delarosatrevin@scilifelab.se) [1]
5
+ # *
6
+ # * [1] SciLifeLab, Stockholm University
7
+ # *
8
+ # * This program is free software: you can redistribute it and/or modify
9
+ # * it under the terms of the GNU General Public License as published by
10
+ # * the Free Software Foundation, either version 3 of the License, or
11
+ # * (at your option) any later version.
12
+ # *
13
+ # * This program is distributed in the hope that it will be useful,
14
+ # * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # * GNU General Public License for more details.
17
+ # *
18
+ # * You should have received a copy of the GNU General Public License
19
+ # * along with this program. If not, see <https://www.gnu.org/licenses/>.
20
+ # *
21
+ # * All comments concerning this program package may be sent to the
22
+ # * e-mail address 'scipion@cnb.csic.es'
23
+ # *
24
+ # **************************************************************************
25
+ """
26
+ Definition of Mock protocols to be used within the tests in the Mock Domain
27
+ """
28
+
29
+ import time
30
+ import datetime
31
+ import pyworkflow.utils as pwutils
32
+ import pyworkflow.object as pwobj
33
+ import pyworkflow.protocol as pwprot
34
+ from pyworkflowtests.objects import MockSetOfImages, MockImage
35
+
36
+ class SleepingProtocol(pwprot.Protocol):
37
+ def __init__(self, **args):
38
+ pwprot.Protocol.__init__(self, **args)
39
+ self.name = pwobj.String(args.get('name', None))
40
+ self.numberOfSleeps = pwobj.Integer(args.get('n', 1))
41
+ self.runMode = pwobj.Integer(pwprot.MODE_RESUME)
42
+
43
+ def sleepStep(self, t):
44
+ log = self._getPath("step_%02d.txt" % t)
45
+ f = open(log, 'w+')
46
+ f.write("Going to sleep at %s\n"
47
+ % pwutils.dateStr(datetime.datetime.now(), True))
48
+ time.sleep(t)
49
+ f.write(" Slept: %d seconds\n" % t)
50
+ f.write("Awakened at %s\n"
51
+ % pwutils.dateStr(datetime.datetime.now(), True))
52
+ f.close()
53
+ return [log]
54
+
55
+ def _insertAllSteps(self):
56
+ print("Inserting all steps...")
57
+ for i in range(self.numberOfSleeps.get()):
58
+ self._insertFunctionStep('sleepStep', i + 1)
59
+
60
+
61
+ class ParallelSleepingProtocol(SleepingProtocol):
62
+ def _insertAllSteps(self):
63
+ step1 = self._insertFunctionStep('sleepStep', 1)
64
+ n = 2
65
+ deps = [step1]
66
+ for i in range(n):
67
+ self._insertFunctionStep('sleepStep')
68
+
69
+ class ConcurrencyProtocol(SleepingProtocol):
70
+ """ Protocol to test concurrency access to sets"""
71
+
72
+ def __init__(self, **kwargs):
73
+ super().__init__(**kwargs)
74
+ self.stepsExecutionMode = pwprot.STEPS_PARALLEL
75
+
76
+ def _defineParams(self, form):
77
+ form.addParallelSection(threads=2, mpi=0)
78
+
79
+ def _insertAllSteps(self):
80
+ n = 2
81
+ for i in range(n):
82
+ self._insertFunctionStep(self.sleepAndOutput, 1, prerequisites=[])
83
+
84
+ def sleepAndOutput(self, secs):
85
+ self.sleepStep(secs)
86
+
87
+ with self._lock:
88
+ outputSet = self.getOutputSet("myOutput", MockSetOfImages)
89
+ newImage = MockImage()
90
+ time.sleep(1)
91
+ outputSet.append(newImage)
92
+ outputSet.write()
93
+
94
+ self._store()
95
+
96
+
97
+ def getOutputSet(self, attrName, setClass):
98
+ output = getattr(self, attrName, None)
99
+
100
+ if output is None:
101
+ output = setClass.create(self._getExtraPath())
102
+ self._defineOutputs(**{attrName: output})
103
+
104
+ return output
105
+
106
+ class ProtOutputTest(pwprot.Protocol):
107
+ """ Protocol to test scalar output and input linking"""
108
+ _label = 'test output'
109
+
110
+ def __init__(self, **args):
111
+ pwprot.Protocol.__init__(self, **args)
112
+ self.name = pwobj.String(args.get('name', None))
113
+
114
+ def _defineParams(self, form):
115
+
116
+ section = form.addSection("Input")
117
+ section.addParam('iBoxSize', pwprot.IntParam, allowsPointers=True,
118
+ default=10,
119
+ label='Input box size as Integer',
120
+ validators=[pwprot.Positive])
121
+
122
+ section.addParam('nullableInteger', pwprot.IntParam, allowsPointers=True,
123
+ label='Nullable Integer', allowsNull=True)
124
+
125
+ def _createOutputStep(self):
126
+ # New Output would be an Integer
127
+ boxSize = pwobj.Integer(10)
128
+
129
+ if self.iBoxSize.hasValue():
130
+ boxSize.set(2*int(self.iBoxSize.get()))
131
+
132
+ self._defineOutputs(oBoxSize=boxSize)
133
+
134
+ def _insertAllSteps(self):
135
+ self._insertFunctionStep('_createOutputStep')
136
+
137
+
138
+ class ProtMultiPointerTest(pwprot.Protocol):
139
+ """ Class to test how multipointer params are exported to json"""
140
+ def _defineParams(self, form):
141
+
142
+ # This should cover Multipointer params that points to attributes...
143
+ # therefore extended attribute of pointers should be used
144
+ form.addParam('mpToAttr', pwprot.MultiPointerParam,
145
+ label="Multipointer to attribute",
146
+ pointerClass='String',
147
+ help="Should point to String inside another protocol")
148
+
149
+ # This should cover Multipointer params that points to protocols...
150
+ # therefore extended attribute of pointers should NOT be used
151
+ form.addParam('mpToProts', pwprot.MultiPointerParam,
152
+ label="Multipointer to sets",
153
+ pointerClass='Protocol',
154
+ help="Should point to another protocol")
File without changes
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env python
2
+ # To run only the tests in this file, use:
3
+ # python -m unittest test_canvas -v
4
+
5
+ import pyworkflow.gui.canvas
6
+ import tkinter
7
+ import math
8
+ from pyworkflow.tests import *
9
+
10
+
11
+ class TestCanvas(BaseTest):
12
+ # IMPORTANT: Tk requires at least that DISPLAY is defined
13
+ # hence in some environments (like buildbot) the test may fail,
14
+ # check for the TclError exception
15
+
16
+ _labels = [PULL_REQUEST]
17
+
18
+ @classmethod
19
+ def setUpClass(cls):
20
+ setupTestOutput(cls)
21
+
22
+ def distance(self, c1, c2):
23
+ return round(math.hypot(c2[0] - c1[0], c2[1] - c1[1]), 2)
24
+
25
+ def allEqual(self, values):
26
+ return not values or values.count(values[0]) == len(values)
27
+
28
+ def allDifferent(self, values):
29
+ return not values or len(values) == len(set(values))
30
+
31
+ def test_connectorsCoords(self):
32
+ try:
33
+ root = tkinter.Tk()
34
+ canvas = pyworkflow.gui.canvas.Canvas(root, width=800, height=600)
35
+ tb1 = canvas.createTextbox("First", 100, 100, "blue")
36
+
37
+ connectorsCoords = tb1.getConnectorsCoordinates()
38
+ self.assertTrue(self.allDifferent(connectorsCoords))
39
+
40
+ print(connectorsCoords)
41
+
42
+ distances = {}
43
+ for i in range(len(connectorsCoords) - 1):
44
+ distances[i] = self.distance(connectorsCoords[i],
45
+ connectorsCoords[i + 1])
46
+
47
+ print(distances)
48
+ self.assertTrue(self.allEqual(list(distances.values())))
49
+ self.assertNotEqual(distances[0], 0)
50
+ except tkinter.TclError as ex:
51
+ print(ex)
52
+
53
+ def test_closestConnectors(self):
54
+ try:
55
+ root = tkinter.Tk()
56
+ canvas = pyworkflow.gui.canvas.Canvas(root, width=800, height=600)
57
+ tb1 = canvas.createTextbox("Textbox1", 100, 100, "blue")
58
+ tb2 = canvas.createTextbox("Textbox2", 300, 100, "blue")
59
+ tb3 = canvas.createTextbox("Textbox3", 100, 300, "blue")
60
+
61
+ tb1ConnectorsCoords = tb1.getConnectorsCoordinates()
62
+ tb2ConnectorsCoords = tb2.getConnectorsCoordinates()
63
+ tb3ConnectorsCoords = tb3.getConnectorsCoordinates()
64
+ c1, c2 = pyworkflow.gui.canvas.findStrictClosestConnectors(tb1, tb2)
65
+ c3, c4 = pyworkflow.gui.canvas.findStrictClosestConnectors(tb1, tb3)
66
+ # tb1 and tb2 are aligned vertically. tb1 and tb3, horizontally.
67
+ # So, their closest connectors must share one coordinate (y in case of c1&c2, x i n case of c3&c4)
68
+ self.assertEqual(c1[1], c2[1])
69
+ self.assertEqual(c3[0], c4[0])
70
+
71
+ except tkinter.TclError as ex:
72
+ print(ex)
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env python
2
+ # **************************************************************************
3
+ # *
4
+ # * Authors: J.M. De la Rosa Trevin (delarosatrevin@scilifelab.se) [1]
5
+ # *
6
+ # * [1] SciLifeLab, Stockholm University
7
+ # *
8
+ # * This program is free software: you can redistribute it and/or modify
9
+ # * it under the terms of the GNU General Public License as published by
10
+ # * the Free Software Foundation, either version 3 of the License, or
11
+ # * (at your option) any later version.
12
+ # *
13
+ # * This program is distributed in the hope that it will be useful,
14
+ # * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # * GNU General Public License for more details.
17
+ # *
18
+ # * You should have received a copy of the GNU General Public License
19
+ # * along with this program. If not, see <https://www.gnu.org/licenses/>.
20
+ # *
21
+ # * All comments concerning this program package may be sent to the
22
+ # * e-mail address 'scipion@cnb.csic.es'
23
+ # *
24
+ # **************************************************************************
25
+
26
+ import pyworkflow.tests as pwtests
27
+ import pyworkflowtests.objects as objectsMod
28
+ from pyworkflowtests import Domain
29
+
30
+
31
+ class TestDomain(pwtests.BaseTest):
32
+
33
+ def test_objects(self):
34
+ """ Test that all objects are properly discovered. """
35
+ objects = Domain.getObjects()
36
+ for k in dir(objectsMod):
37
+ v = getattr(objectsMod, k)
38
+ if isinstance(v, objectsMod.MockObject):
39
+ self.assertEqual(objects[k], v)
40
+
41
+ def test_viewers(self):
42
+ pass
43
+
44
+ def test_wizards(self):
45
+ pass
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env python
2
+
3
+ import logging
4
+ import unittest
5
+
6
+ from pyworkflow import Config
7
+ from pyworkflow.utils import (getLineInFile,
8
+ LoggingConfigurator, restoreStdoutAndErr)
9
+ from pyworkflow.tests import BaseTest, setupTestOutput
10
+ from pyworkflow.utils.process import runJob
11
+
12
+
13
+ class TestLogs(BaseTest):
14
+
15
+ @classmethod
16
+ def setUpClass(cls):
17
+ setupTestOutput(cls)
18
+
19
+ def testSimpleFileLog(self):
20
+
21
+ # Default generic configuration
22
+ Config.SCIPION_LOG = self.getOutputPath("general.log")
23
+ genLogFn = Config.SCIPION_LOG
24
+ print("General log file at %s" % genLogFn)
25
+ LoggingConfigurator.setupLogging()
26
+ log1 = logging.getLogger('pyworkflow.test.log.test_scipion_log')
27
+
28
+ def testMessage(message, msg_callback, file, shouldExist):
29
+
30
+ if msg_callback:
31
+ msg_callback(message)
32
+
33
+ self.assertEqual(shouldExist, bool(getLineInFile(message, file)))
34
+
35
+ testMessage("INFO to GEN", log1.info, genLogFn, True)
36
+ testMessage("DEBUG missing in GEN", log1.debug, genLogFn, False)
37
+ testMessage("WARNING in GEN", log1.warning, genLogFn, True)
38
+ testMessage("ERROR in GEN", log1.error, genLogFn, True)
39
+
40
+ # Protocol run logging configuration (this is propagating the messages,
41
+ # so messages end un in general log too). This is to allow custom configurations to receive running protocol messages)
42
+ logFn = self.getOutputPath('stdout.log')
43
+ logErrFn = self.getOutputPath('stdErr.log')
44
+ log2 = LoggingConfigurator.setUpProtocolRunLogging(logFn, logErrFn)
45
+
46
+ fileInfoTest = 'INFO to FILE'
47
+ testMessage(fileInfoTest, log2.info, logFn, True)
48
+ testMessage(fileInfoTest, None, genLogFn, False)
49
+
50
+ fileDebugMsg = "DEBUG does not reach FILE nor GEN"
51
+ testMessage(fileDebugMsg, log2.debug, logFn, False)
52
+ testMessage(fileDebugMsg, None, genLogFn, False)
53
+
54
+ fileWarningTest = 'WARNING to FILE and not GEN'
55
+ testMessage(fileWarningTest, log2.warning, logFn, True)
56
+ testMessage(fileWarningTest, None, genLogFn, False)
57
+
58
+ fileErrorTest = 'ERROR to FILE and not GEN'
59
+ testMessage(fileErrorTest, log2.error, logErrFn, True)
60
+ testMessage(fileErrorTest, None, genLogFn, False)
61
+
62
+ # Test print goes to the log file (stdout is captured)
63
+ printStdOut = "Print ends up in stdout FILE"
64
+ print(printStdOut, flush=True)
65
+ testMessage(printStdOut,None, logFn, True)
66
+
67
+ subprocessOut = "subprocess output in stdout FILE"
68
+ runJob(None,"echo", subprocessOut)
69
+ testMessage(subprocessOut,None, logFn, True)
70
+
71
+ restoreStdoutAndErr()
72
+
73
+ if __name__ == '__main__':
74
+ unittest.main()