pymodaq 3.6.13__py3-none-any.whl → 4.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/__init__.py +13 -6
- pymodaq/control_modules/__init__.py +0 -7
- pymodaq/control_modules/daq_move.py +965 -2
- pymodaq/control_modules/daq_move_ui.py +319 -0
- pymodaq/control_modules/daq_viewer.py +1573 -3
- pymodaq/control_modules/daq_viewer_ui.py +393 -0
- pymodaq/control_modules/mocks.py +51 -0
- pymodaq/control_modules/move_utility_classes.py +709 -8
- pymodaq/control_modules/utils.py +256 -0
- pymodaq/control_modules/viewer_utility_classes.py +663 -6
- pymodaq/daq_utils.py +89 -0
- pymodaq/dashboard.py +91 -72
- pymodaq/examples/custom_app.py +12 -11
- pymodaq/examples/custom_viewer.py +10 -10
- pymodaq/examples/function_plotter.py +16 -13
- pymodaq/examples/nonlinearscanner.py +8 -6
- pymodaq/examples/parameter_ex.py +7 -7
- pymodaq/examples/preset_MockCamera.xml +1 -0
- pymodaq/extensions/__init__.py +16 -0
- pymodaq/extensions/console.py +76 -0
- pymodaq/{daq_logger.py → extensions/daq_logger.py} +115 -65
- pymodaq/extensions/daq_scan.py +1339 -0
- pymodaq/extensions/daq_scan_ui.py +240 -0
- pymodaq/extensions/h5browser.py +23 -0
- pymodaq/{pid → extensions/pid}/__init__.py +4 -2
- pymodaq/{pid → extensions/pid}/daq_move_PID.py +2 -2
- pymodaq/{pid → extensions/pid}/pid_controller.py +48 -36
- pymodaq/{pid → extensions/pid}/utils.py +52 -6
- pymodaq/extensions/utils.py +40 -0
- pymodaq/post_treatment/__init__.py +6 -0
- pymodaq/{daq_analysis → post_treatment/daq_analysis}/daq_analysis_main.py +17 -17
- pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_main.py +8 -14
- pymodaq/post_treatment/load_and_plot.py +219 -0
- pymodaq/post_treatment/process_to_scalar.py +263 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/run_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat +1 -1
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc +1 -0
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +109784 -109173
- pymodaq/resources/QtDesigner_Ressources/icons.svg +142 -0
- pymodaq/resources/VERSION +1 -1
- pymodaq/resources/config_template.toml +32 -13
- pymodaq/resources/preset_default.xml +1 -1
- pymodaq/{daq_utils → utils}/Tuto innosetup/script_full_setup.iss +1 -1
- pymodaq/utils/__init__.py +0 -29
- pymodaq/utils/abstract/__init__.py +48 -0
- pymodaq/{daq_utils → utils}/abstract/logger.py +7 -3
- pymodaq/utils/array_manipulation.py +379 -8
- pymodaq/{daq_utils → utils}/calibration_camera.py +6 -6
- pymodaq/{daq_utils → utils}/chrono_timer.py +1 -1
- pymodaq/utils/config.py +448 -0
- pymodaq/utils/conftests.py +5 -0
- pymodaq/utils/daq_utils.py +828 -8
- pymodaq/utils/data.py +1873 -7
- pymodaq/{daq_utils → utils}/db/db_logger/db_logger.py +86 -47
- pymodaq/{daq_utils → utils}/db/db_logger/db_logger_models.py +31 -10
- pymodaq/{daq_utils → utils}/enums.py +12 -7
- pymodaq/utils/exceptions.py +37 -0
- pymodaq/utils/factory.py +82 -0
- pymodaq/{daq_utils → utils}/gui_utils/__init__.py +1 -1
- pymodaq/utils/gui_utils/custom_app.py +129 -0
- pymodaq/utils/gui_utils/file_io.py +66 -0
- pymodaq/{daq_utils → utils}/gui_utils/layout.py +2 -2
- pymodaq/{daq_utils → utils}/gui_utils/utils.py +13 -3
- pymodaq/{daq_utils → utils}/gui_utils/widgets/__init__.py +2 -2
- pymodaq/utils/gui_utils/widgets/label.py +24 -0
- pymodaq/{daq_utils → utils}/gui_utils/widgets/lcd.py +12 -7
- pymodaq/{daq_utils → utils}/gui_utils/widgets/push.py +66 -2
- pymodaq/{daq_utils → utils}/gui_utils/widgets/qled.py +6 -4
- pymodaq/utils/gui_utils/widgets/spinbox.py +24 -0
- pymodaq/{daq_utils → utils}/gui_utils/widgets/table.py +2 -2
- pymodaq/utils/h5modules/__init__.py +1 -0
- pymodaq/{daq_utils/h5backend.py → utils/h5modules/backends.py} +200 -112
- pymodaq/utils/h5modules/browsing.py +683 -0
- pymodaq/utils/h5modules/data_saving.py +839 -0
- pymodaq/utils/h5modules/h5logging.py +110 -0
- pymodaq/utils/h5modules/module_saving.py +350 -0
- pymodaq/utils/h5modules/saving.py +914 -0
- pymodaq/utils/h5modules/utils.py +85 -0
- pymodaq/utils/logger.py +64 -6
- pymodaq/utils/managers/action_manager.py +460 -0
- pymodaq/{daq_utils → utils}/managers/batchscan_manager.py +144 -112
- pymodaq/{daq_utils → utils}/managers/modules_manager.py +188 -114
- pymodaq/{daq_utils → utils}/managers/overshoot_manager.py +3 -3
- pymodaq/utils/managers/parameter_manager.py +110 -0
- pymodaq/{daq_utils → utils}/managers/preset_manager.py +17 -13
- pymodaq/{daq_utils → utils}/managers/preset_manager_utils.py +8 -7
- pymodaq/{daq_utils → utils}/managers/remote_manager.py +7 -6
- pymodaq/{daq_utils → utils}/managers/roi_manager.py +148 -57
- pymodaq/utils/math_utils.py +546 -10
- pymodaq/{daq_utils → utils}/messenger.py +5 -1
- pymodaq/utils/parameter/__init__.py +2 -15
- pymodaq/{daq_utils → utils}/parameter/ioxml.py +12 -6
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/__init__.py +1 -3
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/filedir.py +1 -1
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/itemselect.py +3 -0
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/led.py +1 -1
- pymodaq/utils/parameter/pymodaq_ptypes/pixmap.py +161 -0
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/slide.py +1 -1
- pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/table.py +1 -1
- pymodaq/utils/parameter/utils.py +206 -11
- pymodaq/utils/plotting/data_viewers/__init__.py +6 -0
- pymodaq/utils/plotting/data_viewers/viewer.py +393 -0
- pymodaq/utils/plotting/data_viewers/viewer0D.py +251 -0
- pymodaq/utils/plotting/data_viewers/viewer1D.py +574 -0
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer1Dbasic.py +8 -3
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D.py +292 -357
- pymodaq/{daq_utils → utils}/plotting/data_viewers/viewer2D_basic.py +58 -75
- pymodaq/utils/plotting/data_viewers/viewerND.py +738 -0
- pymodaq/{daq_utils → utils}/plotting/gant_chart.py +2 -2
- pymodaq/{daq_utils → utils}/plotting/items/axis_scaled.py +4 -2
- pymodaq/{daq_utils → utils}/plotting/items/image.py +8 -6
- pymodaq/utils/plotting/navigator.py +355 -0
- pymodaq/utils/plotting/scan_selector.py +480 -0
- pymodaq/utils/plotting/utils/axes_viewer.py +88 -0
- pymodaq/utils/plotting/utils/filter.py +538 -0
- pymodaq/utils/plotting/utils/lineout.py +224 -0
- pymodaq/{daq_utils → utils}/plotting/utils/plot_utils.py +196 -84
- pymodaq/{daq_utils → utils}/plotting/utils/signalND.py +21 -13
- pymodaq/utils/plotting/widgets.py +76 -0
- pymodaq/utils/scanner/__init__.py +10 -0
- pymodaq/utils/scanner/scan_factory.py +204 -0
- pymodaq/utils/scanner/scanner.py +271 -0
- pymodaq/utils/scanner/scanners/_1d_scanners.py +117 -0
- pymodaq/utils/scanner/scanners/_2d_scanners.py +293 -0
- pymodaq/utils/scanner/scanners/sequential.py +192 -0
- pymodaq/utils/scanner/scanners/tabular.py +294 -0
- pymodaq/utils/scanner/utils.py +83 -0
- pymodaq/utils/slicing.py +47 -0
- pymodaq/utils/svg/__init__.py +6 -0
- pymodaq/utils/svg/svg_renderer.py +20 -0
- pymodaq/utils/svg/svg_view.py +35 -0
- pymodaq/utils/svg/svg_viewer2D.py +51 -0
- pymodaq/{daq_utils → utils}/tcp_server_client.py +36 -37
- pymodaq/{daq_utils → utils}/tree_layout/tree_layout_main.py +50 -35
- pymodaq/utils/units.py +216 -0
- pymodaq-4.0.1.dist-info/METADATA +159 -0
- {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info}/RECORD +167 -170
- {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info}/WHEEL +1 -2
- pymodaq-4.0.1.dist-info/entry_points.txt +8 -0
- pymodaq/daq_move/daq_move_gui.py +0 -279
- pymodaq/daq_move/daq_move_gui.ui +0 -534
- pymodaq/daq_move/daq_move_main.py +0 -1042
- pymodaq/daq_move/process_from_QtDesigner_DAQ_Move_GUI.bat +0 -2
- pymodaq/daq_move/utility_classes.py +0 -686
- pymodaq/daq_scan.py +0 -2160
- pymodaq/daq_utils/array_manipulation.py +0 -386
- pymodaq/daq_utils/config.py +0 -273
- pymodaq/daq_utils/conftests.py +0 -7
- pymodaq/daq_utils/custom_parameter_tree.py +0 -9
- pymodaq/daq_utils/daq_enums.py +0 -133
- pymodaq/daq_utils/daq_utils.py +0 -1402
- pymodaq/daq_utils/exceptions.py +0 -71
- pymodaq/daq_utils/gui_utils/custom_app.py +0 -103
- pymodaq/daq_utils/gui_utils/file_io.py +0 -75
- pymodaq/daq_utils/gui_utils/widgets/spinbox.py +0 -9
- pymodaq/daq_utils/h5exporter_hyperspy.py +0 -115
- pymodaq/daq_utils/h5exporters.py +0 -242
- pymodaq/daq_utils/h5modules.py +0 -1559
- pymodaq/daq_utils/h5utils.py +0 -241
- pymodaq/daq_utils/managers/action_manager.py +0 -236
- pymodaq/daq_utils/managers/parameter_manager.py +0 -57
- pymodaq/daq_utils/math_utils.py +0 -705
- pymodaq/daq_utils/parameter/__init__.py +0 -1
- pymodaq/daq_utils/parameter/oldpymodaq_ptypes.py +0 -1626
- pymodaq/daq_utils/parameter/pymodaq_ptypes/pixmap.py +0 -85
- pymodaq/daq_utils/parameter/utils.py +0 -136
- pymodaq/daq_utils/plotting/data_viewers/__init__.py +0 -0
- pymodaq/daq_utils/plotting/data_viewers/process_from_QtDesigner_0DViewer_GUI.bat +0 -2
- pymodaq/daq_utils/plotting/data_viewers/viewer0D.py +0 -204
- pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.py +0 -89
- pymodaq/daq_utils/plotting/data_viewers/viewer0D_GUI.ui +0 -131
- pymodaq/daq_utils/plotting/data_viewers/viewer1D.py +0 -781
- pymodaq/daq_utils/plotting/data_viewers/viewerND.py +0 -894
- pymodaq/daq_utils/plotting/data_viewers/viewerbase.py +0 -64
- pymodaq/daq_utils/plotting/items/__init__.py +0 -0
- pymodaq/daq_utils/plotting/navigator.py +0 -500
- pymodaq/daq_utils/plotting/scan_selector.py +0 -289
- pymodaq/daq_utils/plotting/utils/__init__.py +0 -0
- pymodaq/daq_utils/plotting/utils/filter.py +0 -236
- pymodaq/daq_utils/plotting/viewer0D/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewer0D/viewer0D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewer1D/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewer1D/viewer1D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewer1D/viewer1Dbasic.py +0 -4
- pymodaq/daq_utils/plotting/viewer2D/viewer_2D_basic.py +0 -4
- pymodaq/daq_utils/plotting/viewer2D/viewer_2D_main.py +0 -4
- pymodaq/daq_utils/plotting/viewerND/__init__.py +0 -0
- pymodaq/daq_utils/plotting/viewerND/viewerND_main.py +0 -4
- pymodaq/daq_utils/scanner.py +0 -1289
- pymodaq/daq_utils/tree_layout/__init__.py +0 -0
- pymodaq/daq_viewer/__init__.py +0 -0
- pymodaq/daq_viewer/daq_gui_settings.py +0 -237
- pymodaq/daq_viewer/daq_gui_settings.ui +0 -441
- pymodaq/daq_viewer/daq_viewer_main.py +0 -2225
- pymodaq/daq_viewer/process_from_QtDesigner_DAQ_GUI_settings.bat +0 -2
- pymodaq/daq_viewer/utility_classes.py +0 -673
- pymodaq/examples/logger_image/__init__.py +0 -0
- pymodaq/examples/logger_image/logger_displayer.py +0 -121
- pymodaq/examples/logger_image/setup.svg +0 -3119
- pymodaq/examples/logger_image/setup_svg.py +0 -114
- pymodaq/h5browser.py +0 -39
- pymodaq/utils/scanner.py +0 -15
- pymodaq-3.6.13.dist-info/METADATA +0 -39
- pymodaq-3.6.13.dist-info/entry_points.txt +0 -8
- pymodaq-3.6.13.dist-info/top_level.txt +0 -1
- /pymodaq/{daq_analysis → post_treatment/daq_analysis}/__init__.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/__init__.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.py +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/daq_measurement_GUI.ui +0 -0
- /pymodaq/{daq_measurement → post_treatment/daq_measurement}/process_from_QtDesigner_DAQ_Measurement_GUI.bat +0 -0
- /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.odt +0 -0
- /pymodaq/{daq_utils → utils}/Tuto innosetup/Tuto innosetup.pdf +0 -0
- /pymodaq/{daq_move → utils/db}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils/db/db_logger}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/gui_utils/dock.py +0 -0
- /pymodaq/{daq_utils → utils}/gui_utils/list_picker.py +0 -0
- /pymodaq/{daq_utils/abstract → utils/managers}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/bool.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/date.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/list.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/numeric.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/tableview.py +0 -0
- /pymodaq/{daq_utils → utils}/parameter/pymodaq_ptypes/text.py +0 -0
- /pymodaq/{daq_utils/db → utils/plotting}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/plotting/image_viewer.py +0 -0
- /pymodaq/{daq_utils/db/db_logger → utils/plotting/items}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/plotting/items/crosshair.py +0 -0
- /pymodaq/{daq_utils/managers → utils/plotting/utils}/__init__.py +0 -0
- /pymodaq/{daq_utils → utils}/qvariant.py +0 -0
- /pymodaq/{daq_utils/plotting/viewer2D → utils/scanner/scanners}/__init__.py +0 -0
- /pymodaq/{daq_utils/plotting → utils/tree_layout}/__init__.py +0 -0
- {pymodaq-3.6.13.dist-info → pymodaq-4.0.1.dist-info/licenses}/LICENSE +0 -0
pymodaq/daq_utils/exceptions.py
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
class DAQ_ScanException(Exception):
|
|
2
|
-
"""Raised when an error occur within the DAQ_Scan"""
|
|
3
|
-
pass
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ScannerException(Exception):
|
|
7
|
-
"""Raised when there is an error related to the Scanner class (see pymodaq.da_utils.scanner)"""
|
|
8
|
-
pass
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class DetectorError(Exception):
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ActuatorError(Exception):
|
|
16
|
-
pass
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class ViewerError(Exception):
|
|
20
|
-
pass
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class DataSourceError(Exception):
|
|
24
|
-
pass
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class InvalidExport(Exception):
|
|
28
|
-
pass
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
class InvalidGroupType(Exception):
|
|
32
|
-
pass
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class InvalidSave(Exception):
|
|
36
|
-
pass
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
class InvalidGroupDataType(Exception):
|
|
40
|
-
pass
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
class InvalidDataType(Exception):
|
|
44
|
-
pass
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class InvalidDataDimension(Exception):
|
|
48
|
-
pass
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class InvalidScanType(Exception):
|
|
52
|
-
pass
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
class ExpectedError(Exception):
|
|
56
|
-
"""Raised in the tests made for pymodaq plugins"""
|
|
57
|
-
pass
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
class Expected_1(ExpectedError):
|
|
61
|
-
"""Expected error 1 for pymodaq tests"""
|
|
62
|
-
pass
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
class Expected_2(ExpectedError):
|
|
66
|
-
"""Expected error 2 for pymodaq tests"""
|
|
67
|
-
pass
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
class Expected_3(ExpectedError):
|
|
71
|
-
"""Expected error 3 for pymodaq tests"""
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
from qtpy.QtCore import QObject, QLocale
|
|
2
|
-
from pymodaq.daq_utils.gui_utils.dock import DockArea
|
|
3
|
-
from pymodaq.daq_utils.managers.action_manager import ActionManager
|
|
4
|
-
from pymodaq.daq_utils.managers.parameter_manager import ParameterManager
|
|
5
|
-
from pymodaq.daq_utils.managers.modules_manager import ModulesManager
|
|
6
|
-
from pyqtgraph.dockarea import DockArea
|
|
7
|
-
from qtpy import QtCore, QtWidgets
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class CustomApp(QObject, ActionManager, ParameterManager):
|
|
11
|
-
"""
|
|
12
|
-
Implements the MixIns ActionManager and ParameterManager methods and attributes, you have to subclass it and make
|
|
13
|
-
concrete implementation of a given number of methods:
|
|
14
|
-
|
|
15
|
-
* setup_actions: mandatory, see ActionManager
|
|
16
|
-
* value_changed: non mandatory, see ParameterManager
|
|
17
|
-
* child_added: non mandatory, see ParameterManager
|
|
18
|
-
* param_deleted: non mandatory, see ParameterManager
|
|
19
|
-
* setup_docks: mandatory
|
|
20
|
-
* setup_menu: non mandatory
|
|
21
|
-
* connect_things: mandatory
|
|
22
|
-
"""
|
|
23
|
-
# custom signal that will be fired sometimes. Could be connected to an external object method or an internal method
|
|
24
|
-
log_signal = QtCore.Signal(str)
|
|
25
|
-
|
|
26
|
-
# list of dicts enabling the settings tree on the user interface
|
|
27
|
-
params = []
|
|
28
|
-
|
|
29
|
-
def __init__(self, dockarea: DockArea, dashboard=None):
|
|
30
|
-
QObject.__init__(self)
|
|
31
|
-
ActionManager.__init__(self)
|
|
32
|
-
ParameterManager.__init__(self)
|
|
33
|
-
QLocale.setDefault(QLocale(QLocale.English, QLocale.UnitedStates))
|
|
34
|
-
|
|
35
|
-
if not isinstance(dockarea, DockArea):
|
|
36
|
-
raise Exception('no valid parent container, expected a DockArea')
|
|
37
|
-
|
|
38
|
-
self.dockarea = dockarea
|
|
39
|
-
self.mainwindow = dockarea.parent()
|
|
40
|
-
self.dashboard = dashboard
|
|
41
|
-
|
|
42
|
-
self.docks = dict([])
|
|
43
|
-
self.statusbar = None
|
|
44
|
-
self._toolbar = QtWidgets.QToolBar()
|
|
45
|
-
|
|
46
|
-
if self.mainwindow is not None:
|
|
47
|
-
self.mainwindow.addToolBar(self._toolbar)
|
|
48
|
-
self.statusbar = self.mainwindow.statusBar()
|
|
49
|
-
|
|
50
|
-
self.set_toolbar(self._toolbar)
|
|
51
|
-
|
|
52
|
-
def setup_ui(self):
|
|
53
|
-
self.setup_docks()
|
|
54
|
-
|
|
55
|
-
self.setup_actions() # see ActionManager MixIn class
|
|
56
|
-
|
|
57
|
-
self.setup_menu()
|
|
58
|
-
|
|
59
|
-
self.connect_things()
|
|
60
|
-
|
|
61
|
-
def setup_docks(self):
|
|
62
|
-
"""
|
|
63
|
-
Mandatory method to be subclassed to setup the docks layout
|
|
64
|
-
for instance:
|
|
65
|
-
|
|
66
|
-
self.docks['ADock'] = gutils.Dock('ADock name)
|
|
67
|
-
self.dockarea.addDock(self.docks['ADock"])
|
|
68
|
-
self.docks['AnotherDock'] = gutils.Dock('AnotherDock name)
|
|
69
|
-
self.dockarea.addDock(self.docks['AnotherDock"], 'bottom', self.docks['ADock"])
|
|
70
|
-
|
|
71
|
-
See Also
|
|
72
|
-
########
|
|
73
|
-
pyqtgraph.dockarea.Dock
|
|
74
|
-
"""
|
|
75
|
-
raise NotImplementedError
|
|
76
|
-
|
|
77
|
-
def setup_menu(self):
|
|
78
|
-
"""
|
|
79
|
-
Non mandatory method to be subclassed in order to create a menubar
|
|
80
|
-
create menu for actions contained into the self._actions, for instance:
|
|
81
|
-
|
|
82
|
-
For instance:
|
|
83
|
-
|
|
84
|
-
file_menu = self._menubar.addMenu('File')
|
|
85
|
-
self.affect_to('load', file_menu)
|
|
86
|
-
self.affect_to('save', file_menu)
|
|
87
|
-
|
|
88
|
-
file_menu.addSeparator()
|
|
89
|
-
self.affect_to('quit', file_menu)
|
|
90
|
-
|
|
91
|
-
See Also
|
|
92
|
-
--------
|
|
93
|
-
pymodaq.daq_utils.managers.action_manager.ActionManager
|
|
94
|
-
"""
|
|
95
|
-
pass
|
|
96
|
-
|
|
97
|
-
def connect_things(self):
|
|
98
|
-
raise NotImplementedError
|
|
99
|
-
|
|
100
|
-
@property
|
|
101
|
-
def modules_manager(self) -> ModulesManager:
|
|
102
|
-
if self.dashboard is not None:
|
|
103
|
-
return self.dashboard.modules_manager
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
from pymodaq.daq_utils.config import Config
|
|
4
|
-
from qtpy import QtWidgets
|
|
5
|
-
|
|
6
|
-
config = Config()
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def select_file(start_path=config('data_saving', 'h5file', 'save_path'), save=True, ext=None, filter=None):
|
|
10
|
-
"""Save or open a file with Qt5 file dialog, to be used within an Qt5 loop.
|
|
11
|
-
|
|
12
|
-
Usage::
|
|
13
|
-
|
|
14
|
-
from pymodaq.daq_utils.daq_utils import select_file
|
|
15
|
-
select_file(start_path="C:\\test.h5",save=True,ext='h5')
|
|
16
|
-
|
|
17
|
-
=============== ======================================= ===========================================================================
|
|
18
|
-
**Parameters** **Type** **Description**
|
|
19
|
-
|
|
20
|
-
*start_path* Path object or str or None, optional the path Qt5 will open in te dialog
|
|
21
|
-
*save* bool, optional * if True, a savefile dialog will open in order to set a savefilename
|
|
22
|
-
* if False, a openfile dialog will open in order to open an existing file
|
|
23
|
-
*ext* str, optional the extension of the file to be saved or opened
|
|
24
|
-
=============== ======================================= ===========================================================================
|
|
25
|
-
|
|
26
|
-
Returns
|
|
27
|
-
-------
|
|
28
|
-
Path object
|
|
29
|
-
the Path object pointing to the file
|
|
30
|
-
|
|
31
|
-
Examples
|
|
32
|
-
--------
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"""
|
|
37
|
-
if ext is None:
|
|
38
|
-
ext = '.h5'
|
|
39
|
-
|
|
40
|
-
if filter is None:
|
|
41
|
-
if not save:
|
|
42
|
-
if not isinstance(ext, list):
|
|
43
|
-
ext = [ext]
|
|
44
|
-
filter = "Data files ("
|
|
45
|
-
for ext_tmp in ext:
|
|
46
|
-
filter += '*.' + ext_tmp + " "
|
|
47
|
-
filter += ")"
|
|
48
|
-
|
|
49
|
-
if start_path is not None:
|
|
50
|
-
if not isinstance(start_path, str):
|
|
51
|
-
start_path = str(start_path)
|
|
52
|
-
if save:
|
|
53
|
-
# fname = QtWidgets.QFileDialog.getSaveFileName(None, 'Enter a .' + ext + ' file name', start_path,
|
|
54
|
-
# ext + " file (*." + ext + ")")
|
|
55
|
-
fname = QtWidgets.QFileDialog.getSaveFileName(None, 'Enter a file name', start_path,
|
|
56
|
-
filter)
|
|
57
|
-
else:
|
|
58
|
-
fname = QtWidgets.QFileDialog.getOpenFileName(None, 'Select a file name', start_path, filter)
|
|
59
|
-
|
|
60
|
-
fname = fname[0]
|
|
61
|
-
if fname != '': # execute if the user didn't cancel the file selection
|
|
62
|
-
fname = Path(fname)
|
|
63
|
-
# if save:
|
|
64
|
-
# parent = fname.parent
|
|
65
|
-
# filename = fname.stem
|
|
66
|
-
# fname = parent.joinpath(filename + "." + ext) # forcing the right extension on the filename
|
|
67
|
-
return fname # fname is a Path object
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if __name__ == '__main__':
|
|
71
|
-
import sys
|
|
72
|
-
app = QtWidgets.QApplication(sys.argv)
|
|
73
|
-
file = select_file(save=True, filter="Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)")
|
|
74
|
-
print(file)
|
|
75
|
-
sys.exit(app.exec_())
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
# Standard imports
|
|
2
|
-
|
|
3
|
-
# 3rd party imports
|
|
4
|
-
import numpy as np
|
|
5
|
-
import hyperspy.api_nogui as hs
|
|
6
|
-
|
|
7
|
-
# project imports
|
|
8
|
-
from pymodaq.daq_utils.h5backend import Node
|
|
9
|
-
from pymodaq.daq_utils.h5utils import get_h5_data_from_node, extract_axis, verify_axis_data_uniformity
|
|
10
|
-
from pymodaq.daq_utils.h5exporters import ExporterFactory, H5Exporter
|
|
11
|
-
from pymodaq.daq_utils.daq_utils import set_logger, get_module_name
|
|
12
|
-
|
|
13
|
-
# This is needed to log
|
|
14
|
-
logger = set_logger(get_module_name(__file__))
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@ExporterFactory.register_exporter()
|
|
18
|
-
class H5hspyExporter(H5Exporter):
|
|
19
|
-
""" Exporter object for saving nodes as hspy files"""
|
|
20
|
-
|
|
21
|
-
FORMAT_DESCRIPTION = "Hyperspy file format"
|
|
22
|
-
FORMAT_EXTENSION = "hspy"
|
|
23
|
-
|
|
24
|
-
def _export_data(self, node: Node, filename) -> None:
|
|
25
|
-
"""Exporting a .h5 node as a hyperspy object"""
|
|
26
|
-
|
|
27
|
-
# first verify if the node type is compatible with export. Only data nodes are.
|
|
28
|
-
nodetype = node.attrs['type']
|
|
29
|
-
if nodetype == 'data':
|
|
30
|
-
# If yes we can use this function (the same for plotting in h5browser) to extract information
|
|
31
|
-
data, axes, nav_axes, is_spread = get_h5_data_from_node(node)
|
|
32
|
-
data = data.reshape(data.shape, order='F')
|
|
33
|
-
logger.debug(f"extracted data of shape {data.shape}")
|
|
34
|
-
logger.debug(f"extracted axes: {axes}")
|
|
35
|
-
|
|
36
|
-
# get_h5_data_from_node will return sometimes empty axes that we must yeet.
|
|
37
|
-
axes_keys_to_remove = []
|
|
38
|
-
for key, ax in axes.items():
|
|
39
|
-
if ax['data'] is None:
|
|
40
|
-
logger.warning(f'Dropping axis {key} due to empty data')
|
|
41
|
-
axes_keys_to_remove.append(key)
|
|
42
|
-
for key in axes_keys_to_remove:
|
|
43
|
-
del axes[key]
|
|
44
|
-
|
|
45
|
-
else:
|
|
46
|
-
# Else just raise an error.
|
|
47
|
-
raise NotImplementedError(f"hspy export not supported for nodes of type {nodetype}'. "
|
|
48
|
-
f"Export from the data node instead.")
|
|
49
|
-
|
|
50
|
-
# Verify that this is not an adaptive scan. If it is we throw and say it is not supported.
|
|
51
|
-
if is_spread:
|
|
52
|
-
raise NotImplementedError(f"hspy export not supported for adaptive scan data.")
|
|
53
|
-
|
|
54
|
-
# Then we build the hyperspy axes objects.
|
|
55
|
-
hyperspy_axes = []
|
|
56
|
-
for key, ax in axes.items():
|
|
57
|
-
logger.info(f"Extracting axis {ax['label']}.")
|
|
58
|
-
unique_ax = extract_axis(ax)
|
|
59
|
-
try:
|
|
60
|
-
indexv = data.shape.index(len(unique_ax))
|
|
61
|
-
logger.info(f"{ax['label']}, size {len(unique_ax)}, data index: {indexv}")
|
|
62
|
-
except ValueError:
|
|
63
|
-
raise ValueError(f"Signal axis of length {len(unique_ax)} does not match any "
|
|
64
|
-
f"dimension in data of shape {data.shape} ")
|
|
65
|
-
is_nav = key.startswith('nav')
|
|
66
|
-
hyperspy_axes.append(self.build_hyperspy_axis(unique_ax, data_idx=indexv, label=ax['label'],
|
|
67
|
-
unit=ax['units'], navigate=is_nav))
|
|
68
|
-
|
|
69
|
-
ordered_axes = sorted(hyperspy_axes, key=lambda d: d['index_in_array'])
|
|
70
|
-
for ax in ordered_axes:
|
|
71
|
-
del ax['index_in_array']
|
|
72
|
-
# Then we build the hyperspy object. First we must know its dimensionality
|
|
73
|
-
# from the number of signal axes.
|
|
74
|
-
dim = len(axes) - len(nav_axes)
|
|
75
|
-
if dim == 1:
|
|
76
|
-
# Then signal1D
|
|
77
|
-
sig = hs.signals.Signal1D(data=data, original_metadata={}, axes=ordered_axes)
|
|
78
|
-
elif dim == 2:
|
|
79
|
-
# Then signal2D
|
|
80
|
-
sig = hs.signals.Signal2D(data=data, original_metadata={}, axes=ordered_axes)
|
|
81
|
-
else:
|
|
82
|
-
# Then basesignal
|
|
83
|
-
sig = hs.signals.BaseSignal(data=data, original_metadata={}, axes=ordered_axes)
|
|
84
|
-
|
|
85
|
-
# Finally save
|
|
86
|
-
sig.save(filename)
|
|
87
|
-
|
|
88
|
-
def build_hyperspy_axis(self, ax_data: np.ndarray, data_idx: int,
|
|
89
|
-
label: str, unit: str, navigate: bool) -> dict:
|
|
90
|
-
"""Build an axis based on the input data. Choose between a UniformDataAxis or
|
|
91
|
-
DataAxis object based on a quick linearity check of the input data."""
|
|
92
|
-
offset, scale = verify_axis_data_uniformity(ax_data)
|
|
93
|
-
if offset is not None:
|
|
94
|
-
axis_dict = {'_type': 'UniformDataAxis',
|
|
95
|
-
'index_in_array': data_idx,
|
|
96
|
-
'name': label,
|
|
97
|
-
'units': unit,
|
|
98
|
-
'navigate': navigate,
|
|
99
|
-
'size': len(ax_data),
|
|
100
|
-
'scale': scale,
|
|
101
|
-
'offset': offset}
|
|
102
|
-
else:
|
|
103
|
-
axis_dict = {'_type': 'DataAxis',
|
|
104
|
-
'index_in_array': data_idx,
|
|
105
|
-
'name': label,
|
|
106
|
-
'units': unit,
|
|
107
|
-
'navigate': navigate,
|
|
108
|
-
'size': len(ax_data),
|
|
109
|
-
'axis': ax_data}
|
|
110
|
-
|
|
111
|
-
return axis_dict
|
|
112
|
-
|
|
113
|
-
def build_hyperspy_original_metadata(self, node: Node):
|
|
114
|
-
"""Build original metadata dictionary"""
|
|
115
|
-
pass
|
pymodaq/daq_utils/h5exporters.py
DELETED
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
# Standard imports
|
|
2
|
-
from abc import ABCMeta, abstractmethod
|
|
3
|
-
from typing import Callable
|
|
4
|
-
|
|
5
|
-
# 3rd party imports
|
|
6
|
-
import numpy as np
|
|
7
|
-
|
|
8
|
-
# project imports
|
|
9
|
-
from pymodaq.daq_utils.h5backend import H5Backend, Node
|
|
10
|
-
from pymodaq.daq_utils.daq_utils import set_logger, get_module_name
|
|
11
|
-
|
|
12
|
-
logger = set_logger(get_module_name(__file__))
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class ExporterFactory:
|
|
16
|
-
"""The factory class for creating executors"""
|
|
17
|
-
|
|
18
|
-
exporters_registry = {}
|
|
19
|
-
file_filters = {}
|
|
20
|
-
|
|
21
|
-
@classmethod
|
|
22
|
-
def register_exporter(cls) -> Callable:
|
|
23
|
-
"""Class decorator method to register exporter class to the internal registry. Must be used as
|
|
24
|
-
decorator above the definition of an H5Exporter class. H5Exporter must implement specific class
|
|
25
|
-
attributes and methods, see definition: h5node_exporter.H5Exporter
|
|
26
|
-
|
|
27
|
-
See h5node_exporter.H5txtExporter and h5node_exporter.H5txtExporter for usage examples.
|
|
28
|
-
|
|
29
|
-
returns:
|
|
30
|
-
the exporter class
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
def inner_wrapper(wrapped_class) -> Callable:
|
|
34
|
-
extension = wrapped_class.FORMAT_EXTENSION
|
|
35
|
-
# Warn if overriding existing exporter
|
|
36
|
-
if extension in cls.exporters_registry:
|
|
37
|
-
logger.warning(f"Exporter for the .{extension} format already exists and will be replaced")
|
|
38
|
-
|
|
39
|
-
# Register extension
|
|
40
|
-
cls.exporters_registry[extension] = wrapped_class
|
|
41
|
-
cls.file_filters[extension] = wrapped_class.FORMAT_DESCRIPTION
|
|
42
|
-
# Return wrapped_class
|
|
43
|
-
return wrapped_class
|
|
44
|
-
|
|
45
|
-
# Return decorated function
|
|
46
|
-
return inner_wrapper
|
|
47
|
-
|
|
48
|
-
@classmethod
|
|
49
|
-
def create_exporter(cls, extension: str):
|
|
50
|
-
"""Factory command to create the exporter object.
|
|
51
|
-
|
|
52
|
-
This method gets the appropriate executor class from the registry
|
|
53
|
-
and instantiates it.
|
|
54
|
-
|
|
55
|
-
Args:
|
|
56
|
-
extension (str): the extension of the file that will be exported
|
|
57
|
-
|
|
58
|
-
returns:
|
|
59
|
-
an instance of the executor created
|
|
60
|
-
"""
|
|
61
|
-
if extension not in cls.exporters_registry:
|
|
62
|
-
raise ValueError(f".{extension} is not a supported file format.")
|
|
63
|
-
|
|
64
|
-
exporter_class = cls.exporters_registry[extension]
|
|
65
|
-
|
|
66
|
-
exporter = exporter_class()
|
|
67
|
-
|
|
68
|
-
return exporter
|
|
69
|
-
|
|
70
|
-
@classmethod
|
|
71
|
-
def get_file_filters(cls):
|
|
72
|
-
"""Create the file filters string"""
|
|
73
|
-
tmplist = [f"{v} (*.{k})" for k, v in cls.file_filters.items()]
|
|
74
|
-
return ";;".join(tmplist)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
class H5Exporter(metaclass=ABCMeta):
|
|
78
|
-
"""Base class for an exporter. """
|
|
79
|
-
|
|
80
|
-
# This is to define an abstract class attribute
|
|
81
|
-
@classmethod
|
|
82
|
-
@property
|
|
83
|
-
@abstractmethod
|
|
84
|
-
def FORMAT_DESCRIPTION(cls):
|
|
85
|
-
"""str: file format description as a short text. eg: text file"""
|
|
86
|
-
raise NotImplementedError
|
|
87
|
-
|
|
88
|
-
@classmethod
|
|
89
|
-
@property
|
|
90
|
-
@abstractmethod
|
|
91
|
-
def FORMAT_EXTENSION(cls):
|
|
92
|
-
"""str: File format extension. eg: txt"""
|
|
93
|
-
raise NotImplementedError
|
|
94
|
-
|
|
95
|
-
def __init__(self):
|
|
96
|
-
"""Abstract Exporter Constructor"""
|
|
97
|
-
pass
|
|
98
|
-
|
|
99
|
-
@abstractmethod
|
|
100
|
-
def _export_data(self, node: Node, filename: str) -> None:
|
|
101
|
-
"""Abstract method to save a .h5 node to a file"""
|
|
102
|
-
pass
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
@ExporterFactory.register_exporter()
|
|
106
|
-
class H5h5Exporter(H5Exporter):
|
|
107
|
-
""" Exporter object for saving nodes as single h5 files"""
|
|
108
|
-
|
|
109
|
-
FORMAT_DESCRIPTION = "Single node h5 file"
|
|
110
|
-
FORMAT_EXTENSION = "h5"
|
|
111
|
-
|
|
112
|
-
def _export_data(self, node: Node, filename: str) -> None:
|
|
113
|
-
"""Export an h5 node"""
|
|
114
|
-
# This should allow to get the base file object
|
|
115
|
-
if node.backend == 'tables':
|
|
116
|
-
basefile = node.node._v_file
|
|
117
|
-
basefile.copy_file(dstfilename=str(filename), overwrite=False)
|
|
118
|
-
else:
|
|
119
|
-
import h5py
|
|
120
|
-
with h5py.File(filename, 'w') as f_dest:
|
|
121
|
-
node.node.h5file.copy(self.h5file, f_dest)
|
|
122
|
-
|
|
123
|
-
# basefile = node.get_file()
|
|
124
|
-
# basefile.copy_file(dstfilename=str(filename), overwrite=False)
|
|
125
|
-
|
|
126
|
-
new_file = H5Backend(backend="tables")
|
|
127
|
-
new_file.open_file(str(filename), 'a')
|
|
128
|
-
|
|
129
|
-
new_file.h5file.move_node(self.get_node_path(node), newparent=new_file.h5file.get_node('/'))
|
|
130
|
-
new_file.h5file.remove_node('/Raw_datas', recursive=True)
|
|
131
|
-
new_file.close_file()
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
@ExporterFactory.register_exporter()
|
|
135
|
-
class H5txtExporter(H5Exporter):
|
|
136
|
-
""" Exporter object for saving nodes as txt files"""
|
|
137
|
-
|
|
138
|
-
FORMAT_DESCRIPTION = "Text files"
|
|
139
|
-
FORMAT_EXTENSION = "txt"
|
|
140
|
-
|
|
141
|
-
def _export_data(self, node: Node, filename: str) -> None:
|
|
142
|
-
"""Export the node as a .txt file format"""
|
|
143
|
-
if 'ARRAY' in node.attrs['CLASS']:
|
|
144
|
-
data = node.read()
|
|
145
|
-
if not isinstance(data, np.ndarray):
|
|
146
|
-
# in case one has a list of same objects (array of strings for instance, logger or other)
|
|
147
|
-
data = np.array(data)
|
|
148
|
-
np.savetxt(filename, data, '%s', '\t')
|
|
149
|
-
else:
|
|
150
|
-
np.savetxt(filename, data, '%.6e', '\t')
|
|
151
|
-
elif 'GROUP' in node.attrs['CLASS']:
|
|
152
|
-
data_tot = []
|
|
153
|
-
header = []
|
|
154
|
-
dtypes = []
|
|
155
|
-
fmts = []
|
|
156
|
-
for subnode_name, subnode in node.children().items():
|
|
157
|
-
if 'ARRAY' in subnode.attrs['CLASS']:
|
|
158
|
-
if len(subnode.attrs['shape']) == 1:
|
|
159
|
-
data = subnode.read()
|
|
160
|
-
if not isinstance(data, np.ndarray):
|
|
161
|
-
# in case one has a list of same objects (array of strings for instance, logger or other)
|
|
162
|
-
data = np.array(data)
|
|
163
|
-
data_tot.append(data)
|
|
164
|
-
dtypes.append((subnode_name, data.dtype))
|
|
165
|
-
header.append(subnode_name)
|
|
166
|
-
if data.dtype.char == 'U':
|
|
167
|
-
fmt = '%s' # for strings
|
|
168
|
-
elif data.dtype.char == 'l':
|
|
169
|
-
fmt = '%d' # for integers
|
|
170
|
-
else:
|
|
171
|
-
fmt = '%.6f' # for decimal numbers
|
|
172
|
-
fmts.append(fmt)
|
|
173
|
-
|
|
174
|
-
data_trans = np.array(list(zip(*data_tot)), dtype=dtypes)
|
|
175
|
-
np.savetxt(filename, data_trans, fmts, '\t', header='#' + '\t'.join(header))
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
@ExporterFactory.register_exporter()
|
|
179
|
-
class H5asciiExporter(H5Exporter):
|
|
180
|
-
""" Exporter object for saving nodes as txt files"""
|
|
181
|
-
|
|
182
|
-
FORMAT_DESCRIPTION = "Ascii file"
|
|
183
|
-
FORMAT_EXTENSION = "ascii"
|
|
184
|
-
|
|
185
|
-
def _export_data(self, node: Node, filename: str) -> None:
|
|
186
|
-
if 'ARRAY' in node.attrs['CLASS']:
|
|
187
|
-
data = node.read()
|
|
188
|
-
if not isinstance(data, np.ndarray):
|
|
189
|
-
# in case one has a list of same objects (array of strings for instance, logger or other)
|
|
190
|
-
data = np.array(data)
|
|
191
|
-
np.savetxt(filename,
|
|
192
|
-
data.T if len(data.shape) > 1 else [data],
|
|
193
|
-
'%s', '\t')
|
|
194
|
-
else:
|
|
195
|
-
np.savetxt(filename,
|
|
196
|
-
data.T if len(data.shape) > 1 else [data],
|
|
197
|
-
'%.6e', '\t')
|
|
198
|
-
|
|
199
|
-
elif 'GROUP' in node.attrs['CLASS']:
|
|
200
|
-
data_tot = []
|
|
201
|
-
header = []
|
|
202
|
-
dtypes = []
|
|
203
|
-
fmts = []
|
|
204
|
-
for subnode_name, subnode in node.children().items():
|
|
205
|
-
if 'ARRAY' in subnode.attrs['CLASS']:
|
|
206
|
-
if len(subnode.attrs['shape']) == 1:
|
|
207
|
-
data = subnode.read()
|
|
208
|
-
if not isinstance(data, np.ndarray):
|
|
209
|
-
# in case one has a list of same objects (array of strings for instance, logger or other)
|
|
210
|
-
data = np.array(data)
|
|
211
|
-
data_tot.append(data)
|
|
212
|
-
dtypes.append((subnode_name, data.dtype))
|
|
213
|
-
header.append(subnode_name)
|
|
214
|
-
if data.dtype.char == 'U':
|
|
215
|
-
fmt = '%s' # for strings
|
|
216
|
-
elif data.dtype.char == 'l':
|
|
217
|
-
fmt = '%d' # for integers
|
|
218
|
-
else:
|
|
219
|
-
fmt = '%.6f' # for decimal numbers
|
|
220
|
-
fmts.append(fmt)
|
|
221
|
-
|
|
222
|
-
data_trans = np.array(list(zip(*data_tot)), dtype=dtypes)
|
|
223
|
-
|
|
224
|
-
np.savetxt(filename, data_trans, fmts, '\t', header='#' + '\t'.join(header))
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
@ExporterFactory.register_exporter()
|
|
228
|
-
class H5npyExporter(H5Exporter):
|
|
229
|
-
""" Exporter object for saving nodes as npy files"""
|
|
230
|
-
|
|
231
|
-
FORMAT_DESCRIPTION = "Binary NumPy format"
|
|
232
|
-
FORMAT_EXTENSION = "npy"
|
|
233
|
-
|
|
234
|
-
def _export_data(self, node: Node, filename: str) -> None:
|
|
235
|
-
"""Export the node as a numpy binary file format"""
|
|
236
|
-
# String __contain__ method will evaluate to True for CARRAY,EARRAY,VLARRAY,stringARRAY
|
|
237
|
-
if 'ARRAY' in node.attrs['CLASS']:
|
|
238
|
-
data = node.read()
|
|
239
|
-
if not isinstance(data, np.ndarray):
|
|
240
|
-
data = np.array(data)
|
|
241
|
-
|
|
242
|
-
np.save(filename, data)
|