parseq 2025.10.0__tar.gz

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 (206) hide show
  1. parseq-2025.10.0/LICENSE +21 -0
  2. parseq-2025.10.0/PKG-INFO +159 -0
  3. parseq-2025.10.0/parseq/CODERULES.txt +7 -0
  4. parseq-2025.10.0/parseq/__init__.py +22 -0
  5. parseq-2025.10.0/parseq/core/__init__.py +447 -0
  6. parseq-2025.10.0/parseq/core/commons.py +317 -0
  7. parseq-2025.10.0/parseq/core/config.py +82 -0
  8. parseq-2025.10.0/parseq/core/correction.py +162 -0
  9. parseq-2025.10.0/parseq/core/logger.py +67 -0
  10. parseq-2025.10.0/parseq/core/nodes.py +250 -0
  11. parseq-2025.10.0/parseq/core/plotExport.py +392 -0
  12. parseq-2025.10.0/parseq/core/save_restore.py +509 -0
  13. parseq-2025.10.0/parseq/core/singletons.py +65 -0
  14. parseq-2025.10.0/parseq/core/spectra.py +1997 -0
  15. parseq-2025.10.0/parseq/core/transforms.py +776 -0
  16. parseq-2025.10.0/parseq/description.py +121 -0
  17. parseq-2025.10.0/parseq/fits/__init__.py +2 -0
  18. parseq-2025.10.0/parseq/fits/basefit.py +614 -0
  19. parseq-2025.10.0/parseq/fits/exafsfit.py +613 -0
  20. parseq-2025.10.0/parseq/fits/functionfit.py +181 -0
  21. parseq-2025.10.0/parseq/fits/lcf.py +331 -0
  22. parseq-2025.10.0/parseq/gui/__init__.py +1 -0
  23. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-delete-24.png +0 -0
  24. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-delete-32.png +0 -0
  25. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-delete-64.png +0 -0
  26. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-scale-24.png +0 -0
  27. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-scale-32.png +0 -0
  28. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-scale-64.png +0 -0
  29. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-spikes-24.png +0 -0
  30. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-spikes-32.png +0 -0
  31. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-spikes-64.png +0 -0
  32. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-spline--24.png +0 -0
  33. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-spline--32.png +0 -0
  34. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-spline--64.png +0 -0
  35. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-spline-24.png +0 -0
  36. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-spline-32.png +0 -0
  37. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-spline-64.png +0 -0
  38. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-step-24.png +0 -0
  39. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-step-32.png +0 -0
  40. parseq-2025.10.0/parseq/gui/_images/icon-add-correction-step-64.png +0 -0
  41. parseq-2025.10.0/parseq/gui/_images/icon-correction-delete-24.png +0 -0
  42. parseq-2025.10.0/parseq/gui/_images/icon-correction-delete-32.png +0 -0
  43. parseq-2025.10.0/parseq/gui/_images/icon-correction-scale-24.png +0 -0
  44. parseq-2025.10.0/parseq/gui/_images/icon-correction-scale-32.png +0 -0
  45. parseq-2025.10.0/parseq/gui/_images/icon-correction-spikes-24.png +0 -0
  46. parseq-2025.10.0/parseq/gui/_images/icon-correction-spikes-32.png +0 -0
  47. parseq-2025.10.0/parseq/gui/_images/icon-correction-spline--24.png +0 -0
  48. parseq-2025.10.0/parseq/gui/_images/icon-correction-spline--32.png +0 -0
  49. parseq-2025.10.0/parseq/gui/_images/icon-correction-spline-24.png +0 -0
  50. parseq-2025.10.0/parseq/gui/_images/icon-correction-spline-32.png +0 -0
  51. parseq-2025.10.0/parseq/gui/_images/icon-correction-step-24.png +0 -0
  52. parseq-2025.10.0/parseq/gui/_images/icon-correction-step-32.png +0 -0
  53. parseq-2025.10.0/parseq/gui/_images/icon-fit-32.png +0 -0
  54. parseq-2025.10.0/parseq/gui/_images/icon-fit-64.png +0 -0
  55. parseq-2025.10.0/parseq/gui/_images/icon-help.png +0 -0
  56. parseq-2025.10.0/parseq/gui/_images/icon-info.png +0 -0
  57. parseq-2025.10.0/parseq/gui/_images/icon-item-1dim-32.png +0 -0
  58. parseq-2025.10.0/parseq/gui/_images/icon-item-1dim-64.png +0 -0
  59. parseq-2025.10.0/parseq/gui/_images/icon-item-2dim-32.png +0 -0
  60. parseq-2025.10.0/parseq/gui/_images/icon-item-2dim-64.png +0 -0
  61. parseq-2025.10.0/parseq/gui/_images/icon-item-3dim-32.png +0 -0
  62. parseq-2025.10.0/parseq/gui/_images/icon-item-3dim-64.png +0 -0
  63. parseq-2025.10.0/parseq/gui/_images/icon-item-ndim-32.png +0 -0
  64. parseq-2025.10.0/parseq/gui/_images/icon-item-ndim-64.png +0 -0
  65. parseq-2025.10.0/parseq/gui/_images/icon-load-proj.png +0 -0
  66. parseq-2025.10.0/parseq/gui/_images/icon-redo.png +0 -0
  67. parseq-2025.10.0/parseq/gui/_images/icon-save-proj.png +0 -0
  68. parseq-2025.10.0/parseq/gui/_images/icon-save-text.png +0 -0
  69. parseq-2025.10.0/parseq/gui/_images/icon-undo.png +0 -0
  70. parseq-2025.10.0/parseq/gui/_images/parseq.ico +0 -0
  71. parseq-2025.10.0/parseq/gui/aboutDialog.py +283 -0
  72. parseq-2025.10.0/parseq/gui/calibrateEnergy.py +258 -0
  73. parseq-2025.10.0/parseq/gui/columnFormat.py +459 -0
  74. parseq-2025.10.0/parseq/gui/combineSpectra.py +214 -0
  75. parseq-2025.10.0/parseq/gui/dataRebin.py +485 -0
  76. parseq-2025.10.0/parseq/gui/dataTreeModelView.py +1281 -0
  77. parseq-2025.10.0/parseq/gui/fileDialogs.py +305 -0
  78. parseq-2025.10.0/parseq/gui/fileTreeModelView.py +1702 -0
  79. parseq-2025.10.0/parseq/gui/fits/__init__.py +25 -0
  80. parseq-2025.10.0/parseq/gui/fits/gbasefit.py +348 -0
  81. parseq-2025.10.0/parseq/gui/fits/gexafsfit.py +1021 -0
  82. parseq-2025.10.0/parseq/gui/fits/gfunctionfit.py +432 -0
  83. parseq-2025.10.0/parseq/gui/fits/glcf.py +607 -0
  84. parseq-2025.10.0/parseq/gui/gcommons.py +620 -0
  85. parseq-2025.10.0/parseq/gui/gcorrection.py +1163 -0
  86. parseq-2025.10.0/parseq/gui/glitches.py +126 -0
  87. parseq-2025.10.0/parseq/gui/mainWindow.py +954 -0
  88. parseq-2025.10.0/parseq/gui/nodeWidget.py +1447 -0
  89. parseq-2025.10.0/parseq/gui/plot.py +141 -0
  90. parseq-2025.10.0/parseq/gui/plotOptions.py +686 -0
  91. parseq-2025.10.0/parseq/gui/propWidget.py +956 -0
  92. parseq-2025.10.0/parseq/gui/propsOfData.py +295 -0
  93. parseq-2025.10.0/parseq/gui/roi.py +1345 -0
  94. parseq-2025.10.0/parseq/gui/tasker.py +46 -0
  95. parseq-2025.10.0/parseq/gui/undoredo.py +139 -0
  96. parseq-2025.10.0/parseq/gui/webWidget.py +638 -0
  97. parseq-2025.10.0/parseq/help/__init__.py +1 -0
  98. parseq-2025.10.0/parseq/help/_images/XAS-foils.gif +0 -0
  99. parseq-2025.10.0/parseq/help/_images/corr_del.gif +0 -0
  100. parseq-2025.10.0/parseq/help/_images/corr_scl.gif +0 -0
  101. parseq-2025.10.0/parseq/help/_images/corr_spk.gif +0 -0
  102. parseq-2025.10.0/parseq/help/_images/corr_spl.gif +0 -0
  103. parseq-2025.10.0/parseq/help/_images/corr_stp.gif +0 -0
  104. parseq-2025.10.0/parseq/help/_images/mickey-rtfm.gif +0 -0
  105. parseq-2025.10.0/parseq/help/_images/parseq.ico +0 -0
  106. parseq-2025.10.0/parseq/help/_images/parseq_big.png +0 -0
  107. parseq-2025.10.0/parseq/help/_images/pipeline-data-tree.png +0 -0
  108. parseq-2025.10.0/parseq/help/_images/pipeline-file-tree.png +0 -0
  109. parseq-2025.10.0/parseq/help/_images/pipeline-fit-EXAFS.png +0 -0
  110. parseq-2025.10.0/parseq/help/_images/pipeline-graph-XAS.png +0 -0
  111. parseq-2025.10.0/parseq/help/_images/pipeline-line-props.png +0 -0
  112. parseq-2025.10.0/parseq/help/_images/pipeline-proj-load.png +0 -0
  113. parseq-2025.10.0/parseq/help/_images/pipeline-proj-save.png +0 -0
  114. parseq-2025.10.0/parseq/help/_images/pipeline-timing.png +0 -0
  115. parseq-2025.10.0/parseq/help/_images/pipeline-transform-apply.png +0 -0
  116. parseq-2025.10.0/parseq/help/_images/pipeline-undo.png +0 -0
  117. parseq-2025.10.0/parseq/help/_static/animation.js +36 -0
  118. parseq-2025.10.0/parseq/help/_static/thumbnail.css +56 -0
  119. parseq-2025.10.0/parseq/help/_templates/empty.html +1 -0
  120. parseq-2025.10.0/parseq/help/_templates/layout.html +10 -0
  121. parseq-2025.10.0/parseq/help/_themes/mytheme/layout.html +18 -0
  122. parseq-2025.10.0/parseq/help/_themes/mytheme/static/mycss.css_t +372 -0
  123. parseq-2025.10.0/parseq/help/_themes/mytheme/static/utils.js +42 -0
  124. parseq-2025.10.0/parseq/help/_themes/mytheme/theme.conf +4 -0
  125. parseq-2025.10.0/parseq/help/_themes/parseq/layout.html +22 -0
  126. parseq-2025.10.0/parseq/help/_themes/parseq/page.html +23 -0
  127. parseq-2025.10.0/parseq/help/_themes/parseq/static/default.css_t +445 -0
  128. parseq-2025.10.0/parseq/help/_themes/parseq/static/math_config_win32.js +0 -0
  129. parseq-2025.10.0/parseq/help/_themes/parseq/static/utils.js +56 -0
  130. parseq-2025.10.0/parseq/help/_themes/parseq/theme.conf +31 -0
  131. parseq-2025.10.0/parseq/help/cite.rst +9 -0
  132. parseq-2025.10.0/parseq/help/conf.py +245 -0
  133. parseq-2025.10.0/parseq/help/conf_doc.py +62 -0
  134. parseq-2025.10.0/parseq/help/corrections.rst +5 -0
  135. parseq-2025.10.0/parseq/help/data.rst +6 -0
  136. parseq-2025.10.0/parseq/help/exts/animation.py +258 -0
  137. parseq-2025.10.0/parseq/help/fits.rst +10 -0
  138. parseq-2025.10.0/parseq/help/history.rst +70 -0
  139. parseq-2025.10.0/parseq/help/howto.rst +3 -0
  140. parseq-2025.10.0/parseq/help/index.rst +27 -0
  141. parseq-2025.10.0/parseq/help/indexrst.mock +16 -0
  142. parseq-2025.10.0/parseq/help/instructions.rst +46 -0
  143. parseq-2025.10.0/parseq/help/license.rst +24 -0
  144. parseq-2025.10.0/parseq/help/make.bat +35 -0
  145. parseq-2025.10.0/parseq/help/nodes.rst +6 -0
  146. parseq-2025.10.0/parseq/help/top.rst +28 -0
  147. parseq-2025.10.0/parseq/help/transforms.rst +6 -0
  148. parseq-2025.10.0/parseq/help/widgets.rst +6 -0
  149. parseq-2025.10.0/parseq/tests/__init__.py +7 -0
  150. parseq-2025.10.0/parseq/tests/circles.png +0 -0
  151. parseq-2025.10.0/parseq/tests/data/BFT-Cu-foil_EXAFS_23070.txt.gz +0 -0
  152. parseq-2025.10.0/parseq/tests/data/Ce-CeRu2.bft +366 -0
  153. parseq-2025.10.0/parseq/tests/data/Ru-CeRu2.bft +614 -0
  154. parseq-2025.10.0/parseq/tests/data/cu-ref-mix.res +1251 -0
  155. parseq-2025.10.0/parseq/tests/data/cur-Cu-foil_EXAFS_23070.txt.gz +0 -0
  156. parseq-2025.10.0/parseq/tests/data/fitTestEXAFS.h5 +0 -0
  157. parseq-2025.10.0/parseq/tests/data/pb-ref-mix.res +614 -0
  158. parseq-2025.10.0/parseq/tests/data/zn-ref-mix.res +1251 -0
  159. parseq-2025.10.0/parseq/tests/modeltest.py +469 -0
  160. parseq-2025.10.0/parseq/tests/test_QSortFilterProxyModel.py +43 -0
  161. parseq-2025.10.0/parseq/tests/test_aboutWidget.py +23 -0
  162. parseq-2025.10.0/parseq/tests/test_calibrateEnergyWidget.py +30 -0
  163. parseq-2025.10.0/parseq/tests/test_columnStrings.py +58 -0
  164. parseq-2025.10.0/parseq/tests/test_combineSpectraWidget.py +25 -0
  165. parseq-2025.10.0/parseq/tests/test_commons.py +41 -0
  166. parseq-2025.10.0/parseq/tests/test_curve_shear.py +69 -0
  167. parseq-2025.10.0/parseq/tests/test_dataCorrection.py +116 -0
  168. parseq-2025.10.0/parseq/tests/test_dataRebinWidget.py +65 -0
  169. parseq-2025.10.0/parseq/tests/test_dataTreeModelView.py +91 -0
  170. parseq-2025.10.0/parseq/tests/test_fileDialog.py +31 -0
  171. parseq-2025.10.0/parseq/tests/test_fileTreeModelView.py +86 -0
  172. parseq-2025.10.0/parseq/tests/test_fit.py +279 -0
  173. parseq-2025.10.0/parseq/tests/test_fit_EXAFS.py +276 -0
  174. parseq-2025.10.0/parseq/tests/test_flowLayout.py +26 -0
  175. parseq-2025.10.0/parseq/tests/test_glitchDetection.py +57 -0
  176. parseq-2025.10.0/parseq/tests/test_hdf5.py +83 -0
  177. parseq-2025.10.0/parseq/tests/test_iconColor.py +44 -0
  178. parseq-2025.10.0/parseq/tests/test_mainWindow.py +45 -0
  179. parseq-2025.10.0/parseq/tests/test_node.py +35 -0
  180. parseq-2025.10.0/parseq/tests/test_nodeWidget.py +33 -0
  181. parseq-2025.10.0/parseq/tests/test_plotBandROI.py +151 -0
  182. parseq-2025.10.0/parseq/tests/test_plotInteractiveImageROIwithKeys.py +84 -0
  183. parseq-2025.10.0/parseq/tests/test_plotInteractiveImageSingleROI.py +99 -0
  184. parseq-2025.10.0/parseq/tests/test_plotOptions.py +41 -0
  185. parseq-2025.10.0/parseq/tests/test_slice.py +38 -0
  186. parseq-2025.10.0/parseq/tests/test_stateButtons.py +26 -0
  187. parseq-2025.10.0/parseq/third_party/XAFSmass.py +54 -0
  188. parseq-2025.10.0/parseq/third_party/__init__.py +1 -0
  189. parseq-2025.10.0/parseq/third_party/data/Energies.txt +94 -0
  190. parseq-2025.10.0/parseq/third_party/xrt.py +35 -0
  191. parseq-2025.10.0/parseq/utils/__init__.py +1 -0
  192. parseq-2025.10.0/parseq/utils/constants.py +5 -0
  193. parseq-2025.10.0/parseq/utils/format.py +12 -0
  194. parseq-2025.10.0/parseq/utils/ft.py +62 -0
  195. parseq-2025.10.0/parseq/utils/glitch.py +17 -0
  196. parseq-2025.10.0/parseq/utils/h5reduce.py +61 -0
  197. parseq-2025.10.0/parseq/utils/math.py +126 -0
  198. parseq-2025.10.0/parseq/version.py +4 -0
  199. parseq-2025.10.0/parseq.egg-info/PKG-INFO +159 -0
  200. parseq-2025.10.0/parseq.egg-info/SOURCES.txt +214 -0
  201. parseq-2025.10.0/parseq.egg-info/dependency_links.txt +1 -0
  202. parseq-2025.10.0/parseq.egg-info/not-zip-safe +1 -0
  203. parseq-2025.10.0/parseq.egg-info/requires.txt +16 -0
  204. parseq-2025.10.0/parseq.egg-info/top_level.txt +1 -0
  205. parseq-2025.10.0/setup.cfg +4 -0
  206. parseq-2025.10.0/setup.py +94 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Konstantin Klementiev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.4
2
+ Name: parseq
3
+ Version: 2025.10.0
4
+ Summary: ParSeq is a python software library for Parallel execution of Sequential data analysis.
5
+ Home-page: http://parseq.readthedocs.io
6
+ Author: Konstantin Klementiev
7
+ Author-email: konstantin.klementiev@gmail.com
8
+ License: MIT License
9
+ Project-URL: Source, https://github.com/kklmn/ParSeq
10
+ Keywords: data-analysis pipeline framework gui synchrotron spectroscopy
11
+ Platform: OS Independent
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Natural Language :: English
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Intended Audience :: Science/Research
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Classifier: Topic :: Software Development
21
+ Classifier: Topic :: Software Development :: User Interfaces
22
+ Description-Content-Type: text/x-rst
23
+ License-File: LICENSE
24
+ Requires-Dist: numpy>=1.8.0
25
+ Requires-Dist: scipy>=0.17.0
26
+ Requires-Dist: matplotlib>=2.0.0
27
+ Requires-Dist: sphinx>=1.6.2
28
+ Requires-Dist: sphinxcontrib-jquery
29
+ Requires-Dist: autopep8
30
+ Requires-Dist: h5py
31
+ Requires-Dist: silx>=1.1.0
32
+ Requires-Dist: hdf5plugin
33
+ Requires-Dist: psutil
34
+ Requires-Dist: pyqtwebengine
35
+ Requires-Dist: docutils
36
+ Requires-Dist: distro
37
+ Requires-Dist: colorama
38
+ Requires-Dist: sphinx_tabs
39
+ Requires-Dist: xafsmass>=1.6.0
40
+ Dynamic: author
41
+ Dynamic: author-email
42
+ Dynamic: classifier
43
+ Dynamic: description
44
+ Dynamic: description-content-type
45
+ Dynamic: home-page
46
+ Dynamic: keywords
47
+ Dynamic: license
48
+ Dynamic: license-file
49
+ Dynamic: platform
50
+ Dynamic: project-url
51
+ Dynamic: requires-dist
52
+ Dynamic: summary
53
+
54
+ Package ParSeq is a python software library for **Par**\ allel execution of
55
+ **Seq**\ uential data analysis. It implements a general analysis framework that
56
+ consists of transformation nodes -- intermediate stops along the data pipeline
57
+ for data visualization, cross-data operations (e.g. taking average), providing
58
+ user input and displaying status -- and transformations that connect the nodes.
59
+
60
+ It provides an adjustable data tree model (supports grouping, renaming, moving
61
+ and drag-and-drop arrangement), tunable data format definitions, plotters for
62
+ 1D, 2D and 3D data, cross-data analysis routines and flexible widget work space
63
+ suitable for single- and multi-screen computers. It also defines a structure to
64
+ implement particular analysis pipelines as lightweight Python packages.
65
+
66
+ ParSeq is intended for synchrotron based techniques, first of all spectroscopy.
67
+
68
+ Main features
69
+ -------------
70
+
71
+ - ParSeq allows creating analysis pipelines as lightweight Python packages.
72
+
73
+ - Flexible use of screen area by detachable/dockable transformation nodes
74
+ (parts of analysis pipeline).
75
+
76
+ - Two ways of acting from GUI onto multiple data: (a) simultaneous work with
77
+ multiply selected data and (b) copying a specific parameter or a group of
78
+ parameters from active data items to later selected data items.
79
+
80
+ - Undo and redo for most of treatment steps.
81
+
82
+ - Entering into the analysis pipeline at any node, not only at the head of the
83
+ pipeline.
84
+
85
+ - Creation of cross-data combinations (e.g. averaging, PCA) and their
86
+ propagation downstream the pipeline together with the parental data. The
87
+ possibility of termination of the parental data at any selected downstream
88
+ node.
89
+
90
+ - General data correction routines for 1D data: range deletion, scaling,
91
+ replacement by a spline, deletion of spikes and jump correction.
92
+
93
+ - Parallel execution of data transformations with multiprocessing or
94
+ multithreading (can be opted by the pipeline application).
95
+
96
+ - Optional curve fitting solvers, also executed in parallel for multiple data
97
+ items.
98
+
99
+ - Informative error handling that provides alerts and stack traceback with the
100
+ type and location of the occurred error.
101
+
102
+ - Optional time profiling of the pipeline, as controlled by a command-line
103
+ argument.
104
+
105
+ - Export of the workflow into a project file. Export of data into various data
106
+ formats with accompanied Python scripts that visualize the exported data in
107
+ publication-quality plots.
108
+
109
+ - ParSeq understands container files (presently only hdf5) and adds them to
110
+ the system file tree as subfolders. The file tree, including hdf5
111
+ containers, is lazy loaded thus enabling big data collections.
112
+
113
+ - A web viewer widget near each analysis widget displays help pages generated
114
+ from the analysis widget doc strings. The help pages are built by Sphinx at
115
+ the startup time.
116
+
117
+ - The pipeline can be operated by the GUI or from a Python script without GUI.
118
+
119
+ - Optional automatic loading of new data during a measurement time.
120
+
121
+ The mechanisms for creating nodes, transformations and curve fitting solvers,
122
+ connecting them together and creating Qt widgets for the transformations and
123
+ and curve fits are exemplified by separately installed analysis packages:
124
+
125
+ - `ParSeq-XAS <https://github.com/kklmn/ParSeq-XAS>`_
126
+ - `ParSeq-XES-scan <https://github.com/kklmn/ParSeq-XES-scan>`_
127
+
128
+ Installation
129
+ ------------
130
+
131
+ Install it by pip or conda **or** get ParSeq from
132
+ `GitHub <https://github.com/kklmn/ParSeq>`_ and use it with or without
133
+ installation.
134
+ The documentation is available online on
135
+ `Read the Docs <http://parseq.readthedocs.io>`_.
136
+
137
+ Launch an example
138
+ -----------------
139
+
140
+ Either install ParSeq and a ParSeq pipeline application by their installers to
141
+ the standard location or put them to any folder in their respective folders
142
+ (``parseq`` and e.g. ``parseq_XES_scan``) and run the ``*_start.py`` module of
143
+ the pipeline. You can try it with ``--help`` to explore the available options.
144
+ An assumed usage pattern is to load a project ``.pspj`` file from GUI or from
145
+ the starting command line.
146
+
147
+ Hosting and contact
148
+ -------------------
149
+
150
+ The ParSeq project is hosted on `GitHub <https://github.com/kklmn/ParSeq>`_.
151
+ Please use the project's Issues tab to get help or report an issue.
152
+
153
+ Citing ParSeq
154
+ -------------
155
+
156
+ Please cite ParSeq as: `K Klementiev, "ParSeq: Python software for comparative
157
+ data analysis pipelines", J. Phys.: Conf. Ser. 3010 (2025) 012126;
158
+ doi:10.1088/1742-6596/3010/1/012126
159
+ <https://doi.org/10.1088/1742-6596/3010/1/012126>`_.
@@ -0,0 +1,7 @@
1
+ # ======Naming Convention: note the difference from PEP8 for variables!========
2
+ # * classes MixedUpperCase
3
+ # * constants CAPITAL_UNDERSCORE_SEPARATED
4
+ # * varables lowerUpper *or* just lower
5
+ # * functions and methods underscore_separated (not GUI) *or* lowerUpper (GUI)
6
+ # * PEP8 applies for the rest
7
+ # =============================================================================
@@ -0,0 +1,22 @@
1
+ # -*- coding: utf-8 -*-
2
+ u"""
3
+ ParSeq implements a general analysis framework with a data model, plotter,
4
+ cross-data analysis and tunable widget work space. It also sets a structure to
5
+ implement particular analysis pipelines as relatively lightweight Python
6
+ packages.
7
+
8
+ ParSeq is intended for synchrotron based techniques, first of all spectroscopy.
9
+ """
10
+
11
+ # !!! SEE CODERULES.TXT !!!
12
+
13
+ from .version import __versioninfo__, __version__, __date__
14
+
15
+ __module__ = "parseq"
16
+ __author__ = "Konstantin Klementiev (MAX IV Laboratory)"
17
+ __email__ = "first dot last at gmail dot com"
18
+ __license__ = "MIT license"
19
+ __synopsis__ = "ParSeq is a python software library for Parallel execution of"\
20
+ " Sequential data analysis"
21
+
22
+ #__all__ = ['core']
@@ -0,0 +1,447 @@
1
+ # -*- coding: utf-8 -*-
2
+ u"""
3
+ Create analysis pipeline
4
+ ========================
5
+
6
+ Consider `parseq_XES_scan` and `parseq_XAS` as examples for the development
7
+ steps described below.
8
+
9
+ Centralized facilities
10
+ ----------------------
11
+
12
+ Nodes and transformations
13
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
14
+
15
+ .. imagezoom:: _images/pipeline-graph-XAS.png
16
+ :align: right
17
+ :alt: &ensp;A pipeline for data processing of XAS spectra. This pipeline has
18
+ multiple entry nodes and three fitting routines. It partially operates
19
+ in multithreading and multiprocessing.
20
+
21
+ Analysis pipeline is a chain of data transformations with a set of intermediate
22
+ stops -- nodes -- where the results can be visualized and assessed and the
23
+ transformations can be steered. See an example on the right.
24
+
25
+ Data nodes define array names that will appear as attributes of data objects.
26
+ The array values will be read from files or calculated from other arrays. The
27
+ pipeline can be used with or without GUI widgets. In the former case, the
28
+ defined node arrays will appear in the node plot: 1D, 2D or 3D (a stack of 2D
29
+ plots).
30
+
31
+ .. imagezoom:: _images/pipeline-data-tree.png
32
+ :alt: &ensp;EXAFS spectra arranged in a tree. The item tooltips present data
33
+ flow information, array sizes and error messages.
34
+
35
+ The data tree model (as in the Qt's `Model/View Programming
36
+ <https://doc.qt.io/qt-6/model-view-programming.html>`_ concept) is a single
37
+ object throughout the pipeline. In contrast, data tree widgets, see an example
38
+ on the left, are present in *each* data node, not as a single tree instance,
39
+ with the idea to also serve as a plot legend. The data tree can be populated
40
+ from the file tree by using the popup menu or by a drag-and-drop action. The
41
+ newly loaded data get their set of transformation parameters from the currently
42
+ active data item (or the first of them if several items were active). If no
43
+ items have been previously loaded, the parameters are read from the ini file.
44
+ If the ini file does not exist yet, the parameters get their values from
45
+ `defaultParams` dictionary defined in each transformation class.
46
+
47
+ Data can be rearranged by the user: ordered, renamed, grouped and removed. User
48
+ selection in the data model is common for all transformation nodes. For 1D data
49
+ the line color is the same in all data nodes. 1D data plotting can optionally
50
+ be done for several curves simultaneously: for those selected either
51
+ dynamically (via mouse selection) or statically (via check boxes). This
52
+ behavior is set by clicking on the header of the visibility column: it toggles
53
+ between the icon with one eye or many eyes. 2D and 3D data plotting is always
54
+ done for one selected data object -- the first one among selected data items.
55
+
56
+ Each transformation class defines a dictionary of transformation parameters and
57
+ default values for them. It also defines a static method that calculates data
58
+ arrays. The transformation parameters are attributed to each data object. The
59
+ parameter values are supposed to be changed in GUI widgets. This change can be
60
+ done simultaneously for one or several active data objects. Alternatively, any
61
+ parameter can be copied to one or several later selected data.
62
+
63
+ .. imagezoom:: _images/pipeline-transform-apply.png
64
+ :align: right
65
+ :alt: &ensp;An example of the apply/reset popup menu on a control element.
66
+
67
+ Each transformation can optionally define the number of threads or processes
68
+ that will start in parallel to run the transformation of several data items.
69
+ The multiprocessing python API requires the main transformation method as a
70
+ *static* or *class* method (not an instance method). Additionally, for the sake
71
+ of inter-process data transfer in multiprocessing, all input and output node
72
+ arrays have to be added to ``inArrays`` and ``outArrays`` lists (attributes of
73
+ the transformation class).
74
+
75
+ In the pipeline GUI widgets, all interactive GUI elements can be registered
76
+ using a few dedicated methods of the base class :class:`PropWidget`. The
77
+ registration will enable (a) automatic GUI update from the active data and will
78
+ run transformations given the updated GUI elements, so no
79
+ `signal slots <https://doc.qt.io/qt-6/signalsandslots.html>`_
80
+ are typically required. The registration will also enable (b) copying
81
+ transformation parameters to other data by means of popup menus on each GUI
82
+ element, see on the right.
83
+
84
+ Docked node widgets
85
+ ~~~~~~~~~~~~~~~~~~~
86
+
87
+ With the idea of flexible usage of screen area, the node widgets were made
88
+ detachable and dockable into the main ParSeq window. To do this, drag a node
89
+ widget by its caption bar. To dock it back, hover it over the main window or
90
+ use the dock button at the right end of the caption bar.
91
+
92
+ The state of each node widget (docked or floating) and its floating geometry is
93
+ saved in ini file and project files.
94
+
95
+ Undo and redo
96
+ ~~~~~~~~~~~~~
97
+
98
+ .. imagezoom:: _images/pipeline-undo.png
99
+ :align: left
100
+ :alt: &ensp;The undo menu where individual actions can be reverted or
101
+ deleted. The most typical way of using undo is to sequentially reverse
102
+ actions from the top of the undo stack, either by the Undo button or the
103
+ standard key combination Ctrl+Z.
104
+
105
+ The change of any transformation parameter can be reverted or redone again by
106
+ using undo/redo actions. Adding or deleting data items can also be reverted.
107
+ Parseq will keep reference to the deleted data items. In order to free up RAM
108
+ from the deleted items, the undo or redo list can manually be emptied.
109
+
110
+ File tree views and file formats
111
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
112
+
113
+ Each transformation node has its own file tree view with a data format widget
114
+ at its bottom. The file tree is by default visible only in the pipeline head
115
+ node(s). It can be made visible/hidden by the vertical button of the leftmost
116
+ splitter widget "files & containers".
117
+
118
+ The file tree model is a joint model of the standard Qt's `QFileSystemModel`
119
+ and the silx's `Hdf5TreeModel`, which means that hdf5 files are displayed in
120
+ the same file tree as subdirectories.
121
+
122
+ When an entry in the data tree is clicked, the corresponding file or hdf5 entry
123
+ gets highlighted in the starting transformation node widget. When the file tree
124
+ is browsed, the highlight color is green if this entry can be loaded, i.e. the
125
+ data format fields in the data format widget are defined and valid.
126
+
127
+ .. imagezoom:: _images/pipeline-file-tree.png
128
+ :align: right
129
+ :alt: &ensp;The file tree of a node. Visible is an expanded entry of an hdf5
130
+ file. The sum of the two selected arrays will define I0 array.
131
+
132
+ ParSeq works with two file types: column text files and hdf5 files.
133
+
134
+ For column files, the format definitions are expressions of variables `Col0`,
135
+ `Col1` etc, e.g. as `Col3+Col4`. Simple expressions, like `Col0`, can be
136
+ reduced to the corresponding index integer, here just `0`. The expressions may
137
+ include numpy functions: `np.log(Col6/Col7)`.
138
+
139
+ The file header can optionally be defined by the number of header lines, by the
140
+ leading comment character or a key word present in the last header line. The
141
+ whole header will serve as metadata for the corresponding data item.
142
+
143
+ Sometimes, column data files have a variable sequence of columns depending on
144
+ the used instruments. ParSeq can automatically handle such cases if the
145
+ pipeline provides a node method `auto_format()` that searches the column file
146
+ header for a data description line and returns the wished column indices. An
147
+ example can be found in the pipeline ParSeq-XAS in its module `XAS_nodes.py`.
148
+
149
+ For hdf5 files, the format definitions are relative hdf5 paths or expressions
150
+ of a data dictionary `d`, whose keys are relative hdf5 paths:
151
+ `d["measurement/albaem-01_ch1"] + d["measurement/albaem-01_ch2"]`. The easiest
152
+ way to build these expressions is to use the popup menu in the file tree view,
153
+ see the image on the right. String or scalar hdf5 entries can be inserted into
154
+ the list of metadata items, again by using the popup menu. Note that you can
155
+ use hdf5 data sets from various hdf5 data groups or even hdf5 data files, not
156
+ necessarily from one data group when you load one data item.
157
+
158
+ The format definitions will be restored at the next program start. The data
159
+ format widget updates upon data selection change. So if several data formats
160
+ are in use in one session, the selection of a right data item is a way to
161
+ activate the right data format before loading the next similar data item.
162
+ The format definitions can also be saved into an ini file (.parseq/formats.ini)
163
+ and later restored from it using the popup menu when right-clicked on a data
164
+ file.
165
+
166
+ Automatic data loading can be activated by the check box "auto load new data
167
+ from current location", which is a useful feature during beam times.
168
+
169
+ Metadata
170
+ ~~~~~~~~
171
+
172
+ Metadata widget joins the metadata string variables, see the previous section.
173
+ The widget can also be used to examine text files for column positions, use the
174
+ popup menu in the file tree view for that. The widget is hidden by default and
175
+ is located below the node plot.
176
+
177
+ Plots
178
+ ~~~~~
179
+
180
+ .. imagezoom:: _images/pipeline-line-props.png
181
+ :align: right
182
+ :alt: &ensp;Line properties accessed from the header of a node's data tree.
183
+
184
+ The node plots are used to display data and to host a few analysis widgets:
185
+ regions of interest (ROIs) and data correction widgets. The 1D, 2D and 3D (2D
186
+ stacks) plots are adopted from silx with a few customizations.
187
+
188
+ Bear in mind that if several items have the same alias, silx displays only one
189
+ of them, so make sure aliases are unique. Parseq will try to append a numbered
190
+ suffix to the alias if the added data have the same file name. Aliases can
191
+ always be changed by the user.
192
+
193
+ In 1D plotting window, clicking on a curve will select the corresponding data
194
+ item in the data tree widget. Auxiliary curves can be added in user-defined
195
+ transformation widgets by specifying a method `extraPlot()`. The curves should
196
+ have their `legend` property defined in the following format: the data item
197
+ alias followed by a dot followed by a sub-name. If this convention is followed,
198
+ the curves become clickable, which will select the corresponding data item in
199
+ the data tree. Selected data items are plotted on top of the others.
200
+
201
+ Default plot settings for 1D curves can be set in the definitions of node
202
+ arrays. The GUI can also change it from any data tree view, see on the right.
203
+
204
+ The silx's plots may define a plot *backend*. Currently silx implements
205
+ 'matplotlib' and 'opengl'. The former one is default in ParSeq as it looks
206
+ better in almost all scenarios, the latter one is quicker, especially for 2D
207
+ and 3D plots. The user is free to select either backend by CLI parameters of
208
+ the pipeline starter.
209
+
210
+ Fits
211
+ ~~~~
212
+
213
+ Data nodes can optionally host curve fitting routines. If one or more fit
214
+ widgets were specified for a given node, they appear in separate splitters
215
+ under the node's plot. In the initial view, the splitters are collapsed.
216
+
217
+ .. imagezoom:: _images/pipeline-fit-EXAFS.png
218
+ :align: right
219
+ :alt: &ensp;EXAFS fit widget as an example of ParSeq fit widgets. It was
220
+ built on top of the ParSeq base fit and base fit widget classes.
221
+
222
+ Similarly to transformations, fitting solvers can run in parallel for several
223
+ data items. Fitting parameters can be constrained or tied to other parameters,
224
+ also to parameters of another data item fit. See an example fit widget on the
225
+ right.
226
+
227
+ ParSeq implements a base fit class :class:`parseq.fits.basefit.Fit` and its
228
+ widget mate :class:`parseq.gui.fits.gbasefit.FitWidget`. These are parent
229
+ classes for ParSeq's Liner Combination Fit, Function Fit and EXAFS Fit.
230
+
231
+ The actual fit worker for each fit process or thread is
232
+ `scipy.optimize.curve_fit
233
+ <https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html>`_.
234
+ Its performance figures are displayed at the bottom of each fit widget.
235
+
236
+ Cross-data combinations
237
+ ~~~~~~~~~~~~~~~~~~~~~~~
238
+
239
+ Data items in each transformation node can be combined to produce joint
240
+ secondary data: average, sum, rms deviation and PCA components and Target
241
+ Transformation. If the abscissas of the involved datasets are different,
242
+ an interpolation is offered.
243
+
244
+ Whenever the contributing data have been modified in an upstream
245
+ transformation, the combined data will also update.
246
+
247
+ Standard data corrections
248
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
249
+
250
+ ParSeq data pipelines perform data evolution in specialized *transformations*.
251
+ ParSeq also implements a few standard data *corrections*, intended for
252
+ amendment of experimental 1D data curves. These include (a) range deletion,
253
+ (b) range vertical scaling, (c) replacement by a spline and (d) a step
254
+ correction.
255
+
256
+ Although data can flow in ParSeq without GUIs, data corrections are most
257
+ conveniently done using the mouse.
258
+
259
+ Project saving with data export and plot script generation
260
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
261
+
262
+ .. imagezoom:: _images/pipeline-proj-load.png
263
+ :align: left
264
+ :alt: &ensp;The Load project dialog. In the right panel is an image browser
265
+ of the project plots.
266
+
267
+ .. imagezoom:: _images/pipeline-proj-save.png
268
+ :align: right
269
+ :alt: &ensp;The Save project dialog. The bottom panel is a widget for data
270
+ export options.
271
+
272
+ There are a few example projects files coming with each pipeline application.
273
+ A ParSeq project file (.pspj) defines the data tree and all parameters for all
274
+ transformations and fits. It has an `ini file structure
275
+ <https://docs.python.org/3/library/configparser.html>`_. At its saving time
276
+ ParSeq also saves all relevant plot views that can be browsed in the Load
277
+ project dialog, see on the left.
278
+
279
+ Before starting the Save project dialog, select the data items to be exported.
280
+ In the dialog, select the nodes to export from, data format(s) and whether a
281
+ plotting script is wanted. The script will plot the *exported data* and
282
+ preserve the plotting settings from the analysis pipeline. The idea of the
283
+ script generation is twofold: to demonstrate the access to the saved data and
284
+ to give a possibility to tune the resulting figures. The scripts have a few
285
+ comments inside about tuning axis ranges, axis labels and curve legends.
286
+
287
+ In the saved project, file path to each data item is saved in two versions: as
288
+ an absolute path and as a relative path in respect to the project location.
289
+ When the project is copied together with the files to a new location, the
290
+ project should be directly loadable. When copied from a GPFS location at a
291
+ beamline, this may not work, and the relative paths have to be manually edited
292
+ by a Search/Replace operation in a text file editor.
293
+
294
+ Error handling
295
+ ~~~~~~~~~~~~~~
296
+
297
+ Should an error occur during a transformation, this error is caught by ParSeq.
298
+ The corresponding data item turns to a bad state displayed by a red background
299
+ in the data tree. The caught error is displayed in the tooltip of that data
300
+ tree item where it names the transformation, the data item and the involved
301
+ python module. The error can be copied to clipboard.
302
+
303
+ Additionally, errors are written to the pipeline log file. The log file is
304
+ located in the user's home directory in ".parseq" subfolder. Note, the log file
305
+ is limited to one program session; it renewed at the next program start. The
306
+ logging level depends on the verbosity settings set by the command-line
307
+ options.
308
+
309
+ Command-line interface and start options
310
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
311
+
312
+ The available command line options of the starter script can be revealed with a
313
+ :command:`--help` key. Most of them are intended for development purpose.
314
+
315
+ Performance profiling
316
+ ~~~~~~~~~~~~~~~~~~~~~
317
+
318
+ If the starter script is started with an elevated verbosity level (e.g. with a
319
+ key :command:`--verbosity 100`), the terminal output prints the timing results
320
+ for each relevant invocation of transformation and plotting methods, see below.
321
+ This functionality is meant as a tool for data pipeline development.
322
+
323
+ .. imagezoom:: _images/pipeline-timing.png
324
+ :align: none
325
+ :alt: &ensp;An example of the terminal output with timing figures, enabled
326
+ by the CLI option `--verbosity` (*or* `-v`).
327
+
328
+ Help system
329
+ ~~~~~~~~~~~
330
+
331
+ The transformation class docstrings are built by ParSeq at the application
332
+ start up time using `Sphinx <https://www.sphinx-doc.org>`_ into an html file
333
+ and displayed in a help panel close to the transformation widget.
334
+
335
+ The main application help files are also built at the start up time if ParSeq
336
+ file have been modified.
337
+
338
+ If the produced html files look unexpectedly, the troubleshooting should start
339
+ with an elevated verbosity level, e.g. by `python XAS_start.py -v 10`, to see
340
+ the output from Sphinx. Next, open the html file in an external browser and use
341
+ its page inspect function to discover image paths, css styles etc.
342
+
343
+ The help system can be rebuilt by the user via the top menu command
344
+ "Rebuild documentation".
345
+
346
+ About dialog
347
+ ~~~~~~~~~~~~
348
+
349
+ The about dialog displays the connectivity between the pipeline nodes in a
350
+ dynamically created svg graph. If a fit is defined in a node, it is also
351
+ displayed here.
352
+
353
+ Prepare pipeline metadata and images
354
+ ------------------------------------
355
+
356
+ Create a project directory for the pipeline. Create `__init__.py` file that
357
+ defines metadata about the project. Note that pipeline applications and ParSeq
358
+ itself use the module `parseq.core.singletons` as a means to store global
359
+ variables; the pipeline's `__init__.py` module defines a few of them. Together
360
+ with the docstrings of the module, these metadata will appear in the About
361
+ dialog.
362
+
363
+ Create `doc/_images` directory and put an application icon there. The pipeline
364
+ transformations will have class docstrings that may also include images; those
365
+ images should be located here, in `doc/_images`.
366
+
367
+ Make data nodes
368
+ ---------------
369
+
370
+ To define a node class means to name all plot arrays, define their roles,
371
+ labels and units. The data containers may also have other array attributes that
372
+ do not participate in plots; these are not to be declared.
373
+
374
+ Make data transformations
375
+ -------------------------
376
+
377
+ Start making a transformation class with defining a dictionary `defaultParams`
378
+ of default parameter values. Decide on using multiprocessing/multithreading by
379
+ specifying `nThreads` or `nProcesses`. If any of these numbers is > 1 (the
380
+ default values are both 1), specify two lists of array names: `inArrays` and
381
+ `outArrays`. Define a static or a class method :meth:`.Transform.run_main`.
382
+ Note, it can have a few signatures. Within the method, get the actual
383
+ transformation parameters from the dictionary `data.transformParams` and get
384
+ data arrays as attributes of `data`, e.g. ``data.x``.
385
+
386
+ For expensive transformations, you should update the *progress* status.
387
+
388
+ For accessing arrays of other data objects, use a different signature of
389
+ :meth:`.Transform.run_main` that contains the *allData* argument. Note that in
390
+ this case multiprocessing is not possible.
391
+
392
+ Make GUI widgets
393
+ ----------------
394
+
395
+ The widgets that control transformation parameters are descendants of
396
+ :class:`.PropWidget`. The main methods of that class are
397
+ :meth:`.PropWidget.registerPropWidget` and
398
+ :meth:`.PropWidget.registerPropGroup`. They use the Qt signal/slot mechanism to
399
+ update the corresponding transformation parameters; the user does not have to
400
+ explicitly implement the reaction slots. Additionally, these methods enable
401
+ copying transformation parameters to other data by means of popup menus, update
402
+ the GUI upon selecting data objects in the data tree, start the corresponding
403
+ transformation and operate undo and redo lists.
404
+
405
+ Because each transformation already has a set of default parameter values,
406
+ these GUI widgets can gradually grow during the development time, without
407
+ compromising the data pipeline functionality.
408
+
409
+ Provide docstrings in reStructuredText markup. They will be built by Sphinx and
410
+ displayed near the corresponding widgets.
411
+
412
+ Make fitting worker classes
413
+ ---------------------------
414
+
415
+ Similarly to a transformation class, a fitting class defines multiprocessing /
416
+ multithreading needs and a static or a class method :meth:`.Fit.run_main`. It
417
+ also defines in a few class dictionaries the data array to be fitted and the
418
+ fit parameters.
419
+
420
+ Make data pipeline
421
+ ------------------
422
+
423
+ This is a small module that instantiates the above nodes, transformations, fits
424
+ and widgets and connects them together.
425
+
426
+ Create test data tree
427
+ ---------------------
428
+
429
+ Put a few data files in a local folder (i.e. `data`) and create a module that
430
+ defines a function that loads the data into a :ref:`data tree <data>`, defines
431
+ suitable transformation parameters and launches the first transformation (the
432
+ next ones will start automatically).
433
+
434
+ Create pipeline starter
435
+ -----------------------
436
+
437
+ The starter should understand command line arguments and prepare options for
438
+ loading the test data and to run the pipeline with and without GUI.
439
+
440
+ Creating development versions of analysis application
441
+ -----------------------------------------------------
442
+
443
+ Copy the whole folder of the application to the same level but with a different
444
+ name, e.g. append a version suffix. In the import section in the start script
445
+ change the import name to the above created folder name. Done.
446
+
447
+ """