pymodaq 4.2.4__py3-none-any.whl → 5.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymodaq might be problematic. Click here for more details.
- pymodaq/__init__.py +30 -23
- pymodaq/control_modules/daq_move.py +27 -14
- pymodaq/control_modules/daq_move_ui.py +28 -12
- pymodaq/control_modules/daq_viewer.py +38 -28
- pymodaq/control_modules/daq_viewer_ui.py +6 -6
- pymodaq/control_modules/mocks.py +1 -1
- pymodaq/control_modules/move_utility_classes.py +19 -10
- pymodaq/control_modules/utils.py +18 -12
- pymodaq/control_modules/viewer_utility_classes.py +13 -4
- pymodaq/dashboard.py +164 -115
- pymodaq/examples/custom_app.py +13 -16
- pymodaq/examples/custom_viewer.py +6 -6
- pymodaq/examples/function_plotter.py +13 -12
- pymodaq/examples/parameter_ex.py +50 -25
- pymodaq/examples/tcp_client.py +1 -1
- pymodaq/extensions/__init__.py +1 -1
- pymodaq/extensions/bayesian/bayesian_optimisation.py +15 -12
- pymodaq/extensions/bayesian/utils.py +10 -10
- pymodaq/extensions/console.py +10 -13
- pymodaq/extensions/{daq_logger.py → daq_logger/daq_logger.py} +36 -56
- pymodaq/{utils/db/db_logger → extensions/daq_logger/db}/db_logger.py +16 -15
- pymodaq/{utils/db/db_logger → extensions/daq_logger/db}/db_logger_models.py +2 -0
- pymodaq/{utils/h5modules → extensions/daq_logger}/h5logging.py +7 -8
- pymodaq/extensions/daq_scan.py +153 -247
- pymodaq/extensions/daq_scan_ui.py +11 -9
- pymodaq/extensions/h5browser.py +8 -8
- pymodaq/extensions/pid/__init__.py +6 -3
- pymodaq/extensions/pid/daq_move_PID.py +4 -2
- pymodaq/extensions/pid/pid_controller.py +15 -12
- pymodaq/extensions/pid/utils.py +10 -5
- pymodaq/extensions/utils.py +5 -3
- pymodaq/post_treatment/load_and_plot.py +10 -7
- pymodaq/resources/preset_default.xml +1 -1
- pymodaq/utils/array_manipulation.py +4 -384
- pymodaq/utils/calibration_camera.py +12 -9
- pymodaq/utils/chrono_timer.py +7 -5
- pymodaq/utils/config.py +3 -450
- pymodaq/utils/daq_utils.py +6 -708
- pymodaq/utils/data.py +9 -2774
- pymodaq/utils/exceptions.py +0 -4
- pymodaq/utils/gui_utils/__init__.py +8 -8
- pymodaq/utils/gui_utils/loader_utils.py +38 -0
- pymodaq/utils/gui_utils/utils.py +6 -138
- pymodaq/utils/h5modules/__init__.py +0 -4
- pymodaq/utils/h5modules/module_saving.py +15 -8
- pymodaq/utils/leco/__init__.py +2 -2
- pymodaq/utils/leco/daq_move_LECODirector.py +2 -2
- pymodaq/utils/leco/daq_xDviewer_LECODirector.py +2 -2
- pymodaq/utils/leco/director_utils.py +2 -2
- pymodaq/utils/leco/leco_director.py +3 -3
- pymodaq/utils/leco/pymodaq_listener.py +2 -2
- pymodaq/utils/leco/utils.py +1 -1
- pymodaq/utils/logger.py +4 -76
- pymodaq/utils/managers/batchscan_manager.py +16 -19
- pymodaq/utils/managers/modules_manager.py +10 -7
- pymodaq/utils/managers/overshoot_manager.py +3 -5
- pymodaq/utils/managers/preset_manager.py +37 -15
- pymodaq/utils/managers/preset_manager_utils.py +11 -9
- pymodaq/utils/managers/remote_manager.py +12 -10
- pymodaq/utils/math_utils.py +4 -572
- pymodaq/utils/parameter/__init__.py +4 -11
- pymodaq/utils/parameter/utils.py +4 -299
- pymodaq/utils/scanner/scan_config.py +1 -1
- pymodaq/utils/scanner/scan_factory.py +16 -12
- pymodaq/utils/{plotting → scanner}/scan_selector.py +19 -20
- pymodaq/utils/scanner/scanner.py +10 -8
- pymodaq/utils/scanner/scanners/_1d_scanners.py +8 -5
- pymodaq/utils/scanner/scanners/_2d_scanners.py +5 -5
- pymodaq/utils/scanner/scanners/sequential.py +8 -8
- pymodaq/utils/scanner/scanners/tabular.py +9 -9
- pymodaq/utils/scanner/utils.py +6 -4
- pymodaq/utils/svg/svg_viewer2D.py +3 -4
- pymodaq/utils/tcp_ip/serializer.py +64 -16
- pymodaq/utils/tcp_ip/tcp_server_client.py +10 -8
- {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/METADATA +5 -3
- pymodaq-5.0.0.dist-info/RECORD +123 -0
- pymodaq/post_treatment/process_to_scalar.py +0 -263
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/1d.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/2d.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/3d.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Add2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Add_Step.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Approve.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Approve_All.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Browse_Dir_Path.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Calculator.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnGroup.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnNum.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnText.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnTime.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnWave.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Close3.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/CollapseAll.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/CollapseAll_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ColorPicker.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Contract.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Create.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/DeleteLayer.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditOpen.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditRedo.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditUndo.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Ellipse.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/EllipseFilled.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Error.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ErrorMessage.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Error_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Exit.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Expand.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ExpandAll.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ExpandAll_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/FFT.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/HLM.ico +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Help.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Help_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Histogram.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/LUT_LookUpTable.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/MagnifyingGlass.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/MagnifyingGlass_24.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Marker.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Math.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/MeasurementStudio_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Move.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/MoveDown.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/MoveUp.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Multiply.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/NewFile.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/NewLayer.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/New_File.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/New_Folder.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_1D.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_2D.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_File.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_File_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_sim.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Options.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Oscilloscope.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Oscilloscope_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Pass.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/RGB.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Rectangle.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/RectangleFilled.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Redo.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Region.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Rendezvous.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SELECT.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAll.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAll_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAs.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAs_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save_24.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Search.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/SelectPolygon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Select_24.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Settings.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snap&Save.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Spreadsheet.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Statistics.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Statistics2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Status.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Subtract.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Vision.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Volts.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Wait2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_1_1.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_in.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_out.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_to_Selection.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/abort.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/advanced2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/autoscale.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/b_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/back.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/bg_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/camera.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/camera_snap.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/cartesian.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/clear2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/clear_ROI.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/close2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/cluster2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/color.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/color2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/continuous.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/data.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/delay.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/download.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/download2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/error2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ethernet.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/exit2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/fan.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/filter2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/g_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/gear2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to_1.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to_2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/grab.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/graph.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/greenLight2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/greenLight2_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/green_light.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/grey_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/greyscale.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/help1.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/help1_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/home2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/information2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/ini.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/integrator.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/joystick.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_green.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_green_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_red.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_red_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_yellow.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_yellow_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/limiter.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/load_ROI.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/meshPlot.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/move_contour.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/move_straight_line.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/movie.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/multi_point.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/multiplexer.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/new.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/openArrow.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/openTree.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/oscilloscope2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/oscilloscope3.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/overlay.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass2_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/pause.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/permute.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/phase.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/play.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/polar.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/pole_zero.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerMeter.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerSwitch.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerSwitch_16.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/print2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/print2_32.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/properties.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/r_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/radiocontrolbutton.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/read2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/red_light.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/remove.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/reset.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/rgb_icon.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/robot.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/rotation2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/run2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/run_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/saturation.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/saveTree.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/save_ROI.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/scale_horizontally.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/scale_vertically.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/search2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/select2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_all2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_none.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/sequence.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/sequence2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/snap.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/sort_ascend.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/spectrumAnalyzer.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/start.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/status_cancelled.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop3.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop_all.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/sum.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/surfacePlot.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/tree.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/updateTree.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/utility2.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/utility_small.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/vector.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/verify.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/video.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/wait.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/waterfallPlot.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/watershed.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/yellow_light.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/zip_file.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/zoomAuto.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/Icon_Library/zoomReset.png +0 -0
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat +0 -2
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc +0 -234
- pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +0 -127150
- pymodaq/resources/QtDesigner_Ressources/icons.svg +0 -142
- pymodaq/resources/VERSION +0 -1
- pymodaq/resources/config_template.toml +0 -94
- pymodaq/resources/triangulation_data.npy +0 -0
- pymodaq/utils/abstract/__init__.py +0 -48
- pymodaq/utils/db/__init__.py +0 -0
- pymodaq/utils/db/db_logger/__init__.py +0 -0
- pymodaq/utils/enums.py +0 -76
- pymodaq/utils/factory.py +0 -82
- pymodaq/utils/gui_utils/custom_app.py +0 -133
- pymodaq/utils/gui_utils/dock.py +0 -107
- pymodaq/utils/gui_utils/file_io.py +0 -93
- pymodaq/utils/gui_utils/layout.py +0 -34
- pymodaq/utils/gui_utils/list_picker.py +0 -38
- pymodaq/utils/gui_utils/widgets/__init__.py +0 -5
- pymodaq/utils/gui_utils/widgets/label.py +0 -24
- pymodaq/utils/gui_utils/widgets/lcd.py +0 -111
- pymodaq/utils/gui_utils/widgets/push.py +0 -149
- pymodaq/utils/gui_utils/widgets/qled.py +0 -62
- pymodaq/utils/gui_utils/widgets/spinbox.py +0 -24
- pymodaq/utils/gui_utils/widgets/table.py +0 -263
- pymodaq/utils/gui_utils/widgets/tree_layout.py +0 -188
- pymodaq/utils/gui_utils/widgets/tree_toml.py +0 -102
- pymodaq/utils/h5modules/backends.py +0 -1022
- pymodaq/utils/h5modules/browsing.py +0 -625
- pymodaq/utils/h5modules/data_saving.py +0 -1105
- pymodaq/utils/h5modules/exporter.py +0 -119
- pymodaq/utils/h5modules/exporters/__init__.py +0 -0
- pymodaq/utils/h5modules/exporters/base.py +0 -111
- pymodaq/utils/h5modules/exporters/flimj.py +0 -63
- pymodaq/utils/h5modules/exporters/hyperspy.py +0 -143
- pymodaq/utils/h5modules/saving.py +0 -866
- pymodaq/utils/h5modules/utils.py +0 -115
- pymodaq/utils/managers/action_manager.py +0 -489
- pymodaq/utils/managers/parameter_manager.py +0 -282
- pymodaq/utils/managers/roi_manager.py +0 -726
- pymodaq/utils/messenger.py +0 -66
- pymodaq/utils/parameter/ioxml.py +0 -542
- pymodaq/utils/parameter/pymodaq_ptypes/__init__.py +0 -38
- pymodaq/utils/parameter/pymodaq_ptypes/bool.py +0 -31
- pymodaq/utils/parameter/pymodaq_ptypes/date.py +0 -126
- pymodaq/utils/parameter/pymodaq_ptypes/filedir.py +0 -143
- pymodaq/utils/parameter/pymodaq_ptypes/itemselect.py +0 -265
- pymodaq/utils/parameter/pymodaq_ptypes/led.py +0 -44
- pymodaq/utils/parameter/pymodaq_ptypes/list.py +0 -150
- pymodaq/utils/parameter/pymodaq_ptypes/numeric.py +0 -18
- pymodaq/utils/parameter/pymodaq_ptypes/pixmap.py +0 -175
- pymodaq/utils/parameter/pymodaq_ptypes/slide.py +0 -145
- pymodaq/utils/parameter/pymodaq_ptypes/table.py +0 -135
- pymodaq/utils/parameter/pymodaq_ptypes/tableview.py +0 -149
- pymodaq/utils/parameter/pymodaq_ptypes/text.py +0 -142
- pymodaq/utils/plotting/__init__.py +0 -0
- pymodaq/utils/plotting/data_viewers/__init__.py +0 -10
- pymodaq/utils/plotting/data_viewers/base.py +0 -286
- pymodaq/utils/plotting/data_viewers/viewer.py +0 -274
- pymodaq/utils/plotting/data_viewers/viewer0D.py +0 -298
- pymodaq/utils/plotting/data_viewers/viewer1D.py +0 -826
- pymodaq/utils/plotting/data_viewers/viewer1Dbasic.py +0 -231
- pymodaq/utils/plotting/data_viewers/viewer2D.py +0 -1118
- pymodaq/utils/plotting/data_viewers/viewer2D_basic.py +0 -146
- pymodaq/utils/plotting/data_viewers/viewerND.py +0 -800
- pymodaq/utils/plotting/gant_chart.py +0 -123
- pymodaq/utils/plotting/image_viewer.py +0 -97
- pymodaq/utils/plotting/items/__init__.py +0 -0
- pymodaq/utils/plotting/items/axis_scaled.py +0 -93
- pymodaq/utils/plotting/items/crosshair.py +0 -94
- pymodaq/utils/plotting/items/image.py +0 -388
- pymodaq/utils/plotting/navigator.py +0 -353
- pymodaq/utils/plotting/plotter/plotter.py +0 -94
- pymodaq/utils/plotting/plotter/plotters/__init__.py +0 -0
- pymodaq/utils/plotting/plotter/plotters/matplotlib_plotters.py +0 -134
- pymodaq/utils/plotting/plotter/plotters/qt_plotters.py +0 -78
- pymodaq/utils/plotting/utils/__init__.py +0 -0
- pymodaq/utils/plotting/utils/axes_viewer.py +0 -88
- pymodaq/utils/plotting/utils/filter.py +0 -585
- pymodaq/utils/plotting/utils/lineout.py +0 -226
- pymodaq/utils/plotting/utils/plot_utils.py +0 -579
- pymodaq/utils/plotting/utils/signalND.py +0 -1347
- pymodaq/utils/plotting/widgets.py +0 -76
- pymodaq/utils/qvariant.py +0 -12
- pymodaq/utils/slicing.py +0 -63
- pymodaq/utils/units.py +0 -216
- pymodaq-4.2.4.dist-info/RECORD +0 -438
- /pymodaq/{post_treatment/daq_analysis → extensions/daq_logger}/__init__.py +0 -0
- /pymodaq/{utils/abstract/logger.py → extensions/daq_logger/abstract.py} +0 -0
- /pymodaq/{resources/QtDesigner_Ressources → extensions/daq_logger/db}/__init__.py +0 -0
- {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/WHEEL +0 -0
- {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/entry_points.txt +0 -0
- {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,1347 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
Created on Fri Aug 31 16:41:26 2018
|
|
4
|
-
|
|
5
|
-
@author: Weber Sébastien
|
|
6
|
-
@email: seba.weber@gmail.com
|
|
7
|
-
"""
|
|
8
|
-
import numpy as np
|
|
9
|
-
import collections
|
|
10
|
-
import copy
|
|
11
|
-
|
|
12
|
-
import math
|
|
13
|
-
from pymodaq.utils import daq_utils as utils
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
# %%
|
|
17
|
-
def generate_axis(offset, scale, size, offset_index=0):
|
|
18
|
-
"""Creates an axis given the offset, scale and number of channels
|
|
19
|
-
|
|
20
|
-
Alternatively, the offset_index of the offset channel can be specified.
|
|
21
|
-
|
|
22
|
-
Parameters
|
|
23
|
-
----------
|
|
24
|
-
offset : float
|
|
25
|
-
scale : float
|
|
26
|
-
size : number of channels
|
|
27
|
-
offset_index : int
|
|
28
|
-
offset_index number of the offset
|
|
29
|
-
|
|
30
|
-
Returns
|
|
31
|
-
-------
|
|
32
|
-
Numpy array
|
|
33
|
-
|
|
34
|
-
"""
|
|
35
|
-
return np.linspace(offset - offset_index * scale,
|
|
36
|
-
offset + scale * (size - 1 - offset_index),
|
|
37
|
-
size)
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
def add_scalar_axis(signal):
|
|
41
|
-
am = signal.axes_manager
|
|
42
|
-
signal.__class__ = Signal
|
|
43
|
-
am.remove(am._axes)
|
|
44
|
-
am._append_axis(size=1,
|
|
45
|
-
scale=1,
|
|
46
|
-
offset=0,
|
|
47
|
-
name="Scalar",
|
|
48
|
-
navigate=False)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def isfloat(number):
|
|
52
|
-
"""Check if a number or array is of float type.
|
|
53
|
-
|
|
54
|
-
This is necessary because e.g. isinstance(np.float32(2), float) is False.
|
|
55
|
-
|
|
56
|
-
"""
|
|
57
|
-
if hasattr(number, "dtype"):
|
|
58
|
-
return np.issubdtype(number, np.float)
|
|
59
|
-
else:
|
|
60
|
-
return isinstance(number, float)
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def iterable_not_string(thing):
|
|
64
|
-
return isinstance(thing, collections.abc.Iterable) and not isinstance(thing, str)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
class SpecialSlicers(object):
|
|
68
|
-
|
|
69
|
-
def __init__(self, obj, isNavigation):
|
|
70
|
-
self.isNavigation = isNavigation
|
|
71
|
-
self.obj = obj
|
|
72
|
-
|
|
73
|
-
def __getitem__(self, slices, out=None):
|
|
74
|
-
return self.obj._slicer(slices, self.isNavigation, out=out)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
class SpecialSlicersSignal(SpecialSlicers):
|
|
78
|
-
|
|
79
|
-
def __setitem__(self, i, j):
|
|
80
|
-
"""x.__setitem__(i, y) <==> x[i]=y
|
|
81
|
-
"""
|
|
82
|
-
if isinstance(j, Signal):
|
|
83
|
-
j = j.data
|
|
84
|
-
array_slices = self.obj._get_array_slices(i, self.isNavigation)
|
|
85
|
-
self.obj.data[array_slices] = j
|
|
86
|
-
|
|
87
|
-
def __len__(self):
|
|
88
|
-
return self.obj.axes_manager.signal_shape[0]
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
class attrgetter:
|
|
92
|
-
"""
|
|
93
|
-
Return a callable object that fetches the given attribute(s) from its operand.
|
|
94
|
-
After f = attrgetter('name'), the call f(r) returns r.name.
|
|
95
|
-
After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).
|
|
96
|
-
After h = attrgetter('name.first', 'name.last'), the call h(r) returns
|
|
97
|
-
(r.name.first, r.name.last).
|
|
98
|
-
"""
|
|
99
|
-
__slots__ = ('_attrs', '_call')
|
|
100
|
-
|
|
101
|
-
def __init__(self, attr, *attrs):
|
|
102
|
-
if not attrs:
|
|
103
|
-
if not isinstance(attr, str):
|
|
104
|
-
raise TypeError('attribute name must be a string')
|
|
105
|
-
self._attrs = (attr,)
|
|
106
|
-
names = attr.split('.')
|
|
107
|
-
|
|
108
|
-
def func(obj):
|
|
109
|
-
for name in names:
|
|
110
|
-
obj = getattr(obj, name)
|
|
111
|
-
return obj
|
|
112
|
-
self._call = func
|
|
113
|
-
else:
|
|
114
|
-
self._attrs = (attr,) + attrs
|
|
115
|
-
getters = tuple(map(attrgetter, self._attrs))
|
|
116
|
-
|
|
117
|
-
def func(obj):
|
|
118
|
-
return tuple(getter(obj) for getter in getters)
|
|
119
|
-
self._call = func
|
|
120
|
-
|
|
121
|
-
def __call__(self, obj):
|
|
122
|
-
return self._call(obj)
|
|
123
|
-
|
|
124
|
-
def __repr__(self):
|
|
125
|
-
return '%s.%s(%s)' % (self.__class__.__module__,
|
|
126
|
-
self.__class__.__qualname__,
|
|
127
|
-
', '.join(map(repr, self._attrs)))
|
|
128
|
-
|
|
129
|
-
def __reduce__(self):
|
|
130
|
-
return self.__class__, self._attrs
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def attrsetter(target, attrs, value):
|
|
134
|
-
""" Sets attribute of the target to specified value, supports nested
|
|
135
|
-
attributes. Only creates a new attribute if the object supports such
|
|
136
|
-
behaviour (e.g. DictionaryTreeBrowser does)
|
|
137
|
-
|
|
138
|
-
Parameters
|
|
139
|
-
----------
|
|
140
|
-
target : object
|
|
141
|
-
attrs : string
|
|
142
|
-
attributes, separated by periods (e.g.
|
|
143
|
-
'metadata.Signal.Noise_parameters.variance' )
|
|
144
|
-
value : object
|
|
145
|
-
|
|
146
|
-
Example
|
|
147
|
-
-------
|
|
148
|
-
First create a signal and model pair:
|
|
149
|
-
|
|
150
|
-
>>> s = hs.signals.Signal1D(np.arange(10))
|
|
151
|
-
>>> m = s.create_model()
|
|
152
|
-
>>> m.signal.data
|
|
153
|
-
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
|
|
154
|
-
|
|
155
|
-
Now set the data of the model with attrsetter
|
|
156
|
-
>>> attrsetter(m, 'signal1D.data', np.arange(10)+2)
|
|
157
|
-
>>> self.signal.data
|
|
158
|
-
array([2, 3, 4, 5, 6, 7, 8, 9, 10, 10])
|
|
159
|
-
|
|
160
|
-
The behaviour is identical to
|
|
161
|
-
>>> self.signal.data = np.arange(10) + 2
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
"""
|
|
165
|
-
where = attrs.rfind('.')
|
|
166
|
-
if where != -1:
|
|
167
|
-
target = attrgetter(attrs[:where])(target)
|
|
168
|
-
setattr(target, attrs[where + 1:], value)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
class FancySlicing(object):
|
|
172
|
-
|
|
173
|
-
def _get_array_slices(self, slices, isNavigation=None):
|
|
174
|
-
try:
|
|
175
|
-
len(slices)
|
|
176
|
-
except TypeError:
|
|
177
|
-
slices = (slices,)
|
|
178
|
-
|
|
179
|
-
slices_ = tuple()
|
|
180
|
-
for sl in slices:
|
|
181
|
-
slices_ += (sl,)
|
|
182
|
-
slices = slices_
|
|
183
|
-
del slices_
|
|
184
|
-
_orig_slices = slices
|
|
185
|
-
|
|
186
|
-
has_nav = True if isNavigation is None else isNavigation
|
|
187
|
-
has_signal = True if isNavigation is None else not isNavigation
|
|
188
|
-
|
|
189
|
-
# Create a deepcopy of self that contains a view of self.data
|
|
190
|
-
|
|
191
|
-
nav_idx = [el.index_in_array for el in
|
|
192
|
-
self.axes_manager.navigation_axes]
|
|
193
|
-
signal_idx = [el.index_in_array for el in
|
|
194
|
-
self.axes_manager.signal_axes]
|
|
195
|
-
|
|
196
|
-
if not has_signal:
|
|
197
|
-
idx = nav_idx
|
|
198
|
-
elif not has_nav:
|
|
199
|
-
idx = signal_idx
|
|
200
|
-
else:
|
|
201
|
-
idx = nav_idx + signal_idx
|
|
202
|
-
|
|
203
|
-
# Add support for Ellipsis
|
|
204
|
-
if Ellipsis in _orig_slices:
|
|
205
|
-
_orig_slices = list(_orig_slices)
|
|
206
|
-
# Expand the first Ellipsis
|
|
207
|
-
ellipsis_index = _orig_slices.index(Ellipsis)
|
|
208
|
-
_orig_slices.remove(Ellipsis)
|
|
209
|
-
_orig_slices = (_orig_slices[:ellipsis_index] + [slice(None), ] * max(0, len(idx) - len(
|
|
210
|
-
_orig_slices)) + _orig_slices[ellipsis_index:])
|
|
211
|
-
# Replace all the following Ellipses by :
|
|
212
|
-
while Ellipsis in _orig_slices:
|
|
213
|
-
_orig_slices[_orig_slices.index(Ellipsis)] = slice(None)
|
|
214
|
-
_orig_slices = tuple(_orig_slices)
|
|
215
|
-
|
|
216
|
-
if len(_orig_slices) > len(idx):
|
|
217
|
-
raise IndexError("too many indices")
|
|
218
|
-
|
|
219
|
-
slices = np.array([slice(None, )] * len(self.axes_manager._axes))
|
|
220
|
-
|
|
221
|
-
slices[idx] = _orig_slices + (slice(None),) * max(
|
|
222
|
-
0, len(idx) - len(_orig_slices))
|
|
223
|
-
|
|
224
|
-
array_slices = []
|
|
225
|
-
for slice_, axis in zip(slices, self.axes_manager._axes):
|
|
226
|
-
if (isinstance(slice_, slice) or len(self.axes_manager._axes) < 2):
|
|
227
|
-
array_slices.append(axis._get_array_slices(slice_))
|
|
228
|
-
else:
|
|
229
|
-
if isinstance(slice_, float):
|
|
230
|
-
slice_ = axis.value2index(slice_)
|
|
231
|
-
array_slices.append(slice_)
|
|
232
|
-
return tuple(array_slices)
|
|
233
|
-
|
|
234
|
-
def _slicer(self, slices, isNavigation=None, out=None):
|
|
235
|
-
array_slices = self._get_array_slices(slices, isNavigation)
|
|
236
|
-
new_data = self.data[array_slices]
|
|
237
|
-
if new_data.size == 1 and new_data.dtype is np.dtype('O'):
|
|
238
|
-
if isinstance(new_data[0], np.ndarray):
|
|
239
|
-
return self.__class__(new_data[0]).transpose(navigation_axes=0)
|
|
240
|
-
else:
|
|
241
|
-
return new_data[0]
|
|
242
|
-
|
|
243
|
-
if out is None:
|
|
244
|
-
_obj = self._deepcopy_with_new_data(new_data,
|
|
245
|
-
copy_variance=True)
|
|
246
|
-
_to_remove = []
|
|
247
|
-
for slice_, axis in zip(array_slices, _obj.axes_manager._axes):
|
|
248
|
-
if (isinstance(slice_, slice) or len(self.axes_manager._axes) < 2):
|
|
249
|
-
axis._slice_me(slice_)
|
|
250
|
-
else:
|
|
251
|
-
_to_remove.append(axis.index_in_axes_manager)
|
|
252
|
-
for _ind in reversed(sorted(_to_remove)):
|
|
253
|
-
_obj._remove_axis(_ind)
|
|
254
|
-
else:
|
|
255
|
-
out.data = new_data
|
|
256
|
-
_obj = out
|
|
257
|
-
i = 0
|
|
258
|
-
for slice_, axis_src in zip(array_slices, self.axes_manager._axes):
|
|
259
|
-
axis_src = axis_src.copy()
|
|
260
|
-
if (isinstance(slice_, slice) or len(self.axes_manager._axes) < 2):
|
|
261
|
-
axis_src._slice_me(slice_)
|
|
262
|
-
axis_dst = out.axes_manager._axes[i]
|
|
263
|
-
i += 1
|
|
264
|
-
axis_dst.update_from(axis_src, attributes=("scale", "offset", "size"))
|
|
265
|
-
|
|
266
|
-
if hasattr(self, "_additional_slicing_targets"):
|
|
267
|
-
for ta in self._additional_slicing_targets:
|
|
268
|
-
try:
|
|
269
|
-
t = attrgetter(ta)(self)
|
|
270
|
-
if out is None:
|
|
271
|
-
if hasattr(t, '_slicer'):
|
|
272
|
-
attrsetter(
|
|
273
|
-
_obj,
|
|
274
|
-
ta,
|
|
275
|
-
t._slicer(
|
|
276
|
-
slices,
|
|
277
|
-
isNavigation))
|
|
278
|
-
else:
|
|
279
|
-
target = attrgetter(ta)(_obj)
|
|
280
|
-
t._slicer(
|
|
281
|
-
slices,
|
|
282
|
-
isNavigation,
|
|
283
|
-
out=target)
|
|
284
|
-
|
|
285
|
-
except AttributeError:
|
|
286
|
-
pass
|
|
287
|
-
# _obj.get_dimensions_from_data() # replots, so we do it manually:
|
|
288
|
-
dc = _obj.data
|
|
289
|
-
for axis in _obj.axes_manager._axes:
|
|
290
|
-
axis.size = int(dc.shape[axis.index_in_array])
|
|
291
|
-
if out is None:
|
|
292
|
-
return _obj
|
|
293
|
-
else:
|
|
294
|
-
out.events.data_changed.trigger(obj=out)
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
class DataAxis(object):
|
|
298
|
-
|
|
299
|
-
def __init__(self,
|
|
300
|
-
size,
|
|
301
|
-
index_in_array=None,
|
|
302
|
-
name=None,
|
|
303
|
-
scale=1.,
|
|
304
|
-
offset=0.,
|
|
305
|
-
units=None,
|
|
306
|
-
navigate=None):
|
|
307
|
-
|
|
308
|
-
self.name = name
|
|
309
|
-
self.units = units
|
|
310
|
-
self.scale = scale
|
|
311
|
-
self.offset = offset
|
|
312
|
-
self.size = size
|
|
313
|
-
self.value = None
|
|
314
|
-
self.high_index = self.size - 1
|
|
315
|
-
self.low_index = 0
|
|
316
|
-
self.index = 0
|
|
317
|
-
self.update_axis()
|
|
318
|
-
self.navigate = navigate
|
|
319
|
-
self.axes_manager = None
|
|
320
|
-
self._update_slice(self.navigate)
|
|
321
|
-
|
|
322
|
-
def _index_changed(self, name, old, new):
|
|
323
|
-
self.events.index_changed.trigger(obj=self, index=self.index)
|
|
324
|
-
if not self._suppress_update_value:
|
|
325
|
-
new_value = self.axis[self.index]
|
|
326
|
-
if new_value != self.value:
|
|
327
|
-
self.value = new_value
|
|
328
|
-
|
|
329
|
-
@property
|
|
330
|
-
def index_in_array(self):
|
|
331
|
-
if self.axes_manager is not None:
|
|
332
|
-
return self.axes_manager._axes.index(self)
|
|
333
|
-
else:
|
|
334
|
-
raise AttributeError(
|
|
335
|
-
"This DataAxis does not belong to an AxesManager"
|
|
336
|
-
" and therefore its index_in_array attribute "
|
|
337
|
-
" is not defined")
|
|
338
|
-
|
|
339
|
-
@property
|
|
340
|
-
def index_in_axes_manager(self):
|
|
341
|
-
if self.axes_manager is not None:
|
|
342
|
-
return self.axes_manager._get_axes_in_natural_order(). \
|
|
343
|
-
index(self)
|
|
344
|
-
else:
|
|
345
|
-
raise AttributeError(
|
|
346
|
-
"This DataAxis does not belong to an AxesManager"
|
|
347
|
-
" and therefore its index_in_array attribute "
|
|
348
|
-
" is not defined")
|
|
349
|
-
|
|
350
|
-
def _get_positive_index(self, index):
|
|
351
|
-
if index < 0:
|
|
352
|
-
index = self.size + index
|
|
353
|
-
if index < 0:
|
|
354
|
-
raise IndexError("index out of bounds")
|
|
355
|
-
return index
|
|
356
|
-
|
|
357
|
-
def _get_index(self, value):
|
|
358
|
-
if isfloat(value):
|
|
359
|
-
return self.value2index(value)
|
|
360
|
-
else:
|
|
361
|
-
return value
|
|
362
|
-
|
|
363
|
-
def _slice_me(self, slice_):
|
|
364
|
-
"""Returns a slice to slice the corresponding data axis and
|
|
365
|
-
change the offset and scale of the DataAxis accordingly.
|
|
366
|
-
|
|
367
|
-
Parameters
|
|
368
|
-
----------
|
|
369
|
-
slice_ : {float, int, slice}
|
|
370
|
-
|
|
371
|
-
Returns
|
|
372
|
-
-------
|
|
373
|
-
my_slice : slice
|
|
374
|
-
|
|
375
|
-
"""
|
|
376
|
-
i2v = self.index2value
|
|
377
|
-
|
|
378
|
-
my_slice = self._get_array_slices(slice_)
|
|
379
|
-
|
|
380
|
-
start, stop, step = my_slice.start, my_slice.stop, my_slice.step
|
|
381
|
-
|
|
382
|
-
if start is None:
|
|
383
|
-
if step is None or step > 0:
|
|
384
|
-
start = 0
|
|
385
|
-
else:
|
|
386
|
-
start = self.size - 1
|
|
387
|
-
self.offset = i2v(start)
|
|
388
|
-
if step is not None:
|
|
389
|
-
self.scale *= step
|
|
390
|
-
|
|
391
|
-
return my_slice
|
|
392
|
-
|
|
393
|
-
def value2index(self, value, rounding=round):
|
|
394
|
-
"""Return the closest index to the given value if between the limit.
|
|
395
|
-
|
|
396
|
-
Parameters
|
|
397
|
-
----------
|
|
398
|
-
value : number or numpy array
|
|
399
|
-
|
|
400
|
-
Returns
|
|
401
|
-
-------
|
|
402
|
-
index : integer or numpy array
|
|
403
|
-
|
|
404
|
-
Raises
|
|
405
|
-
------
|
|
406
|
-
ValueError if any value is out of the axis limits.
|
|
407
|
-
|
|
408
|
-
"""
|
|
409
|
-
if value is None:
|
|
410
|
-
return None
|
|
411
|
-
|
|
412
|
-
if isinstance(value, np.ndarray):
|
|
413
|
-
if rounding is round:
|
|
414
|
-
rounding = np.round
|
|
415
|
-
elif rounding is math.ceil:
|
|
416
|
-
rounding = np.ceil
|
|
417
|
-
elif rounding is math.floor:
|
|
418
|
-
rounding = np.floor
|
|
419
|
-
|
|
420
|
-
index = rounding((value - self.offset) / self.scale)
|
|
421
|
-
|
|
422
|
-
if isinstance(value, np.ndarray):
|
|
423
|
-
index = index.astype(int)
|
|
424
|
-
if np.all(self.size > index) and np.all(index >= 0):
|
|
425
|
-
return index
|
|
426
|
-
else:
|
|
427
|
-
raise ValueError("A value is out of the axis limits")
|
|
428
|
-
else:
|
|
429
|
-
index = int(index)
|
|
430
|
-
if self.size > index >= 0:
|
|
431
|
-
return index
|
|
432
|
-
else:
|
|
433
|
-
raise ValueError("The value is out of the axis limits")
|
|
434
|
-
|
|
435
|
-
def index2value(self, index):
|
|
436
|
-
if isinstance(index, np.ndarray):
|
|
437
|
-
return self.axis[index.ravel()].reshape(index.shape)
|
|
438
|
-
else:
|
|
439
|
-
return self.axis[index]
|
|
440
|
-
|
|
441
|
-
def _get_array_slices(self, slice_):
|
|
442
|
-
"""Returns a slice to slice the corresponding data axis without
|
|
443
|
-
changing the offset and scale of the DataAxis.
|
|
444
|
-
|
|
445
|
-
Parameters
|
|
446
|
-
----------
|
|
447
|
-
slice_ : {float, int, slice}
|
|
448
|
-
|
|
449
|
-
Returns
|
|
450
|
-
-------
|
|
451
|
-
my_slice : slice
|
|
452
|
-
|
|
453
|
-
"""
|
|
454
|
-
v2i = self.value2index
|
|
455
|
-
|
|
456
|
-
if isinstance(slice_, slice):
|
|
457
|
-
start = slice_.start
|
|
458
|
-
stop = slice_.stop
|
|
459
|
-
step = slice_.step
|
|
460
|
-
else:
|
|
461
|
-
if isfloat(slice_):
|
|
462
|
-
start = v2i(slice_)
|
|
463
|
-
else:
|
|
464
|
-
start = self._get_positive_index(slice_)
|
|
465
|
-
stop = start + 1
|
|
466
|
-
step = None
|
|
467
|
-
|
|
468
|
-
if isfloat(step):
|
|
469
|
-
step = int(round(step / self.scale))
|
|
470
|
-
if isfloat(start):
|
|
471
|
-
try:
|
|
472
|
-
start = v2i(start)
|
|
473
|
-
except ValueError:
|
|
474
|
-
if start > self.high_value:
|
|
475
|
-
# The start value is above the axis limit
|
|
476
|
-
raise IndexError(
|
|
477
|
-
"Start value above axis high bound for axis %s."
|
|
478
|
-
"value: %f high_bound: %f" % (repr(self), start,
|
|
479
|
-
self.high_value))
|
|
480
|
-
else:
|
|
481
|
-
# The start value is below the axis limit,
|
|
482
|
-
# we slice from the start.
|
|
483
|
-
start = None
|
|
484
|
-
if isfloat(stop):
|
|
485
|
-
try:
|
|
486
|
-
stop = v2i(stop)
|
|
487
|
-
except ValueError:
|
|
488
|
-
if stop < self.low_value:
|
|
489
|
-
# The stop value is below the axis limits
|
|
490
|
-
raise IndexError(
|
|
491
|
-
"Stop value below axis low bound for axis %s."
|
|
492
|
-
"value: %f low_bound: %f" % (repr(self), stop,
|
|
493
|
-
self.low_value))
|
|
494
|
-
else:
|
|
495
|
-
# The stop value is below the axis limit,
|
|
496
|
-
# we slice until the end.
|
|
497
|
-
stop = None
|
|
498
|
-
|
|
499
|
-
if step == 0:
|
|
500
|
-
raise ValueError("slice step cannot be zero")
|
|
501
|
-
|
|
502
|
-
return slice(start, stop, step)
|
|
503
|
-
|
|
504
|
-
def update_axis(self):
|
|
505
|
-
self.axis = generate_axis(self.offset, self.scale, self.size)
|
|
506
|
-
if len(self.axis) != 0:
|
|
507
|
-
self.low_value, self.high_value = (
|
|
508
|
-
self.axis.min(), self.axis.max())
|
|
509
|
-
self.value = [self.low_value, self.high_value]
|
|
510
|
-
|
|
511
|
-
def _update_slice(self, value):
|
|
512
|
-
if value is False:
|
|
513
|
-
self.slice = slice(None)
|
|
514
|
-
else:
|
|
515
|
-
self.slice = None
|
|
516
|
-
|
|
517
|
-
@property
|
|
518
|
-
def index_in_axes_manager(self):
|
|
519
|
-
if self.axes_manager is not None:
|
|
520
|
-
return self.axes_manager._get_axes_in_natural_order(). \
|
|
521
|
-
index(self)
|
|
522
|
-
else:
|
|
523
|
-
raise AttributeError(
|
|
524
|
-
"This DataAxis does not belong to an AxesManager"
|
|
525
|
-
" and therefore its index_in_array attribute "
|
|
526
|
-
" is not defined")
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
class AxesManager(object):
|
|
530
|
-
|
|
531
|
-
def __init__(self, axes_list):
|
|
532
|
-
self._axes = []
|
|
533
|
-
self.create_axes(axes_list)
|
|
534
|
-
# set_signal_dimension is called only if there is no current
|
|
535
|
-
# view. It defaults to spectrum
|
|
536
|
-
navigates = [i.navigate for i in self._axes]
|
|
537
|
-
self._update_attributes()
|
|
538
|
-
|
|
539
|
-
def _append_axis(self, *args, **kwargs):
|
|
540
|
-
axis = DataAxis(*args, **kwargs)
|
|
541
|
-
axis.axes_manager = self
|
|
542
|
-
self._axes.append(axis)
|
|
543
|
-
|
|
544
|
-
def remove(self, axes):
|
|
545
|
-
"""Remove one or more axes
|
|
546
|
-
"""
|
|
547
|
-
axes = self[axes]
|
|
548
|
-
if not np.iterable(axes):
|
|
549
|
-
axes = (axes,)
|
|
550
|
-
for ax in axes:
|
|
551
|
-
self._remove_one_axis(ax)
|
|
552
|
-
|
|
553
|
-
def _remove_one_axis(self, axis):
|
|
554
|
-
"""Remove the given Axis.
|
|
555
|
-
|
|
556
|
-
Raises
|
|
557
|
-
------
|
|
558
|
-
ValueError if the Axis is not present.
|
|
559
|
-
|
|
560
|
-
"""
|
|
561
|
-
axis = self._axes_getter(axis)
|
|
562
|
-
axis.axes_manager = None
|
|
563
|
-
self._axes.remove(axis)
|
|
564
|
-
|
|
565
|
-
def __getitem__(self, y):
|
|
566
|
-
"""x.__getitem__(y) <==> x[y]
|
|
567
|
-
|
|
568
|
-
"""
|
|
569
|
-
if isinstance(y, str) or not np.iterable(y):
|
|
570
|
-
return self[(y,)][0]
|
|
571
|
-
axes = [self._axes_getter(ax) for ax in y]
|
|
572
|
-
_, indices = np.unique(
|
|
573
|
-
[_id for _id in map(id, axes)], return_index=True)
|
|
574
|
-
ans = tuple(axes[i] for i in sorted(indices))
|
|
575
|
-
return ans
|
|
576
|
-
|
|
577
|
-
def _axes_getter(self, y):
|
|
578
|
-
if y in self._axes:
|
|
579
|
-
return y
|
|
580
|
-
if isinstance(y, str):
|
|
581
|
-
axes = list(self._get_axes_in_natural_order())
|
|
582
|
-
while axes:
|
|
583
|
-
axis = axes.pop()
|
|
584
|
-
if y == axis.name:
|
|
585
|
-
return axis
|
|
586
|
-
raise ValueError("There is no DataAxis named %s" % y)
|
|
587
|
-
elif (isfloat(y.real) and not y.real.is_integer() or isfloat(y.imag) and not y.imag.is_integer()):
|
|
588
|
-
raise TypeError("axesmanager indices must be integers, "
|
|
589
|
-
"complex integers or strings")
|
|
590
|
-
if y.imag == 0: # Natural order
|
|
591
|
-
return self._get_axes_in_natural_order()[y]
|
|
592
|
-
elif y.imag == 3: # Array order
|
|
593
|
-
# Array order
|
|
594
|
-
return self._axes[int(y.real)]
|
|
595
|
-
elif y.imag == 1: # Navigation natural order
|
|
596
|
-
#
|
|
597
|
-
return self.navigation_axes[int(y.real)]
|
|
598
|
-
elif y.imag == 2: # Signal natural order
|
|
599
|
-
return self.signal_axes[int(y.real)]
|
|
600
|
-
else:
|
|
601
|
-
raise IndexError("axesmanager imaginary part of complex indices "
|
|
602
|
-
"must be 0, 1, 2 or 3")
|
|
603
|
-
|
|
604
|
-
def __getslice__(self, i=None, j=None):
|
|
605
|
-
"""x.__getslice__(i, j) <==> x[i:j]
|
|
606
|
-
|
|
607
|
-
"""
|
|
608
|
-
return self._get_axes_in_natural_order()[i:j]
|
|
609
|
-
|
|
610
|
-
def create_axes(self, axes_list):
|
|
611
|
-
"""Given a list of dictionaries defining the axes properties
|
|
612
|
-
create the DataAxis instances and add them to the AxesManager.
|
|
613
|
-
|
|
614
|
-
The index of the axis in the array and in the `_axes` lists
|
|
615
|
-
can be defined by the index_in_array keyword if given
|
|
616
|
-
for all axes. Otherwise it is defined by their index in the
|
|
617
|
-
list.
|
|
618
|
-
|
|
619
|
-
See also
|
|
620
|
-
--------
|
|
621
|
-
_append_axis
|
|
622
|
-
|
|
623
|
-
"""
|
|
624
|
-
for axis_dict in axes_list:
|
|
625
|
-
self._append_axis(**axis_dict)
|
|
626
|
-
|
|
627
|
-
def _get_axes_in_natural_order(self):
|
|
628
|
-
return self.navigation_axes + self.signal_axes
|
|
629
|
-
|
|
630
|
-
def _update_attributes(self):
|
|
631
|
-
getitem_tuple = []
|
|
632
|
-
values = []
|
|
633
|
-
self.signal_axes = ()
|
|
634
|
-
self.navigation_axes = ()
|
|
635
|
-
for axis in self._axes:
|
|
636
|
-
# Until we find a better place, take property of the axes
|
|
637
|
-
# here to avoid difficult to debug bugs.
|
|
638
|
-
axis.axes_manager = self
|
|
639
|
-
if axis.slice is None:
|
|
640
|
-
getitem_tuple += axis.index,
|
|
641
|
-
values.append(axis.value)
|
|
642
|
-
self.navigation_axes += axis,
|
|
643
|
-
else:
|
|
644
|
-
getitem_tuple += axis.slice,
|
|
645
|
-
self.signal_axes += axis,
|
|
646
|
-
if not self.signal_axes and self.navigation_axes:
|
|
647
|
-
getitem_tuple[-1] = slice(axis.index, axis.index + 1)
|
|
648
|
-
|
|
649
|
-
self.signal_axes = self.signal_axes[::-1]
|
|
650
|
-
self.navigation_axes = self.navigation_axes[::-1]
|
|
651
|
-
self._getitem_tuple = tuple(getitem_tuple)
|
|
652
|
-
self.signal_dimension = len(self.signal_axes)
|
|
653
|
-
self.navigation_dimension = len(self.navigation_axes)
|
|
654
|
-
if self.navigation_dimension != 0:
|
|
655
|
-
self.navigation_shape = tuple([
|
|
656
|
-
axis.size for axis in self.navigation_axes])
|
|
657
|
-
else:
|
|
658
|
-
self.navigation_shape = ()
|
|
659
|
-
|
|
660
|
-
if self.signal_dimension != 0:
|
|
661
|
-
self.signal_shape = tuple([
|
|
662
|
-
axis.size for axis in self.signal_axes])
|
|
663
|
-
else:
|
|
664
|
-
self.signal_shape = ()
|
|
665
|
-
self.navigation_size = (np.cumprod(self.navigation_shape)[-1]
|
|
666
|
-
if self.navigation_shape else 0)
|
|
667
|
-
self.signal_size = (np.cumprod(self.signal_shape)[-1]
|
|
668
|
-
if self.signal_shape else 0)
|
|
669
|
-
self._update_max_index()
|
|
670
|
-
|
|
671
|
-
def _update_max_index(self):
|
|
672
|
-
self._max_index = 1
|
|
673
|
-
for i in self.navigation_shape:
|
|
674
|
-
self._max_index *= i
|
|
675
|
-
if self._max_index != 0:
|
|
676
|
-
self._max_index -= 1
|
|
677
|
-
|
|
678
|
-
@property
|
|
679
|
-
def shape(self):
|
|
680
|
-
nav_shape = (self.navigation_shape
|
|
681
|
-
if self.navigation_shape != (0,)
|
|
682
|
-
else tuple())
|
|
683
|
-
sig_shape = (self.signal_shape
|
|
684
|
-
if self.signal_shape != (0,)
|
|
685
|
-
else tuple())
|
|
686
|
-
return nav_shape + sig_shape
|
|
687
|
-
|
|
688
|
-
def _get_dimension_str(self):
|
|
689
|
-
string = "("
|
|
690
|
-
for axis in self.navigation_axes:
|
|
691
|
-
string += str(axis.size) + ", "
|
|
692
|
-
string = string.rstrip(", ")
|
|
693
|
-
string += "|"
|
|
694
|
-
for axis in self.signal_axes:
|
|
695
|
-
string += str(axis.size) + ", "
|
|
696
|
-
string = string.rstrip(", ")
|
|
697
|
-
string += ")"
|
|
698
|
-
return string
|
|
699
|
-
|
|
700
|
-
def __repr__(self):
|
|
701
|
-
text = ('<Axes manager, axes: %s>\n' %
|
|
702
|
-
self._get_dimension_str())
|
|
703
|
-
ax_signature = "% 16s | %6g | %6s | %7.2g | %7.2g | %6s "
|
|
704
|
-
signature = "% 16s | %6s | %6s | %7s | %7s | %6s "
|
|
705
|
-
text += signature % ('Name', 'size', 'index', 'offset', 'scale',
|
|
706
|
-
'units')
|
|
707
|
-
text += '\n'
|
|
708
|
-
text += signature % ('=' * 16, '=' * 6, '=' * 6,
|
|
709
|
-
'=' * 7, '=' * 7, '=' * 6)
|
|
710
|
-
for ax in self.navigation_axes:
|
|
711
|
-
text += '\n'
|
|
712
|
-
text += ax_signature % (str(ax.name)[:16], ax.size, str(ax.index),
|
|
713
|
-
ax.offset, ax.scale, ax.units)
|
|
714
|
-
text += '\n'
|
|
715
|
-
text += signature % ('-' * 16, '-' * 6, '-' * 6,
|
|
716
|
-
'-' * 7, '-' * 7, '-' * 6)
|
|
717
|
-
for ax in self.signal_axes:
|
|
718
|
-
text += '\n'
|
|
719
|
-
text += ax_signature % (str(ax.name)[:16], ax.size, ' ', ax.offset,
|
|
720
|
-
ax.scale, ax.units)
|
|
721
|
-
|
|
722
|
-
return text
|
|
723
|
-
|
|
724
|
-
def _update_axes(self, old_axes, navigation_axes, signal_axes):
|
|
725
|
-
|
|
726
|
-
for ind_ax, ax in enumerate(self._axes):
|
|
727
|
-
navigate = old_axes[ind_ax] in navigation_axes
|
|
728
|
-
ax.navigate = navigate
|
|
729
|
-
ax._update_slice(navigate)
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
class Signal(FancySlicing):
|
|
733
|
-
|
|
734
|
-
def __init__(self, data: np.ndarray, **kwds):
|
|
735
|
-
"""Create a Signal from a numpy array.
|
|
736
|
-
|
|
737
|
-
Parameters
|
|
738
|
-
----------
|
|
739
|
-
data : numpy array
|
|
740
|
-
The signal data. It can be an array of any dimensions.
|
|
741
|
-
axes : dictionary (optional)
|
|
742
|
-
Dictionary to define the axes (see the
|
|
743
|
-
documentation of the AxesManager class for more details).
|
|
744
|
-
"""
|
|
745
|
-
self.data = data
|
|
746
|
-
|
|
747
|
-
if 'axes' not in kwds:
|
|
748
|
-
kwds['axes'] = self._get_undefined_axes_list()
|
|
749
|
-
self.axes_manager = AxesManager(kwds['axes'])
|
|
750
|
-
|
|
751
|
-
self.inav = SpecialSlicersSignal(self, True)
|
|
752
|
-
self.isig = SpecialSlicersSignal(self, False)
|
|
753
|
-
|
|
754
|
-
def get_data_dimension(self):
|
|
755
|
-
dimension = "("
|
|
756
|
-
for ind, ax in enumerate(self.axes_manager.navigation_shape):
|
|
757
|
-
if ind != len(self.axes_manager.navigation_shape) - 1:
|
|
758
|
-
dimension += str(ax) + ','
|
|
759
|
-
else:
|
|
760
|
-
dimension += str(ax) + '|'
|
|
761
|
-
for ind, ax in enumerate(self.axes_manager.signal_shape):
|
|
762
|
-
if ind != len(self.axes_manager.signal_shape) - 1:
|
|
763
|
-
dimension += str(ax) + ','
|
|
764
|
-
else:
|
|
765
|
-
dimension += str(ax) + ')'
|
|
766
|
-
return dimension
|
|
767
|
-
|
|
768
|
-
def _remove_axis(self, axes):
|
|
769
|
-
am = self.axes_manager
|
|
770
|
-
axes = am[axes]
|
|
771
|
-
if not np.iterable(axes):
|
|
772
|
-
axes = (axes,)
|
|
773
|
-
if am.navigation_dimension + am.signal_dimension > len(axes):
|
|
774
|
-
old_signal_dimension = am.signal_dimension
|
|
775
|
-
am.remove(axes)
|
|
776
|
-
if old_signal_dimension != am.signal_dimension:
|
|
777
|
-
self._assign_subclass()
|
|
778
|
-
else:
|
|
779
|
-
# Create a "Scalar" axis because the axis is the last one left and
|
|
780
|
-
add_scalar_axis(self)
|
|
781
|
-
|
|
782
|
-
def _get_undefined_axes_list(self):
|
|
783
|
-
axes = []
|
|
784
|
-
for s in self.data.shape:
|
|
785
|
-
axes.append({'size': int(s), })
|
|
786
|
-
return axes
|
|
787
|
-
|
|
788
|
-
@property
|
|
789
|
-
def data(self):
|
|
790
|
-
return self._data
|
|
791
|
-
|
|
792
|
-
@data.setter
|
|
793
|
-
def data(self, value):
|
|
794
|
-
self._data = np.atleast_1d(np.asanyarray(value))
|
|
795
|
-
|
|
796
|
-
@property
|
|
797
|
-
def shape(self):
|
|
798
|
-
return self._data.shape
|
|
799
|
-
|
|
800
|
-
def __repr__(self):
|
|
801
|
-
unfolded = ""
|
|
802
|
-
string = '<'
|
|
803
|
-
string += self.__class__.__name__
|
|
804
|
-
string += ", %sdimensions: %s" % (
|
|
805
|
-
unfolded,
|
|
806
|
-
self.axes_manager._get_dimension_str())
|
|
807
|
-
|
|
808
|
-
string += '>'
|
|
809
|
-
|
|
810
|
-
return string
|
|
811
|
-
|
|
812
|
-
def _apply_function_on_data_and_remove_axis(self, function, axes,
|
|
813
|
-
out=None):
|
|
814
|
-
axes = self.axes_manager[axes]
|
|
815
|
-
if not np.iterable(axes):
|
|
816
|
-
axes = (axes,)
|
|
817
|
-
# Use out argument in numpy function when available for operations that
|
|
818
|
-
# do not return scalars in numpy.
|
|
819
|
-
np_out = not len(self.axes_manager._axes) == len(axes)
|
|
820
|
-
ar_axes = tuple(ax.index_in_array for ax in axes)
|
|
821
|
-
if len(ar_axes) == 1:
|
|
822
|
-
ar_axes = ar_axes[0]
|
|
823
|
-
|
|
824
|
-
s = out or self._deepcopy_with_new_data(None)
|
|
825
|
-
|
|
826
|
-
if np.ma.is_masked(self.data):
|
|
827
|
-
return self._ma_workaround(s=s, function=function, axes=axes,
|
|
828
|
-
ar_axes=ar_axes, out=out)
|
|
829
|
-
if out:
|
|
830
|
-
if np_out:
|
|
831
|
-
function(self.data, axis=ar_axes, out=out.data, )
|
|
832
|
-
else:
|
|
833
|
-
data = np.atleast_1d(function(self.data, axis=ar_axes, ))
|
|
834
|
-
if data.shape == out.data.shape:
|
|
835
|
-
out.data[:] = data
|
|
836
|
-
else:
|
|
837
|
-
raise ValueError(
|
|
838
|
-
"The output shape %s does not match the shape of "
|
|
839
|
-
"`out` %s" % (data.shape, out.data.shape))
|
|
840
|
-
out.events.data_changed.trigger(obj=out)
|
|
841
|
-
else:
|
|
842
|
-
s.data = np.atleast_1d(
|
|
843
|
-
function(self.data, axis=ar_axes, ))
|
|
844
|
-
s._remove_axis([ax.index_in_axes_manager for ax in axes])
|
|
845
|
-
return s
|
|
846
|
-
|
|
847
|
-
def sum(self, axis=None, out=None):
|
|
848
|
-
"""Sum the data over the given axes.
|
|
849
|
-
|
|
850
|
-
Parameters
|
|
851
|
-
----------
|
|
852
|
-
axis %s
|
|
853
|
-
%s
|
|
854
|
-
|
|
855
|
-
Returns
|
|
856
|
-
-------
|
|
857
|
-
s : Signal
|
|
858
|
-
|
|
859
|
-
See also
|
|
860
|
-
--------
|
|
861
|
-
max, min, mean, std, var, indexmax, valuemax, amax
|
|
862
|
-
|
|
863
|
-
Examples
|
|
864
|
-
--------
|
|
865
|
-
>>> import numpy as np
|
|
866
|
-
>>> s = BaseSignal(np.random.random((64,64,1024)))
|
|
867
|
-
>>> s.data.shape
|
|
868
|
-
(64,64,1024)
|
|
869
|
-
>>> s.sum(-1).data.shape
|
|
870
|
-
(64,64)
|
|
871
|
-
|
|
872
|
-
"""
|
|
873
|
-
if axis is None:
|
|
874
|
-
axis = self.axes_manager.navigation_axes
|
|
875
|
-
return self._apply_function_on_data_and_remove_axis(np.sum, axis,
|
|
876
|
-
out=out)
|
|
877
|
-
|
|
878
|
-
def halflife(self, axis=None, out=None):
|
|
879
|
-
if axis is None:
|
|
880
|
-
axis = self.axes_manager.navigation_axes
|
|
881
|
-
return self._apply_function_on_data_and_remove_axis(self._halflife_fun, axis,
|
|
882
|
-
out=out)
|
|
883
|
-
|
|
884
|
-
def _halflife_fun(self, sub_data, axis=None):
|
|
885
|
-
try:
|
|
886
|
-
|
|
887
|
-
indexes = [s for s in range(len(sub_data.shape)) if s not in [axis]]
|
|
888
|
-
out_shape = tuple(np.array((sub_data.shape))[indexes])
|
|
889
|
-
time = np.zeros((np.prod(out_shape)))
|
|
890
|
-
data_reshaped = sub_data.reshape((np.prod(out_shape), sub_data.shape[axis]))
|
|
891
|
-
for ind_dat in range(np.prod(out_shape)):
|
|
892
|
-
dat = data_reshaped[ind_dat, :]
|
|
893
|
-
ind_x0 = utils.find_index(dat, np.max(dat))[0][0]
|
|
894
|
-
sub_xaxis = np.linspace(0, len(dat), len(dat), endpoint=False)
|
|
895
|
-
x0 = sub_xaxis[ind_x0]
|
|
896
|
-
sub_xaxis = sub_xaxis[ind_x0:]
|
|
897
|
-
|
|
898
|
-
dat_clipped = dat[ind_x0:]
|
|
899
|
-
offset = dat_clipped[-1]
|
|
900
|
-
N0 = np.max(dat_clipped) - offset
|
|
901
|
-
thalf = sub_xaxis[utils.find_index(dat - offset, 0.5 * N0)[0][0]] - x0
|
|
902
|
-
time[ind_dat] = thalf
|
|
903
|
-
return time.reshape(out_shape)
|
|
904
|
-
except Exception as e:
|
|
905
|
-
return time.reshape(out_shape)
|
|
906
|
-
|
|
907
|
-
def max(self, axis=None, out=None):
|
|
908
|
-
"""Returns a signal with the maximum of the signal along at least one
|
|
909
|
-
axis.
|
|
910
|
-
|
|
911
|
-
Parameters
|
|
912
|
-
----------
|
|
913
|
-
axis %s
|
|
914
|
-
%s
|
|
915
|
-
|
|
916
|
-
Returns
|
|
917
|
-
-------
|
|
918
|
-
s : Signal
|
|
919
|
-
|
|
920
|
-
See also
|
|
921
|
-
--------
|
|
922
|
-
min, sum, mean, std, var, indexmax, valuemax, amax
|
|
923
|
-
|
|
924
|
-
Examples
|
|
925
|
-
--------
|
|
926
|
-
>>> import numpy as np
|
|
927
|
-
>>> s = BaseSignal(np.random.random((64,64,1024)))
|
|
928
|
-
>>> s.data.shape
|
|
929
|
-
(64,64,1024)
|
|
930
|
-
>>> s.max(-1).data.shape
|
|
931
|
-
(64,64)
|
|
932
|
-
|
|
933
|
-
"""
|
|
934
|
-
if axis is None:
|
|
935
|
-
axis = self.axes_manager.navigation_axes
|
|
936
|
-
return self._apply_function_on_data_and_remove_axis(np.max, axis,
|
|
937
|
-
out=out)
|
|
938
|
-
|
|
939
|
-
def min(self, axis=None, out=None):
|
|
940
|
-
"""Returns a signal with the minimum of the signal along at least one
|
|
941
|
-
axis.
|
|
942
|
-
|
|
943
|
-
Parameters
|
|
944
|
-
----------
|
|
945
|
-
axis %s
|
|
946
|
-
%s
|
|
947
|
-
|
|
948
|
-
Returns
|
|
949
|
-
-------
|
|
950
|
-
s : Signal
|
|
951
|
-
|
|
952
|
-
See also
|
|
953
|
-
--------
|
|
954
|
-
max, sum, mean, std, var, indexmax, valuemax, amax
|
|
955
|
-
|
|
956
|
-
Examples
|
|
957
|
-
--------
|
|
958
|
-
>>> import numpy as np
|
|
959
|
-
>>> s = BaseSignal(np.random.random((64,64,1024)))
|
|
960
|
-
>>> s.data.shape
|
|
961
|
-
(64,64,1024)
|
|
962
|
-
>>> s.min(-1).data.shape
|
|
963
|
-
(64,64)
|
|
964
|
-
|
|
965
|
-
"""
|
|
966
|
-
if axis is None:
|
|
967
|
-
axis = self.axes_manager.navigation_axes
|
|
968
|
-
return self._apply_function_on_data_and_remove_axis(np.min, axis,
|
|
969
|
-
out=out)
|
|
970
|
-
|
|
971
|
-
def mean(self, axis=None, out=None):
|
|
972
|
-
"""Returns a signal with the average of the signal along at least one
|
|
973
|
-
axis.
|
|
974
|
-
|
|
975
|
-
Parameters
|
|
976
|
-
----------
|
|
977
|
-
axis %s
|
|
978
|
-
%s
|
|
979
|
-
|
|
980
|
-
Returns
|
|
981
|
-
-------
|
|
982
|
-
s : Signal
|
|
983
|
-
|
|
984
|
-
See also
|
|
985
|
-
--------
|
|
986
|
-
max, min, sum, std, var, indexmax, valuemax, amax
|
|
987
|
-
|
|
988
|
-
Examples
|
|
989
|
-
--------
|
|
990
|
-
>>> import numpy as np
|
|
991
|
-
>>> s = BaseSignal(np.random.random((64,64,1024)))
|
|
992
|
-
>>> s.data.shape
|
|
993
|
-
(64,64,1024)
|
|
994
|
-
>>> s.mean(-1).data.shape
|
|
995
|
-
(64,64)
|
|
996
|
-
|
|
997
|
-
"""
|
|
998
|
-
if axis is None:
|
|
999
|
-
axis = self.axes_manager.navigation_axes
|
|
1000
|
-
return self._apply_function_on_data_and_remove_axis(np.mean, axis,
|
|
1001
|
-
out=out)
|
|
1002
|
-
|
|
1003
|
-
def std(self, axis=None, out=None):
|
|
1004
|
-
"""Returns a signal with the standard deviation of the signal along
|
|
1005
|
-
at least one axis.
|
|
1006
|
-
|
|
1007
|
-
Parameters
|
|
1008
|
-
----------
|
|
1009
|
-
axis %s
|
|
1010
|
-
%s
|
|
1011
|
-
|
|
1012
|
-
Returns
|
|
1013
|
-
-------
|
|
1014
|
-
s : Signal
|
|
1015
|
-
|
|
1016
|
-
See also
|
|
1017
|
-
--------
|
|
1018
|
-
max, min, sum, mean, var, indexmax, valuemax, amax
|
|
1019
|
-
|
|
1020
|
-
Examples
|
|
1021
|
-
--------
|
|
1022
|
-
>>> import numpy as np
|
|
1023
|
-
>>> s = BaseSignal(np.random.random((64,64,1024)))
|
|
1024
|
-
>>> s.data.shape
|
|
1025
|
-
(64,64,1024)
|
|
1026
|
-
>>> s.std(-1).data.shape
|
|
1027
|
-
(64,64)
|
|
1028
|
-
|
|
1029
|
-
"""
|
|
1030
|
-
if axis is None:
|
|
1031
|
-
axis = self.axes_manager.navigation_axes
|
|
1032
|
-
return self._apply_function_on_data_and_remove_axis(np.std, axis,
|
|
1033
|
-
out=out)
|
|
1034
|
-
|
|
1035
|
-
def var(self, axis=None, out=None):
|
|
1036
|
-
"""Returns a signal with the variances of the signal along at least one
|
|
1037
|
-
axis.
|
|
1038
|
-
|
|
1039
|
-
Parameters
|
|
1040
|
-
----------
|
|
1041
|
-
axis %s
|
|
1042
|
-
%s
|
|
1043
|
-
|
|
1044
|
-
Returns
|
|
1045
|
-
-------
|
|
1046
|
-
s : Signal
|
|
1047
|
-
|
|
1048
|
-
See also
|
|
1049
|
-
--------
|
|
1050
|
-
max, min, sum, mean, std, indexmax, valuemax, amax
|
|
1051
|
-
|
|
1052
|
-
Examples
|
|
1053
|
-
--------
|
|
1054
|
-
>>> import numpy as np
|
|
1055
|
-
>>> s = BaseSignal(np.random.random((64,64,1024)))
|
|
1056
|
-
>>> s.data.shape
|
|
1057
|
-
(64,64,1024)
|
|
1058
|
-
>>> s.var(-1).data.shape
|
|
1059
|
-
(64,64)
|
|
1060
|
-
|
|
1061
|
-
"""
|
|
1062
|
-
if axis is None:
|
|
1063
|
-
axis = self.axes_manager.navigation_axes
|
|
1064
|
-
return self._apply_function_on_data_and_remove_axis(np.var, axis,
|
|
1065
|
-
out=out)
|
|
1066
|
-
|
|
1067
|
-
def nansum(self, axis=None, out=None):
|
|
1068
|
-
"""%s
|
|
1069
|
-
"""
|
|
1070
|
-
if axis is None:
|
|
1071
|
-
axis = self.axes_manager.navigation_axes
|
|
1072
|
-
return self._apply_function_on_data_and_remove_axis(np.nansum, axis,
|
|
1073
|
-
out=out)
|
|
1074
|
-
|
|
1075
|
-
def nanmax(self, axis=None, out=None):
|
|
1076
|
-
"""%s
|
|
1077
|
-
"""
|
|
1078
|
-
if axis is None:
|
|
1079
|
-
axis = self.axes_manager.navigation_axes
|
|
1080
|
-
return self._apply_function_on_data_and_remove_axis(np.nanmax, axis,
|
|
1081
|
-
out=out)
|
|
1082
|
-
|
|
1083
|
-
def nanmin(self, axis=None, out=None):
|
|
1084
|
-
"""%s"""
|
|
1085
|
-
if axis is None:
|
|
1086
|
-
axis = self.axes_manager.navigation_axes
|
|
1087
|
-
return self._apply_function_on_data_and_remove_axis(np.nanmin, axis,
|
|
1088
|
-
out=out)
|
|
1089
|
-
|
|
1090
|
-
def nanmean(self, axis=None, out=None):
|
|
1091
|
-
"""%s """
|
|
1092
|
-
if axis is None:
|
|
1093
|
-
axis = self.axes_manager.navigation_axes
|
|
1094
|
-
return self._apply_function_on_data_and_remove_axis(np.nanmean, axis,
|
|
1095
|
-
out=out)
|
|
1096
|
-
|
|
1097
|
-
def nanstd(self, axis=None, out=None):
|
|
1098
|
-
"""%s"""
|
|
1099
|
-
if axis is None:
|
|
1100
|
-
axis = self.axes_manager.navigation_axes
|
|
1101
|
-
return self._apply_function_on_data_and_remove_axis(np.nanstd, axis,
|
|
1102
|
-
out=out)
|
|
1103
|
-
|
|
1104
|
-
def nanvar(self, axis=None, out=None):
|
|
1105
|
-
"""%s"""
|
|
1106
|
-
if axis is None:
|
|
1107
|
-
axis = self.axes_manager.navigation_axes
|
|
1108
|
-
return self._apply_function_on_data_and_remove_axis(np.nanvar, axis,
|
|
1109
|
-
out=out)
|
|
1110
|
-
|
|
1111
|
-
def diff(self, axis, order=1, out=None):
|
|
1112
|
-
"""Returns a signal with the n-th order discrete difference along
|
|
1113
|
-
given axis.
|
|
1114
|
-
|
|
1115
|
-
Parameters
|
|
1116
|
-
----------
|
|
1117
|
-
axis %s
|
|
1118
|
-
order : int
|
|
1119
|
-
the order of the derivative
|
|
1120
|
-
%s
|
|
1121
|
-
|
|
1122
|
-
See also
|
|
1123
|
-
--------
|
|
1124
|
-
max, min, sum, mean, std, var, indexmax, valuemax, amax
|
|
1125
|
-
|
|
1126
|
-
Examples
|
|
1127
|
-
--------
|
|
1128
|
-
>>> import numpy as np
|
|
1129
|
-
>>> s = BaseSignal(np.random.random((64,64,1024)))
|
|
1130
|
-
>>> s.data.shape
|
|
1131
|
-
(64,64,1024)
|
|
1132
|
-
>>> s.diff(-1).data.shape
|
|
1133
|
-
(64,64,1023)
|
|
1134
|
-
"""
|
|
1135
|
-
s = out or self._deepcopy_with_new_data(None)
|
|
1136
|
-
data = np.diff(self.data, n=order,
|
|
1137
|
-
axis=self.axes_manager[axis].index_in_array)
|
|
1138
|
-
if out is not None:
|
|
1139
|
-
out.data[:] = data
|
|
1140
|
-
else:
|
|
1141
|
-
s.data = data
|
|
1142
|
-
axis2 = s.axes_manager[axis]
|
|
1143
|
-
new_offset = self.axes_manager[axis].offset + (order * axis2.scale / 2)
|
|
1144
|
-
axis2.offset = new_offset
|
|
1145
|
-
s.get_dimensions_from_data()
|
|
1146
|
-
if out is None:
|
|
1147
|
-
return s
|
|
1148
|
-
else:
|
|
1149
|
-
out.events.data_changed.trigger(obj=out)
|
|
1150
|
-
|
|
1151
|
-
def transpose(self, signal_axes=None,
|
|
1152
|
-
navigation_axes=None, optimize=False):
|
|
1153
|
-
"""Transposes the signal to have the required signal and navigation
|
|
1154
|
-
axes.
|
|
1155
|
-
|
|
1156
|
-
Parameters
|
|
1157
|
-
----------
|
|
1158
|
-
signal_axes, navigation_axes : {None, int, iterable}
|
|
1159
|
-
With the exception of both parameters getting iterables, generally
|
|
1160
|
-
one has to be None (i.e. "floating"). The other one specifies
|
|
1161
|
-
either the required number or explicitly the axes to move to the
|
|
1162
|
-
corresponding space.
|
|
1163
|
-
If both are iterables, full control is given as long as all axes
|
|
1164
|
-
are assigned to one space only.
|
|
1165
|
-
optimize : bool [False]
|
|
1166
|
-
If the data should be re-ordered in memory, most likely making a
|
|
1167
|
-
copy. Ensures the fastest available iteration at the expense of
|
|
1168
|
-
memory.
|
|
1169
|
-
|
|
1170
|
-
See also
|
|
1171
|
-
--------
|
|
1172
|
-
T, as_signal2D, as_signal1D, hs.transpose
|
|
1173
|
-
|
|
1174
|
-
Examples
|
|
1175
|
-
--------
|
|
1176
|
-
>>> # just create a signal with many distinct dimensions
|
|
1177
|
-
>>> s = hs.signals.Signal(np.random.rand(1,2,3,4,5,6,7,8,9))
|
|
1178
|
-
>>> s
|
|
1179
|
-
<Signal, title: , dimensions: (|9, 8, 7, 6, 5, 4, 3, 2, 1)>
|
|
1180
|
-
|
|
1181
|
-
>>> s.transpose() # swap signal and navigation spaces
|
|
1182
|
-
<Signal, title: , dimensions: (9, 8, 7, 6, 5, 4, 3, 2, 1|)>
|
|
1183
|
-
|
|
1184
|
-
>>> s.T # a shortcut for no arguments
|
|
1185
|
-
<Signal, title: , dimensions: (9, 8, 7, 6, 5, 4, 3, 2, 1|)>
|
|
1186
|
-
|
|
1187
|
-
# roll to leave 5 axes in navigation space
|
|
1188
|
-
>>> s.transpose(signal_axes=5)
|
|
1189
|
-
<Signal, title: , dimensions: (4, 3, 2, 1|9, 8, 7, 6, 5)>
|
|
1190
|
-
|
|
1191
|
-
# roll leave 3 axes in navigation space
|
|
1192
|
-
>>> s.transpose(navigation_axes=3)
|
|
1193
|
-
<Signal, title: , dimensions: (3, 2, 1|9, 8, 7, 6, 5, 4)>
|
|
1194
|
-
|
|
1195
|
-
>>> # 3 explicitly defined axes in signal space
|
|
1196
|
-
>>> s.transpose(signal_axes=[0, 2, 6])
|
|
1197
|
-
<Signal, title: , dimensions: (8, 6, 5, 4, 2, 1|9, 7, 3)>
|
|
1198
|
-
|
|
1199
|
-
>>> # A mix of two lists, but specifying all axes explicitly
|
|
1200
|
-
>>> # The order of axes is preserved in both lists
|
|
1201
|
-
>>> s.transpose(navigation_axes=[1, 2, 3, 4, 5, 8], signal_axes=[0, 6, 7])
|
|
1202
|
-
<Signal, title: , dimensions: (8, 7, 6, 5, 4, 1|9, 3, 2)>
|
|
1203
|
-
|
|
1204
|
-
"""
|
|
1205
|
-
|
|
1206
|
-
am = self.axes_manager
|
|
1207
|
-
ns = self.axes_manager.navigation_axes + self.axes_manager.signal_axes
|
|
1208
|
-
ax_list = am._axes
|
|
1209
|
-
if isinstance(signal_axes, int):
|
|
1210
|
-
if navigation_axes is not None:
|
|
1211
|
-
raise ValueError("The navigation_axes are not None, even "
|
|
1212
|
-
"though just a number was given for "
|
|
1213
|
-
"signal_axes")
|
|
1214
|
-
if len(ax_list) < signal_axes:
|
|
1215
|
-
raise ValueError("Too many signal axes requested")
|
|
1216
|
-
if signal_axes < 0:
|
|
1217
|
-
raise ValueError("Can't have negative number of signal axes")
|
|
1218
|
-
elif signal_axes == 0:
|
|
1219
|
-
signal_axes = ()
|
|
1220
|
-
navigation_axes = ax_list[::-1]
|
|
1221
|
-
else:
|
|
1222
|
-
navigation_axes = ax_list[:-signal_axes][::-1]
|
|
1223
|
-
signal_axes = ax_list[-signal_axes:][::-1]
|
|
1224
|
-
elif iterable_not_string(signal_axes):
|
|
1225
|
-
signal_axes = tuple(am[ax] for ax in signal_axes)
|
|
1226
|
-
if navigation_axes is None:
|
|
1227
|
-
navigation_axes = tuple(ax for ax in ax_list
|
|
1228
|
-
if ax not in signal_axes)[::-1]
|
|
1229
|
-
elif iterable_not_string(navigation_axes):
|
|
1230
|
-
# want to keep the order
|
|
1231
|
-
navigation_axes = tuple(am[ax] for ax in navigation_axes)
|
|
1232
|
-
intersection = set(signal_axes).intersection(navigation_axes)
|
|
1233
|
-
if len(intersection):
|
|
1234
|
-
raise ValueError("At least one axis found in both spaces:"
|
|
1235
|
-
" {}".format(intersection))
|
|
1236
|
-
if len(am._axes) != (len(signal_axes) + len(navigation_axes)):
|
|
1237
|
-
raise ValueError("Not all current axes were assigned to a "
|
|
1238
|
-
"space")
|
|
1239
|
-
else:
|
|
1240
|
-
raise ValueError("navigation_axes has to be None or an iterable"
|
|
1241
|
-
" when signal_axes is iterable")
|
|
1242
|
-
elif signal_axes is None:
|
|
1243
|
-
if isinstance(navigation_axes, int):
|
|
1244
|
-
if len(ax_list) < navigation_axes:
|
|
1245
|
-
raise ValueError("Too many navigation axes requested")
|
|
1246
|
-
if navigation_axes < 0:
|
|
1247
|
-
raise ValueError(
|
|
1248
|
-
"Can't have negative number of navigation axes")
|
|
1249
|
-
elif navigation_axes == 0:
|
|
1250
|
-
navigation_axes = ()
|
|
1251
|
-
signal_axes = ax_list[::-1]
|
|
1252
|
-
else:
|
|
1253
|
-
signal_axes = ax_list[navigation_axes:][::-1]
|
|
1254
|
-
navigation_axes = ax_list[:navigation_axes][::-1]
|
|
1255
|
-
elif iterable_not_string(navigation_axes):
|
|
1256
|
-
navigation_axes = tuple(am[ax] for ax in
|
|
1257
|
-
navigation_axes)
|
|
1258
|
-
signal_axes = tuple(ax for ax in ax_list
|
|
1259
|
-
if ax not in navigation_axes)[::-1]
|
|
1260
|
-
elif navigation_axes is None:
|
|
1261
|
-
signal_axes = am.navigation_axes
|
|
1262
|
-
navigation_axes = am.signal_axes
|
|
1263
|
-
else:
|
|
1264
|
-
raise ValueError(
|
|
1265
|
-
"The passed navigation_axes argument is not valid")
|
|
1266
|
-
else:
|
|
1267
|
-
raise ValueError("The passed signal_axes argument is not valid")
|
|
1268
|
-
# translate to axes idx from actual objects for variance
|
|
1269
|
-
idx_sig = [ax.index_in_axes_manager for ax in signal_axes]
|
|
1270
|
-
idx_nav = [ax.index_in_axes_manager for ax in navigation_axes]
|
|
1271
|
-
# From now on we operate with axes in array order
|
|
1272
|
-
signal_axes = signal_axes[::-1]
|
|
1273
|
-
navigation_axes = navigation_axes[::-1]
|
|
1274
|
-
# get data view
|
|
1275
|
-
array_order = tuple(
|
|
1276
|
-
ax.index_in_array for ax in navigation_axes)
|
|
1277
|
-
array_order += tuple(ax.index_in_array for ax in signal_axes)
|
|
1278
|
-
newdata = self.data.transpose(array_order)
|
|
1279
|
-
res = self._deepcopy_with_new_data(newdata, copy_variance=True)
|
|
1280
|
-
|
|
1281
|
-
# reconfigure the axes of the axesmanager:
|
|
1282
|
-
ram = res.axes_manager
|
|
1283
|
-
# ram._update_trait_handlers(remove=True)
|
|
1284
|
-
ram._update_axes(self.axes_manager._axes, navigation_axes, signal_axes)
|
|
1285
|
-
|
|
1286
|
-
# _axes are ordered in array order
|
|
1287
|
-
ram._axes = [ram._axes[i] for i in array_order]
|
|
1288
|
-
for i, ax in enumerate(ram._axes):
|
|
1289
|
-
if i < len(navigation_axes):
|
|
1290
|
-
ax.navigate = True
|
|
1291
|
-
else:
|
|
1292
|
-
ax.navigate = False
|
|
1293
|
-
ram._update_attributes()
|
|
1294
|
-
|
|
1295
|
-
return res
|
|
1296
|
-
|
|
1297
|
-
@property
|
|
1298
|
-
def T(self):
|
|
1299
|
-
"""The transpose of the signal, with signal and navigation spaces
|
|
1300
|
-
swapped.
|
|
1301
|
-
"""
|
|
1302
|
-
return self.transpose()
|
|
1303
|
-
|
|
1304
|
-
def _deepcopy_with_new_data(self, data=None, copy_variance=False):
|
|
1305
|
-
"""Returns a deepcopy of itself replacing the data.
|
|
1306
|
-
|
|
1307
|
-
This method has the advantage over deepcopy that it does not
|
|
1308
|
-
copy the data what can save precious memory
|
|
1309
|
-
|
|
1310
|
-
Parameters
|
|
1311
|
-
---------
|
|
1312
|
-
data : {None | np.array}
|
|
1313
|
-
|
|
1314
|
-
Returns
|
|
1315
|
-
-------
|
|
1316
|
-
ns : Signal
|
|
1317
|
-
|
|
1318
|
-
"""
|
|
1319
|
-
old_np = None
|
|
1320
|
-
try:
|
|
1321
|
-
old_data = self.data
|
|
1322
|
-
self.data = None
|
|
1323
|
-
ns = self.deepcopy()
|
|
1324
|
-
ns.data = data
|
|
1325
|
-
return ns
|
|
1326
|
-
finally:
|
|
1327
|
-
self.data = old_data
|
|
1328
|
-
|
|
1329
|
-
def deepcopy(self):
|
|
1330
|
-
return copy.deepcopy(self)
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
if __name__ == '__main__':
|
|
1334
|
-
# import hyperspy.api as hs
|
|
1335
|
-
|
|
1336
|
-
data = np.array([[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]])
|
|
1337
|
-
|
|
1338
|
-
# signal_hs=hs.signals.BaseSignal(data)
|
|
1339
|
-
# print(signal_hs)
|
|
1340
|
-
# signal_hs_t=signal_hs.transpose(signal_axes=[1])
|
|
1341
|
-
# print(signal_hs_t)
|
|
1342
|
-
|
|
1343
|
-
signal = Signal(data)
|
|
1344
|
-
print(signal)
|
|
1345
|
-
|
|
1346
|
-
signal_t = signal.transpose(signal_axes=[1])
|
|
1347
|
-
print(signal_t)
|