parseq 2024.5.0__zip → 2024.11.1__zip
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.
- {parseq-2024.5.0 → parseq-2024.11.1}/PKG-INFO +12 -15
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/core/commons.py +2 -2
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/core/config.py +10 -6
- parseq-2024.11.1/parseq/core/correction.py +162 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/core/plotExport.py +1 -1
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/core/spectra.py +19 -11
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/core/transforms.py +4 -2
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/description.py +17 -9
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/fits/basefit.py +2 -2
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/fits/exafsfit.py +26 -9
- parseq-2024.11.1/parseq/gui/_images/icon-add-correction-scale-24.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-add-correction-scale-32.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-add-correction-spikes-24.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-add-correction-spikes-32.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-add-correction-step-24.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-add-correction-step-32.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-correction-delete-24.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-correction-delete-32.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-correction-scale-24.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-correction-scale-32.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-correction-spikes-24.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-correction-spikes-32.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-correction-spline-24.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-correction-spline-32.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-correction-step-24.png +0 -0
- parseq-2024.11.1/parseq/gui/_images/icon-correction-step-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/aboutDialog.py +3 -3
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/dataTreeModelView.py +5 -5
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/fileTreeModelView.py +18 -11
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/gcorrection.py +299 -131
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/mainWindow.py +13 -8
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/nodeWidget.py +39 -17
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/plotOptions.py +1 -1
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/propWidget.py +60 -24
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/propsOfData.py +11 -6
- parseq-2024.11.1/parseq/help/_images/corr_del.gif +0 -0
- parseq-2024.11.1/parseq/help/_images/corr_scl.gif +0 -0
- parseq-2024.11.1/parseq/help/_images/corr_spk.gif +0 -0
- parseq-2024.11.1/parseq/help/_images/corr_spl.gif +0 -0
- parseq-2024.11.1/parseq/help/_images/corr_stp.gif +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_static/animation.js +0 -12
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/conf.py +10 -8
- parseq-2024.11.1/parseq/help/corrections.rst +5 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/exts/animation.py +9 -8
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/history.rst +6 -2
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/index.rst +1 -0
- parseq-2024.11.1/parseq/help/instructions.rst +42 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/top.rst +2 -2
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/__init__.py +1 -1
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_dataCorrection.py +38 -17
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/third_party/xrt.py +3 -2
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/version.py +2 -2
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq.egg-info/PKG-INFO +12 -15
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq.egg-info/SOURCES.txt +19 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/setup.py +6 -4
- parseq-2024.5.0/parseq/core/correction.py +0 -65
- parseq-2024.5.0/parseq/gui/_images/icon-add-correction-scale-24.png +0 -0
- parseq-2024.5.0/parseq/gui/_images/icon-add-correction-scale-32.png +0 -0
- parseq-2024.5.0/parseq/gui/_images/icon-add-correction-step-24.png +0 -0
- parseq-2024.5.0/parseq/gui/_images/icon-add-correction-step-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/LICENSE +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/CODERULES.txt +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/__init__.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/core/__init__.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/core/logger.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/core/nodes.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/core/save_restore.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/core/singletons.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/fits/__init__.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/fits/functionfit.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/fits/lcf.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/__init__.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-add-correction-delete-24.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-add-correction-delete-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-add-correction-spline-24.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-add-correction-spline-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-fit-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-fit-64.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-help.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-info.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-1dim-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-1dim-64.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-1dim-busy-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-1dim-busy-64.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-2dim-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-2dim-64.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-2dim-busy-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-2dim-busy-64.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-3dim-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-3dim-64.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-3dim-busy-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-3dim-busy-64.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-ndim-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-ndim-64.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-ndim-busy-32.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-item-ndim-busy-64.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-load-proj.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-redo.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-save-proj.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-save-text.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/icon-undo.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/_images/parseq.ico +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/calibrateEnergy.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/columnFormat.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/combineSpectra.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/dataRebin.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/fileDialogs.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/fits/__init__.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/fits/gbasefit.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/fits/gexafsfit.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/fits/gfunctionfit.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/fits/glcf.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/gcommons.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/plot.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/roi.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/tasker.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/undoredo.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/gui/webWidget.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/__init__.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/XAS-foils.gif +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/mickey-rtfm.gif +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/parseq.ico +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/parseq_big.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/pipeline-data-tree.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/pipeline-file-tree.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/pipeline-fit-EXAFS.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/pipeline-graph-XAS.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/pipeline-line-props.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/pipeline-proj-load.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/pipeline-proj-save.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/pipeline-timing.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/pipeline-transform-apply.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_images/pipeline-undo.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_static/thumbnail.css +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_templates/layout.html +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_themes/mytheme/layout.html +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_themes/mytheme/static/mycss.css_t +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_themes/mytheme/theme.conf +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_themes/parseq/layout.html +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_themes/parseq/page.html +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_themes/parseq/static/default.css_t +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_themes/parseq/static/math_config_win32.js +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_themes/parseq/static/utils.js +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/_themes/parseq/theme.conf +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/conf_doc.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/data.rst +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/fits.rst +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/howto.rst +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/license.rst +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/make.bat +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/nodes.rst +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/transforms.rst +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/help/widgets.rst +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/circles-rect.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/circles.png +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/data/BFT-Cu-foil_EXAFS_23070.txt.gz +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/data/Ce-CeRu2.bft +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/data/Ru-CeRu2.bft +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/data/cu-ref-mix.res +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/data/fitTestEXAFS.h5 +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/data/pb-ref-mix.res +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/data/zn-ref-mix.res +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/modeltest.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_QSortFilterProxyModel.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_ROI.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_aboutWidget.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_calibrateEnergyWidget.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_columnStrings.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_combineSpectraWidget.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_commons.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_curve_shear.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_dataRebinWidget.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_dataTreeModelView.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_fileDialog.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_fileTreeModelView.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_fit.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_fit_EXAFS.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_flowLayout.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_hdf5.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_mainWindow.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_node.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_nodeWidget.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_plotInteractiveImageROIwithKeys.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_plotInteractiveImageSingleROI.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_plotOptions.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_slice.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/tests/test_stateButtons.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/third_party/XAFSmass.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/third_party/__init__.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/third_party/data/Energies.txt +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/utils/__init__.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/utils/constants.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/utils/format.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/utils/ft.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/utils/h5reduce.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq/utils/math.py +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq.egg-info/dependency_links.txt +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq.egg-info/not-zip-safe +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq.egg-info/requires.txt +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/parseq.egg-info/top_level.txt +0 -0
- {parseq-2024.5.0 → parseq-2024.11.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: parseq
|
|
3
|
-
Version: 2024.
|
|
3
|
+
Version: 2024.11.1
|
|
4
4
|
Summary: ParSeq is a python software library for Parallel execution of Sequential data analysis.
|
|
5
5
|
Home-page: http://parseq.readthedocs.io
|
|
6
6
|
Author: Konstantin Klementiev
|
|
@@ -50,12 +50,6 @@ implement particular analysis pipelines as lightweight Python packages.
|
|
|
50
50
|
|
|
51
51
|
ParSeq is intended for synchrotron based techniques, first of all spectroscopy.
|
|
52
52
|
|
|
53
|
-
A screenshot of ParSeq-XAS (an EXAFS analysis pipeline) as an application
|
|
54
|
-
example:
|
|
55
|
-
|
|
56
|
-
.. image:: _images/XAS-foils.gif
|
|
57
|
-
:scale: 50 %
|
|
58
|
-
|
|
59
53
|
Main features
|
|
60
54
|
-------------
|
|
61
55
|
|
|
@@ -73,13 +67,13 @@ Main features
|
|
|
73
67
|
- Entering into the analysis pipeline at any node, not only at the head of the
|
|
74
68
|
pipeline.
|
|
75
69
|
|
|
76
|
-
- Creation of cross-data combinations (e.g. averaging,
|
|
70
|
+
- Creation of cross-data combinations (e.g. averaging, PCA) and their
|
|
77
71
|
propagation downstream the pipeline together with the parental data. The
|
|
78
72
|
possibility of termination of the parental data at any selected downstream
|
|
79
73
|
node.
|
|
80
74
|
|
|
81
75
|
- General data correction routines for 1D data: range deletion, scaling,
|
|
82
|
-
replacement by a spline and jump correction.
|
|
76
|
+
replacement by a spline, deletion of spikes and jump correction.
|
|
83
77
|
|
|
84
78
|
- Parallel execution of data transformations with multiprocessing or
|
|
85
79
|
multithreading (can be opted by the pipeline application).
|
|
@@ -87,15 +81,15 @@ Main features
|
|
|
87
81
|
- Optional curve fitting solvers, also executed in parallel for multiple data
|
|
88
82
|
items.
|
|
89
83
|
|
|
90
|
-
- Informative error handling that provides alerts and stack traceback
|
|
84
|
+
- Informative error handling that provides alerts and stack traceback with the
|
|
91
85
|
type and location of the occurred error.
|
|
92
86
|
|
|
93
87
|
- Optional time profiling of the pipeline, as controlled by a command-line
|
|
94
88
|
argument.
|
|
95
89
|
|
|
96
90
|
- Export of the workflow into a project file. Export of data into various data
|
|
97
|
-
formats with accompanied Python scripts that visualize the exported data
|
|
98
|
-
|
|
91
|
+
formats with accompanied Python scripts that visualize the exported data in
|
|
92
|
+
publication-quality plots.
|
|
99
93
|
|
|
100
94
|
- ParSeq understands container files (presently only hdf5) and adds them to
|
|
101
95
|
the system file tree as subfolders. The file tree, including hdf5
|
|
@@ -116,11 +110,14 @@ and curve fits are exemplified by separately installed analysis packages:
|
|
|
116
110
|
- `ParSeq-XAS <https://github.com/kklmn/ParSeq-XAS>`_
|
|
117
111
|
- `ParSeq-XES-scan <https://github.com/kklmn/ParSeq-XES-scan>`_
|
|
118
112
|
|
|
119
|
-
|
|
113
|
+
Installation
|
|
120
114
|
------------
|
|
121
115
|
|
|
122
|
-
|
|
123
|
-
|
|
116
|
+
Install it by pip or conda or get ParSeq from
|
|
117
|
+
`GitHub <https://github.com/kklmn/ParSeq>`_ and use it with or without
|
|
118
|
+
installation.
|
|
119
|
+
The documentation is available online on
|
|
120
|
+
`Read the Docs <http://parseq.readthedocs.io>`_.
|
|
124
121
|
|
|
125
122
|
Launch an example
|
|
126
123
|
-----------------
|
|
@@ -46,7 +46,7 @@ def expandDotAttr(attr):
|
|
|
46
46
|
|
|
47
47
|
def expandTransformParam(prop):
|
|
48
48
|
"add `transformParams` from the left of the prop name"
|
|
49
|
-
if isinstance(prop,
|
|
49
|
+
if isinstance(prop, str):
|
|
50
50
|
if '.' not in prop:
|
|
51
51
|
# then a single attribute
|
|
52
52
|
return '.'.join(('transformParams', prop))
|
|
@@ -59,7 +59,7 @@ def shrinkTransformParam(prop):
|
|
|
59
59
|
if isinstance(prop, (list, tuple)):
|
|
60
60
|
if 'transformParams' in prop:
|
|
61
61
|
prop = [pr for pr in prop if pr != 'transformParams']
|
|
62
|
-
elif isinstance(prop,
|
|
62
|
+
elif isinstance(prop, str):
|
|
63
63
|
if 'transformParams.' in prop:
|
|
64
64
|
prop = prop.replace('transformParams.', '')
|
|
65
65
|
return prop
|
|
@@ -10,29 +10,33 @@ try:
|
|
|
10
10
|
except ImportError:
|
|
11
11
|
from ConfigParser import ConfigParser # python 2
|
|
12
12
|
|
|
13
|
+
from . import singletons as csi
|
|
14
|
+
|
|
13
15
|
iniDir = os.path.expanduser(os.path.join('~', '.parseq'))
|
|
14
16
|
if not os.path.exists(iniDir):
|
|
15
17
|
os.makedirs(iniDir)
|
|
16
18
|
|
|
17
19
|
encoding = 'utf-8'
|
|
18
20
|
|
|
19
|
-
iniFileLoad =
|
|
21
|
+
iniFileLoad = os.path.join(iniDir, '{0}_load.ini'.format(csi.pipelineName))
|
|
20
22
|
configLoad = ConfigParser()
|
|
21
23
|
configLoad.read(iniFileLoad, encoding=encoding)
|
|
22
24
|
|
|
23
|
-
iniFileGUI =
|
|
25
|
+
iniFileGUI = os.path.join(iniDir, '{0}_gui.ini'.format(csi.pipelineName))
|
|
24
26
|
configGUI = ConfigParser()
|
|
25
27
|
configGUI.read(iniFileGUI, encoding=encoding)
|
|
26
28
|
|
|
27
|
-
iniFileTransforms =
|
|
29
|
+
iniFileTransforms = os.path.join(
|
|
30
|
+
iniDir, '{0}_transforms.ini'.format(csi.pipelineName))
|
|
28
31
|
configTransforms = ConfigParser()
|
|
29
32
|
configTransforms.read(iniFileTransforms, encoding=encoding)
|
|
30
33
|
|
|
31
|
-
iniFileFits =
|
|
34
|
+
iniFileFits = os.path.join(iniDir, '{0}_fits.ini'.format(csi.pipelineName))
|
|
32
35
|
configFits = ConfigParser()
|
|
33
36
|
configFits.read(iniFileFits, encoding=encoding)
|
|
34
37
|
|
|
35
|
-
iniFileFormats =
|
|
38
|
+
iniFileFormats = os.path.join(
|
|
39
|
+
iniDir, '{0}_formats.ini'.format(csi.pipelineName))
|
|
36
40
|
configFormats = ConfigParser()
|
|
37
41
|
configFormats.read(iniFileFormats, encoding=encoding)
|
|
38
42
|
configFormats.optionxform = str # makes it case sensitive
|
|
@@ -41,7 +45,7 @@ configFormats.optionxform = str # makes it case sensitive
|
|
|
41
45
|
def get(conf, section, entry, default=None):
|
|
42
46
|
if conf.has_option(section, entry):
|
|
43
47
|
res = conf.get(section, entry)
|
|
44
|
-
if isinstance(default,
|
|
48
|
+
if isinstance(default, str):
|
|
45
49
|
return res
|
|
46
50
|
else:
|
|
47
51
|
try:
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
r"""
|
|
3
|
+
Data corrections
|
|
4
|
+
----------------
|
|
5
|
+
|
|
6
|
+
General (not pipeline-specific) data corrections were designed in ParSeq for
|
|
7
|
+
the amendment of data distortions. One example of data correction is the
|
|
8
|
+
removal of diffraction peaks arriving at a fluorescence detector during x-ray
|
|
9
|
+
absorption measurements. In this case, diffraction peaks may appear as sharp
|
|
10
|
+
artefacts seen by different detector channels at different x-ray energies. The
|
|
11
|
+
correction can be a simple deletion of a few data points or a replacement by a
|
|
12
|
+
spline segment, where the comparison with undistorted spectra can guide the
|
|
13
|
+
decisions.
|
|
14
|
+
|
|
15
|
+
The ParSeq corrections operate in a transformation node and are applied to all
|
|
16
|
+
data arrays defined in that node. The corrections are calculated following the
|
|
17
|
+
incoming transformations that lead to the node.
|
|
18
|
+
|
|
19
|
+
.. note::
|
|
20
|
+
When setting up a correction that depends on y-coordinates (e,g. spline
|
|
21
|
+
correction) in the ParSeq GUI, make sure that the plot widget does not
|
|
22
|
+
apply a normalization or any other modification affecting the y-axis.
|
|
23
|
+
|
|
24
|
+
In the present version, only 1D nodes can receive corrections. Each correction
|
|
25
|
+
defines a dictionary of parameters. The following corrections are defined.
|
|
26
|
+
|
|
27
|
+
+------------------+------------------+
|
|
28
|
+
| correction | description |
|
|
29
|
+
+==================+==================+
|
|
30
|
+
| delete region | |text_del| |
|
|
31
|
+
+------------------+------------------+
|
|
32
|
+
| scale region | |text_scl| |
|
|
33
|
+
+------------------+------------------+
|
|
34
|
+
| replace region | |
|
|
35
|
+
| by spline | |text_spl| |
|
|
36
|
+
+------------------+------------------+
|
|
37
|
+
| delete spikes | |text_spk| |
|
|
38
|
+
+------------------+------------------+
|
|
39
|
+
| remove data step | |text_stp| |
|
|
40
|
+
+------------------+------------------+
|
|
41
|
+
|
|
42
|
+
.. |text_del| replace::
|
|
43
|
+
(*lim*: 2-sequence)
|
|
44
|
+
All points within the (lim[0], lim[1]) interval are deleted from the node
|
|
45
|
+
arrays.
|
|
46
|
+
|
|
47
|
+
.. |text_scl| replace::
|
|
48
|
+
(*lim*: 2-sequence, *scale*: float)
|
|
49
|
+
All points within the (lim[0], lim[1]) interval are vertically scaled toward
|
|
50
|
+
the straight line connecting the end data points that fall within the
|
|
51
|
+
interval. The scaling factor depends on the vertical distance from the
|
|
52
|
+
`scale` parameter to the straight line.
|
|
53
|
+
|
|
54
|
+
.. |text_spl| replace::
|
|
55
|
+
(*lim*: 2-sequence, *knots*: list of 2-lists ((x, y) points))
|
|
56
|
+
A spline drawn through the given knots replaces the points within the
|
|
57
|
+
(lim[0], lim[1]) interval.
|
|
58
|
+
|
|
59
|
+
.. |text_spk| replace::
|
|
60
|
+
(*lim*: 2-sequence, *cutoff*: float)
|
|
61
|
+
The first y-array defined in the node is used to calculate its second
|
|
62
|
+
difference. The second difference is normalized to its maximum and compared
|
|
63
|
+
with `cutoff`. The exciding points are deleted from the node arrays.
|
|
64
|
+
The automatic cutoff is set as 0.7.
|
|
65
|
+
|
|
66
|
+
.. |text_stp| replace::
|
|
67
|
+
(*left*: float (x-coordinate), *right*: 2-sequence ((x, y) point))
|
|
68
|
+
All data points to the right of the `right` point are shifted vertically by
|
|
69
|
+
the height difference at the `right` point. The points within the interval
|
|
70
|
+
from left to right are linearly shifted from zero at the left to the found
|
|
71
|
+
constant shift at the right.
|
|
72
|
+
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
__author__ = "Konstantin Klementiev"
|
|
76
|
+
__date__ = "22 Nov 2024"
|
|
77
|
+
# !!! SEE CODERULES.TXT !!!
|
|
78
|
+
|
|
79
|
+
import numpy as np
|
|
80
|
+
from scipy.interpolate import InterpolatedUnivariateSpline
|
|
81
|
+
|
|
82
|
+
AUTO_CUTOFF = 0.7 # for 'spikes', fraction of max(d²y)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def calc_correction(x, y, correction, datainds=None):
|
|
86
|
+
if 'lim' not in correction and 'range' in correction: # compatibility
|
|
87
|
+
correction['lim'] = correction.pop('range')
|
|
88
|
+
if correction['kind'] == 'delete':
|
|
89
|
+
lim = correction['lim']
|
|
90
|
+
args = np.argwhere((lim[0] < x) & (x < lim[1]))
|
|
91
|
+
return np.delete(x, args), np.delete(y, args)
|
|
92
|
+
elif correction['kind'] == 'scale':
|
|
93
|
+
lim = correction['lim']
|
|
94
|
+
where = (lim[0] < x) & (x < lim[1])
|
|
95
|
+
wx = x[where]
|
|
96
|
+
if len(wx) == 0:
|
|
97
|
+
return
|
|
98
|
+
wy = y[where]
|
|
99
|
+
if len(wy) == 0:
|
|
100
|
+
return
|
|
101
|
+
dy = wy.max() - wy.min()
|
|
102
|
+
if dy == 0:
|
|
103
|
+
return
|
|
104
|
+
scale = correction['scale']
|
|
105
|
+
factor = (scale - wy.min()) / dy
|
|
106
|
+
yn = np.array(y)
|
|
107
|
+
line = (wy[-1] - wy[0])/(wx[-1] - wx[0])*(wx - wx[0]) + wy[0]
|
|
108
|
+
yn[where] = (wy - line)*factor + line
|
|
109
|
+
return x, yn
|
|
110
|
+
elif correction['kind'] == 'spline':
|
|
111
|
+
lim = correction['lim']
|
|
112
|
+
where = (lim[0] < x) & (x < lim[1])
|
|
113
|
+
wx = x[where]
|
|
114
|
+
if len(wx) == 0:
|
|
115
|
+
return
|
|
116
|
+
yn = np.array(y)
|
|
117
|
+
kns = correction['knots']
|
|
118
|
+
if len(kns) == 1:
|
|
119
|
+
yn[where] = kns[0][1]
|
|
120
|
+
else: # len(knots) >= 2:
|
|
121
|
+
k = min(len(kns)-1, 3)
|
|
122
|
+
try:
|
|
123
|
+
spl = InterpolatedUnivariateSpline(kns[:, 0], kns[:, 1], k=k)
|
|
124
|
+
yn[where] = spl(wx)
|
|
125
|
+
except ValueError:
|
|
126
|
+
return
|
|
127
|
+
return x, yn
|
|
128
|
+
elif correction['kind'] == 'spikes':
|
|
129
|
+
lim, cutoff = correction['lim'], correction['cutoff']
|
|
130
|
+
if cutoff is None:
|
|
131
|
+
return x, y
|
|
132
|
+
elif isinstance(cutoff, str):
|
|
133
|
+
cutoff = AUTO_CUTOFF
|
|
134
|
+
if not (0 < cutoff < 1):
|
|
135
|
+
return x, y
|
|
136
|
+
if datainds is None:
|
|
137
|
+
where = np.argwhere((lim[0] < x) & (x < lim[1])).flatten()
|
|
138
|
+
y2der = np.gradient(np.gradient(y))
|
|
139
|
+
y2derw = y2der[where]
|
|
140
|
+
if len(y2derw) == 0:
|
|
141
|
+
return x, y
|
|
142
|
+
y2derC = abs(y2derw).max() * cutoff
|
|
143
|
+
args = np.argwhere((y2der < -y2derC) | (y2der > y2derC)).flatten()
|
|
144
|
+
argsd = np.intersect1d(where, args)
|
|
145
|
+
else:
|
|
146
|
+
argsd = datainds
|
|
147
|
+
return np.delete(x, argsd), np.delete(y, argsd), argsd
|
|
148
|
+
elif correction['kind'] == 'step':
|
|
149
|
+
left = correction['left']
|
|
150
|
+
right = correction['right']
|
|
151
|
+
inStep = (left < x) & (x < right[0])
|
|
152
|
+
afterStep = x >= right[0]
|
|
153
|
+
eAfterStep = x[afterStep]
|
|
154
|
+
if len(eAfterStep) == 0:
|
|
155
|
+
return
|
|
156
|
+
dyAfter = y[afterStep][0] - right[1]
|
|
157
|
+
yn = np.array(y)
|
|
158
|
+
yn[afterStep] -= dyAfter
|
|
159
|
+
xInStep = x[inStep]
|
|
160
|
+
if len(xInStep) > 0:
|
|
161
|
+
yn[inStep] -= dyAfter / (right[0] - left) * (xInStep - left)
|
|
162
|
+
return x, yn
|
|
@@ -298,7 +298,7 @@ def plotSavedData(plots, lib='mpl'):
|
|
|
298
298
|
ndim = nodeData[2]
|
|
299
299
|
plotFuncName = 'plot{0}D{1}'.format(ndim, lib) # e.g. plot1Dmpl
|
|
300
300
|
plotFunc = globals()[plotFuncName]
|
|
301
|
-
widgets.append(plotFunc(nodeData)) # to keep references to silx
|
|
301
|
+
widgets.append(plotFunc(nodeData)) # to keep references to silx plots
|
|
302
302
|
if lib == 'mpl':
|
|
303
303
|
plt.show() # end plotSavedData
|
|
304
304
|
|
|
@@ -111,7 +111,7 @@ class TreeItem(object):
|
|
|
111
111
|
else:
|
|
112
112
|
res = ""
|
|
113
113
|
if hasattr(self, 'name'): # instance of TreeItem
|
|
114
|
-
if isinstance(self.name,
|
|
114
|
+
if isinstance(self.name, str):
|
|
115
115
|
res = self.name
|
|
116
116
|
elif hasattr(self, 'madeOf'): # instance of Spectrum
|
|
117
117
|
if self.error is not None:
|
|
@@ -119,13 +119,13 @@ class TreeItem(object):
|
|
|
119
119
|
elif self.beingTransformed:
|
|
120
120
|
res = '{0} is {1:.0f}% done'.format(self.beingTransformed,
|
|
121
121
|
self.progress*100)
|
|
122
|
-
elif isinstance(self.madeOf, (
|
|
123
|
-
if isinstance(self.madeOf,
|
|
122
|
+
elif isinstance(self.madeOf, (str, dict, tuple, list)):
|
|
123
|
+
if isinstance(self.madeOf, str):
|
|
124
124
|
res = str(self.madeOf)
|
|
125
125
|
elif isinstance(self.madeOf, (tuple, list)) and\
|
|
126
126
|
'combine' in self.dataFormat:
|
|
127
127
|
what = self.dataFormat['combine']
|
|
128
|
-
if
|
|
128
|
+
if isinstance(self.madeOf[0], str):
|
|
129
129
|
names = self.madeOf
|
|
130
130
|
else:
|
|
131
131
|
names = [it.alias for it in self.madeOf]
|
|
@@ -139,7 +139,7 @@ class TreeItem(object):
|
|
|
139
139
|
res += ': {0}'.format(self.aliasExtra)
|
|
140
140
|
dataSource = self.dataFormat.get('dataSource', [])
|
|
141
141
|
for ds in dataSource:
|
|
142
|
-
if isinstance(ds,
|
|
142
|
+
if isinstance(ds, str):
|
|
143
143
|
if ds.startswith('silx'):
|
|
144
144
|
if res:
|
|
145
145
|
res += '\n'
|
|
@@ -1271,6 +1271,7 @@ class Spectrum(TreeItem):
|
|
|
1271
1271
|
|
|
1272
1272
|
keys = re.findall(r'\[(.*?)\]', colStr)
|
|
1273
1273
|
if len(keys) == 0:
|
|
1274
|
+
colStr = colStr.replace('col', 'Col')
|
|
1274
1275
|
if "Col" in colStr:
|
|
1275
1276
|
regex = re.compile('Col([0-9]*)')
|
|
1276
1277
|
# remove possible duplicates by list(dict.fromkeys())
|
|
@@ -1707,12 +1708,16 @@ class Spectrum(TreeItem):
|
|
|
1707
1708
|
if csi.model is not None:
|
|
1708
1709
|
csi.model.endResetModel()
|
|
1709
1710
|
|
|
1711
|
+
@logger(minLevel=50, attrs=[(0, 'alias'), (1, 'name')])
|
|
1710
1712
|
def make_corrections(self, node):
|
|
1711
|
-
wasCorrected = False
|
|
1712
1713
|
corr_param_name = 'correction_' + node.name
|
|
1713
1714
|
if corr_param_name not in self.transformParams:
|
|
1714
|
-
return
|
|
1715
|
+
return False
|
|
1715
1716
|
corrections = self.transformParams[corr_param_name]
|
|
1717
|
+
if corrections is None:
|
|
1718
|
+
return False
|
|
1719
|
+
|
|
1720
|
+
wasCorrected = False
|
|
1716
1721
|
for correction in corrections:
|
|
1717
1722
|
# if correction['kind'] in ('delete',):
|
|
1718
1723
|
# prop = 'raw'
|
|
@@ -1735,6 +1740,7 @@ class Spectrum(TreeItem):
|
|
|
1735
1740
|
shapeBefore = x.shape
|
|
1736
1741
|
|
|
1737
1742
|
corrKeys = []
|
|
1743
|
+
datainds = None
|
|
1738
1744
|
for k, arr in node.arrays.items():
|
|
1739
1745
|
key = node.get_prop(k, prop)
|
|
1740
1746
|
if key == xkey:
|
|
@@ -1748,15 +1754,16 @@ class Spectrum(TreeItem):
|
|
|
1748
1754
|
# x, y = \
|
|
1749
1755
|
# node.widget.transformWidget.extraPlotTransform(
|
|
1750
1756
|
# self, xkey, x, k, y)
|
|
1751
|
-
res = calc_correction(x, y, correction)
|
|
1757
|
+
res = calc_correction(x, y, correction, datainds)
|
|
1752
1758
|
if res is None:
|
|
1753
1759
|
continue
|
|
1754
1760
|
wasCorrected = True
|
|
1755
|
-
xn, yn = res
|
|
1761
|
+
xn, yn = res[:2]
|
|
1762
|
+
datainds = res[2] if len(res) > 2 else None
|
|
1756
1763
|
setattr(self, key, yn)
|
|
1757
1764
|
corrKeys.append(key)
|
|
1758
1765
|
|
|
1759
|
-
if correction['kind']
|
|
1766
|
+
if correction['kind'] in ('delete', 'spikes'):
|
|
1760
1767
|
for nodeOther in csi.nodes.values():
|
|
1761
1768
|
if nodeOther is node:
|
|
1762
1769
|
continue
|
|
@@ -1776,7 +1783,8 @@ class Spectrum(TreeItem):
|
|
|
1776
1783
|
if key in corrKeys:
|
|
1777
1784
|
continue
|
|
1778
1785
|
if attr is not None and attr.shape == shapeBefore:
|
|
1779
|
-
|
|
1786
|
+
aC = calc_correction(
|
|
1787
|
+
x, attr, correction, datainds)[1]
|
|
1780
1788
|
setattr(self, key, aC)
|
|
1781
1789
|
setattr(self, xkey, xn)
|
|
1782
1790
|
|
|
@@ -310,10 +310,10 @@ class Transform(object):
|
|
|
310
310
|
self.run_pre(params, items, updateUndo)
|
|
311
311
|
|
|
312
312
|
nC = multiprocessing.cpu_count()
|
|
313
|
-
if isinstance(self.nThreads,
|
|
313
|
+
if isinstance(self.nThreads, str):
|
|
314
314
|
self.nThreads = max(nC//2, 1) if self.nThreads.startswith('h')\
|
|
315
315
|
else nC
|
|
316
|
-
if isinstance(self.nProcesses,
|
|
316
|
+
if isinstance(self.nProcesses, str):
|
|
317
317
|
self.nProcesses = max(nC//2, 1) if self.nProcesses.startswith('h')\
|
|
318
318
|
else nC
|
|
319
319
|
|
|
@@ -407,6 +407,7 @@ class Transform(object):
|
|
|
407
407
|
if self.toNode.widget is not None:
|
|
408
408
|
self.toNode.widget.onTransform = True
|
|
409
409
|
if self.sendSignals:
|
|
410
|
+
csi.mainWindow.afterTransformSignal.emit(self.fromNode.widget)
|
|
410
411
|
csi.mainWindow.beforeTransformSignal.emit(self.toNode.widget)
|
|
411
412
|
|
|
412
413
|
# @staticmethod
|
|
@@ -734,6 +735,7 @@ def run_transforms(items, parentItem):
|
|
|
734
735
|
tr.run(dataItems=its)
|
|
735
736
|
if hasattr(tr, 'widget'): # when with GUI
|
|
736
737
|
tr.widget.replotAllDownstream(tr.name)
|
|
738
|
+
|
|
737
739
|
if tr.fromNode is tr.toNode:
|
|
738
740
|
break
|
|
739
741
|
|
|
@@ -18,7 +18,7 @@ A screenshot of ParSeq-XAS (an EXAFS analysis pipeline) as an application
|
|
|
18
18
|
example:
|
|
19
19
|
|
|
20
20
|
.. image:: _images/XAS-foils.gif
|
|
21
|
-
:scale:
|
|
21
|
+
:scale: 60 %
|
|
22
22
|
|
|
23
23
|
Main features
|
|
24
24
|
-------------
|
|
@@ -37,13 +37,13 @@ Main features
|
|
|
37
37
|
- Entering into the analysis pipeline at any node, not only at the head of the
|
|
38
38
|
pipeline.
|
|
39
39
|
|
|
40
|
-
- Creation of cross-data combinations (e.g. averaging,
|
|
40
|
+
- Creation of cross-data combinations (e.g. averaging, PCA) and their
|
|
41
41
|
propagation downstream the pipeline together with the parental data. The
|
|
42
42
|
possibility of termination of the parental data at any selected downstream
|
|
43
43
|
node.
|
|
44
44
|
|
|
45
45
|
- General data correction routines for 1D data: range deletion, scaling,
|
|
46
|
-
replacement by a spline and jump correction.
|
|
46
|
+
replacement by a spline, deletion of spikes and jump correction.
|
|
47
47
|
|
|
48
48
|
- Parallel execution of data transformations with multiprocessing or
|
|
49
49
|
multithreading (can be opted by the pipeline application).
|
|
@@ -51,15 +51,15 @@ Main features
|
|
|
51
51
|
- Optional curve fitting solvers, also executed in parallel for multiple data
|
|
52
52
|
items.
|
|
53
53
|
|
|
54
|
-
- Informative error handling that provides alerts and stack traceback
|
|
54
|
+
- Informative error handling that provides alerts and stack traceback with the
|
|
55
55
|
type and location of the occurred error.
|
|
56
56
|
|
|
57
57
|
- Optional time profiling of the pipeline, as controlled by a command-line
|
|
58
58
|
argument.
|
|
59
59
|
|
|
60
60
|
- Export of the workflow into a project file. Export of data into various data
|
|
61
|
-
formats with accompanied Python scripts that visualize the exported data
|
|
62
|
-
|
|
61
|
+
formats with accompanied Python scripts that visualize the exported data in
|
|
62
|
+
publication-quality plots.
|
|
63
63
|
|
|
64
64
|
- ParSeq understands container files (presently only hdf5) and adds them to
|
|
65
65
|
the system file tree as subfolders. The file tree, including hdf5
|
|
@@ -80,11 +80,19 @@ and curve fits are exemplified by separately installed analysis packages:
|
|
|
80
80
|
- `ParSeq-XAS <https://github.com/kklmn/ParSeq-XAS>`_
|
|
81
81
|
- `ParSeq-XES-scan <https://github.com/kklmn/ParSeq-XES-scan>`_
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
Installation
|
|
84
84
|
------------
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
Install it by pip or conda or get ParSeq from
|
|
87
|
+
`GitHub <https://github.com/kklmn/ParSeq>`_ and use it with or without
|
|
88
|
+
installation.
|
|
89
|
+
See :ref:`detailed installation instructions <instructions>`.
|
|
90
|
+
|
|
91
|
+
Documentation
|
|
92
|
+
-------------
|
|
93
|
+
|
|
94
|
+
The documentation is available online on
|
|
95
|
+
`Read the Docs <http://parseq.readthedocs.io>`_.
|
|
88
96
|
|
|
89
97
|
Launch an example
|
|
90
98
|
-----------------
|
|
@@ -253,10 +253,10 @@ class Fit:
|
|
|
253
253
|
self.run_pre(params, items, updateUndo)
|
|
254
254
|
|
|
255
255
|
nC = multiprocessing.cpu_count()
|
|
256
|
-
if isinstance(self.nThreads,
|
|
256
|
+
if isinstance(self.nThreads, str):
|
|
257
257
|
self.nThreads = max(nC//2, 1) if self.nThreads.startswith('h')\
|
|
258
258
|
else nC
|
|
259
|
-
if isinstance(self.nProcesses,
|
|
259
|
+
if isinstance(self.nProcesses, str):
|
|
260
260
|
self.nProcesses = max(nC//2, 1) if self.nProcesses.startswith('h')\
|
|
261
261
|
else nC
|
|
262
262
|
|
|
@@ -4,6 +4,8 @@ __date__ = "5 Nov 2023"
|
|
|
4
4
|
# !!! SEE CODERULES.TXT !!!
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
|
+
if not hasattr(np, 'trapezoid'):
|
|
8
|
+
np.trapezoid = np.trapz
|
|
7
9
|
from scipy.optimize import curve_fit
|
|
8
10
|
from scipy.interpolate import interp1d
|
|
9
11
|
from scipy.linalg import eigh
|
|
@@ -147,7 +149,8 @@ class EXAFSFit(Fit):
|
|
|
147
149
|
fitw = fit * data.ftfitwindow
|
|
148
150
|
if 'forceFT0' in dtparams:
|
|
149
151
|
if dtparams['forceFT0']:
|
|
150
|
-
fitw -= np.
|
|
152
|
+
fitw -= np.trapezoid(fitw, x=x) / np.trapezoid(
|
|
153
|
+
np.ones_like(fitw), x=x)
|
|
151
154
|
fitft = np.fft.rfft(fitw, n=cls.nfft) * dk/2
|
|
152
155
|
r = np.fft.rfftfreq(cls.nfft, dk/np.pi)
|
|
153
156
|
wherer = r <= dtparams['rmax'] if 'rmax' in dtparams else None
|
|
@@ -202,14 +205,20 @@ class EXAFSFit(Fit):
|
|
|
202
205
|
v['value'] = vMin
|
|
203
206
|
|
|
204
207
|
if kRangeUse:
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
try:
|
|
209
|
+
wherek = (kRange[0] <= x) & (x <= kRange[1])
|
|
210
|
+
except Exception:
|
|
211
|
+
if 'kmin' in dtparams and 'kmax' in dtparams:
|
|
212
|
+
kRange = [dtparams['kmin'], dtparams['kmax']]
|
|
213
|
+
else:
|
|
214
|
+
kRange = [0, x.max()]
|
|
215
|
+
wherek = (kRange[0] <= x) & (x <= kRange[1])
|
|
207
216
|
xw, yw = x[wherek], y[wherek]
|
|
208
|
-
Deltak = kRange[1] - kRange[0]
|
|
217
|
+
Deltak = kRange[1] - kRange[0] \
|
|
218
|
+
if isinstance(kRange, (list, tuple)) else x.max() - x.min()
|
|
209
219
|
else:
|
|
210
220
|
wherek = None
|
|
211
|
-
|
|
212
|
-
xw, yw = x, y
|
|
221
|
+
xw, yw = x, y
|
|
213
222
|
Deltak = x.max() - x.min()
|
|
214
223
|
sigmax = xw**kw
|
|
215
224
|
|
|
@@ -217,8 +226,14 @@ class EXAFSFit(Fit):
|
|
|
217
226
|
dk = x[1] - x[0]
|
|
218
227
|
ft = np.fft.rfft(y, n=cls.nfft) * dk/2
|
|
219
228
|
r = np.fft.rfftfreq(cls.nfft, dk/np.pi)
|
|
220
|
-
|
|
221
|
-
|
|
229
|
+
try:
|
|
230
|
+
wherer = (rRange[0] <= r) & (r <= rRange[1])
|
|
231
|
+
except Exception:
|
|
232
|
+
if 'rmax' in dtparams:
|
|
233
|
+
rRange = [0, dtparams['rmax']]
|
|
234
|
+
else:
|
|
235
|
+
rRange = [0, r.max()]
|
|
236
|
+
wherer = (rRange[0] <= r) & (r <= rRange[1])
|
|
222
237
|
Deltar = rRange[1] - rRange[0]
|
|
223
238
|
rw, ftwr, ftwi = r[wherer], ft.real[wherer], ft.imag[wherer]
|
|
224
239
|
# ftwm = np.abs(ft)[wherer]
|
|
@@ -316,7 +331,9 @@ class EXAFSFit(Fit):
|
|
|
316
331
|
if nu > 0:
|
|
317
332
|
H = cls.get_Hessian_chi2(xw, chi2opt, fitStruct, err, popt, bounds)
|
|
318
333
|
H *= nu / chi2opt
|
|
319
|
-
|
|
334
|
+
diagH = np.array(np.diag(H))
|
|
335
|
+
diagH[diagH < 0] = 1e-28
|
|
336
|
+
Hii = diagH**0.5
|
|
320
337
|
fitProps['corr'] = H / np.dot(Hii.reshape(P, 1), Hii.reshape(1, P))
|
|
321
338
|
|
|
322
339
|
errA = np.sqrt(2) / Hii
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -155,7 +155,7 @@ class AboutDialog(qt.QDialog):
|
|
|
155
155
|
strSphinx = 'Sphinx {0}'.format(sphinx.__version__)
|
|
156
156
|
strSilx = r'silx {0}'.format(versilx)
|
|
157
157
|
strParSeq = '{0}'.format(PARSEQPATH).replace('\\', '/')
|
|
158
|
-
if
|
|
158
|
+
if isinstance(self.parseq_pypi_version, tuple):
|
|
159
159
|
pypiver, curver = self.parseq_pypi_version
|
|
160
160
|
pstr = "`PyPI <https://pypi.python.org/pypi/parseq>`_"
|
|
161
161
|
if curver < pypiver:
|
|
@@ -204,9 +204,9 @@ class AboutDialog(qt.QDialog):
|
|
|
204
204
|
return txt
|
|
205
205
|
|
|
206
206
|
def makeThreadProcessStr(self, nThreads, nProcesses):
|
|
207
|
-
if isinstance(nThreads,
|
|
207
|
+
if isinstance(nThreads, str):
|
|
208
208
|
nThreads = max(nC//2, 1) if nThreads.startswith('h') else nC
|
|
209
|
-
if isinstance(nProcesses,
|
|
209
|
+
if isinstance(nProcesses, str):
|
|
210
210
|
nProcesses = max(nC//2, 1) if nProcesses.startswith('h') else nC
|
|
211
211
|
|
|
212
212
|
res = ''
|