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.

Files changed (399) hide show
  1. pymodaq/__init__.py +30 -23
  2. pymodaq/control_modules/daq_move.py +27 -14
  3. pymodaq/control_modules/daq_move_ui.py +28 -12
  4. pymodaq/control_modules/daq_viewer.py +38 -28
  5. pymodaq/control_modules/daq_viewer_ui.py +6 -6
  6. pymodaq/control_modules/mocks.py +1 -1
  7. pymodaq/control_modules/move_utility_classes.py +19 -10
  8. pymodaq/control_modules/utils.py +18 -12
  9. pymodaq/control_modules/viewer_utility_classes.py +13 -4
  10. pymodaq/dashboard.py +164 -115
  11. pymodaq/examples/custom_app.py +13 -16
  12. pymodaq/examples/custom_viewer.py +6 -6
  13. pymodaq/examples/function_plotter.py +13 -12
  14. pymodaq/examples/parameter_ex.py +50 -25
  15. pymodaq/examples/tcp_client.py +1 -1
  16. pymodaq/extensions/__init__.py +1 -1
  17. pymodaq/extensions/bayesian/bayesian_optimisation.py +15 -12
  18. pymodaq/extensions/bayesian/utils.py +10 -10
  19. pymodaq/extensions/console.py +10 -13
  20. pymodaq/extensions/{daq_logger.py → daq_logger/daq_logger.py} +36 -56
  21. pymodaq/{utils/db/db_logger → extensions/daq_logger/db}/db_logger.py +16 -15
  22. pymodaq/{utils/db/db_logger → extensions/daq_logger/db}/db_logger_models.py +2 -0
  23. pymodaq/{utils/h5modules → extensions/daq_logger}/h5logging.py +7 -8
  24. pymodaq/extensions/daq_scan.py +153 -247
  25. pymodaq/extensions/daq_scan_ui.py +11 -9
  26. pymodaq/extensions/h5browser.py +8 -8
  27. pymodaq/extensions/pid/__init__.py +6 -3
  28. pymodaq/extensions/pid/daq_move_PID.py +4 -2
  29. pymodaq/extensions/pid/pid_controller.py +15 -12
  30. pymodaq/extensions/pid/utils.py +10 -5
  31. pymodaq/extensions/utils.py +5 -3
  32. pymodaq/post_treatment/load_and_plot.py +10 -7
  33. pymodaq/resources/preset_default.xml +1 -1
  34. pymodaq/utils/array_manipulation.py +4 -384
  35. pymodaq/utils/calibration_camera.py +12 -9
  36. pymodaq/utils/chrono_timer.py +7 -5
  37. pymodaq/utils/config.py +3 -450
  38. pymodaq/utils/daq_utils.py +6 -708
  39. pymodaq/utils/data.py +9 -2774
  40. pymodaq/utils/exceptions.py +0 -4
  41. pymodaq/utils/gui_utils/__init__.py +8 -8
  42. pymodaq/utils/gui_utils/loader_utils.py +38 -0
  43. pymodaq/utils/gui_utils/utils.py +6 -138
  44. pymodaq/utils/h5modules/__init__.py +0 -4
  45. pymodaq/utils/h5modules/module_saving.py +15 -8
  46. pymodaq/utils/leco/__init__.py +2 -2
  47. pymodaq/utils/leco/daq_move_LECODirector.py +2 -2
  48. pymodaq/utils/leco/daq_xDviewer_LECODirector.py +2 -2
  49. pymodaq/utils/leco/director_utils.py +2 -2
  50. pymodaq/utils/leco/leco_director.py +3 -3
  51. pymodaq/utils/leco/pymodaq_listener.py +2 -2
  52. pymodaq/utils/leco/utils.py +1 -1
  53. pymodaq/utils/logger.py +4 -76
  54. pymodaq/utils/managers/batchscan_manager.py +16 -19
  55. pymodaq/utils/managers/modules_manager.py +10 -7
  56. pymodaq/utils/managers/overshoot_manager.py +3 -5
  57. pymodaq/utils/managers/preset_manager.py +37 -15
  58. pymodaq/utils/managers/preset_manager_utils.py +11 -9
  59. pymodaq/utils/managers/remote_manager.py +12 -10
  60. pymodaq/utils/math_utils.py +4 -572
  61. pymodaq/utils/parameter/__init__.py +4 -11
  62. pymodaq/utils/parameter/utils.py +4 -299
  63. pymodaq/utils/scanner/scan_config.py +1 -1
  64. pymodaq/utils/scanner/scan_factory.py +16 -12
  65. pymodaq/utils/{plotting → scanner}/scan_selector.py +19 -20
  66. pymodaq/utils/scanner/scanner.py +10 -8
  67. pymodaq/utils/scanner/scanners/_1d_scanners.py +8 -5
  68. pymodaq/utils/scanner/scanners/_2d_scanners.py +5 -5
  69. pymodaq/utils/scanner/scanners/sequential.py +8 -8
  70. pymodaq/utils/scanner/scanners/tabular.py +9 -9
  71. pymodaq/utils/scanner/utils.py +6 -4
  72. pymodaq/utils/svg/svg_viewer2D.py +3 -4
  73. pymodaq/utils/tcp_ip/serializer.py +64 -16
  74. pymodaq/utils/tcp_ip/tcp_server_client.py +10 -8
  75. {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/METADATA +5 -3
  76. pymodaq-5.0.0.dist-info/RECORD +123 -0
  77. pymodaq/post_treatment/process_to_scalar.py +0 -263
  78. pymodaq/resources/QtDesigner_Ressources/Icon_Library/1d.png +0 -0
  79. pymodaq/resources/QtDesigner_Ressources/Icon_Library/2d.png +0 -0
  80. pymodaq/resources/QtDesigner_Ressources/Icon_Library/3d.png +0 -0
  81. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Add2.png +0 -0
  82. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Add_Step.png +0 -0
  83. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Approve.png +0 -0
  84. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Approve_All.png +0 -0
  85. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Browse_Dir_Path.png +0 -0
  86. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Calculator.png +0 -0
  87. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnGroup.png +0 -0
  88. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnNum.png +0 -0
  89. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnText.png +0 -0
  90. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnTime.png +0 -0
  91. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ChnWave.png +0 -0
  92. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Close3.png +0 -0
  93. pymodaq/resources/QtDesigner_Ressources/Icon_Library/CollapseAll.png +0 -0
  94. pymodaq/resources/QtDesigner_Ressources/Icon_Library/CollapseAll_32.png +0 -0
  95. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ColorPicker.png +0 -0
  96. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Contract.png +0 -0
  97. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Create.png +0 -0
  98. pymodaq/resources/QtDesigner_Ressources/Icon_Library/DeleteLayer.png +0 -0
  99. pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditOpen.png +0 -0
  100. pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditRedo.png +0 -0
  101. pymodaq/resources/QtDesigner_Ressources/Icon_Library/EditUndo.png +0 -0
  102. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Ellipse.png +0 -0
  103. pymodaq/resources/QtDesigner_Ressources/Icon_Library/EllipseFilled.png +0 -0
  104. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Error.png +0 -0
  105. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ErrorMessage.png +0 -0
  106. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Error_16.png +0 -0
  107. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Exit.png +0 -0
  108. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Expand.png +0 -0
  109. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ExpandAll.png +0 -0
  110. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ExpandAll_32.png +0 -0
  111. pymodaq/resources/QtDesigner_Ressources/Icon_Library/FFT.png +0 -0
  112. pymodaq/resources/QtDesigner_Ressources/Icon_Library/HLM.ico +0 -0
  113. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Help.png +0 -0
  114. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Help_32.png +0 -0
  115. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Histogram.png +0 -0
  116. pymodaq/resources/QtDesigner_Ressources/Icon_Library/LUT_LookUpTable.png +0 -0
  117. pymodaq/resources/QtDesigner_Ressources/Icon_Library/MagnifyingGlass.png +0 -0
  118. pymodaq/resources/QtDesigner_Ressources/Icon_Library/MagnifyingGlass_24.png +0 -0
  119. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Marker.png +0 -0
  120. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Math.png +0 -0
  121. pymodaq/resources/QtDesigner_Ressources/Icon_Library/MeasurementStudio_32.png +0 -0
  122. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Move.png +0 -0
  123. pymodaq/resources/QtDesigner_Ressources/Icon_Library/MoveDown.png +0 -0
  124. pymodaq/resources/QtDesigner_Ressources/Icon_Library/MoveUp.png +0 -0
  125. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Multiply.png +0 -0
  126. pymodaq/resources/QtDesigner_Ressources/Icon_Library/NewFile.png +0 -0
  127. pymodaq/resources/QtDesigner_Ressources/Icon_Library/NewLayer.png +0 -0
  128. pymodaq/resources/QtDesigner_Ressources/Icon_Library/New_File.png +0 -0
  129. pymodaq/resources/QtDesigner_Ressources/Icon_Library/New_Folder.png +0 -0
  130. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open.png +0 -0
  131. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_1D.png +0 -0
  132. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_2D.png +0 -0
  133. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_File.png +0 -0
  134. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_File_32.png +0 -0
  135. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Open_sim.png +0 -0
  136. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Options.png +0 -0
  137. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Oscilloscope.png +0 -0
  138. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Oscilloscope_16.png +0 -0
  139. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Pass.png +0 -0
  140. pymodaq/resources/QtDesigner_Ressources/Icon_Library/RGB.png +0 -0
  141. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Rectangle.png +0 -0
  142. pymodaq/resources/QtDesigner_Ressources/Icon_Library/RectangleFilled.png +0 -0
  143. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Redo.png +0 -0
  144. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh.png +0 -0
  145. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh2.png +0 -0
  146. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Refresh_32.png +0 -0
  147. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Region.png +0 -0
  148. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Rendezvous.png +0 -0
  149. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SELECT.png +0 -0
  150. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save.png +0 -0
  151. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAll.png +0 -0
  152. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAll_32.png +0 -0
  153. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAs.png +0 -0
  154. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SaveAs_32.png +0 -0
  155. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save_24.png +0 -0
  156. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Save_32.png +0 -0
  157. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Search.png +0 -0
  158. pymodaq/resources/QtDesigner_Ressources/Icon_Library/SelectPolygon.png +0 -0
  159. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Select_24.png +0 -0
  160. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Settings.png +0 -0
  161. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snap&Save.png +0 -0
  162. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot.png +0 -0
  163. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2.png +0 -0
  164. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2_16.png +0 -0
  165. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Snapshot2_32.png +0 -0
  166. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Spreadsheet.png +0 -0
  167. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Statistics.png +0 -0
  168. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Statistics2.png +0 -0
  169. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Status.png +0 -0
  170. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Subtract.png +0 -0
  171. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Vision.png +0 -0
  172. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Volts.png +0 -0
  173. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Wait2.png +0 -0
  174. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_1_1.png +0 -0
  175. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_in.png +0 -0
  176. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_out.png +0 -0
  177. pymodaq/resources/QtDesigner_Ressources/Icon_Library/Zoom_to_Selection.png +0 -0
  178. pymodaq/resources/QtDesigner_Ressources/Icon_Library/abort.png +0 -0
  179. pymodaq/resources/QtDesigner_Ressources/Icon_Library/advanced2.png +0 -0
  180. pymodaq/resources/QtDesigner_Ressources/Icon_Library/autoscale.png +0 -0
  181. pymodaq/resources/QtDesigner_Ressources/Icon_Library/b_icon.png +0 -0
  182. pymodaq/resources/QtDesigner_Ressources/Icon_Library/back.png +0 -0
  183. pymodaq/resources/QtDesigner_Ressources/Icon_Library/bg_icon.png +0 -0
  184. pymodaq/resources/QtDesigner_Ressources/Icon_Library/camera.png +0 -0
  185. pymodaq/resources/QtDesigner_Ressources/Icon_Library/camera_snap.png +0 -0
  186. pymodaq/resources/QtDesigner_Ressources/Icon_Library/cartesian.png +0 -0
  187. pymodaq/resources/QtDesigner_Ressources/Icon_Library/clear2.png +0 -0
  188. pymodaq/resources/QtDesigner_Ressources/Icon_Library/clear_ROI.png +0 -0
  189. pymodaq/resources/QtDesigner_Ressources/Icon_Library/close2.png +0 -0
  190. pymodaq/resources/QtDesigner_Ressources/Icon_Library/cluster2.png +0 -0
  191. pymodaq/resources/QtDesigner_Ressources/Icon_Library/color.png +0 -0
  192. pymodaq/resources/QtDesigner_Ressources/Icon_Library/color2.png +0 -0
  193. pymodaq/resources/QtDesigner_Ressources/Icon_Library/continuous.png +0 -0
  194. pymodaq/resources/QtDesigner_Ressources/Icon_Library/data.png +0 -0
  195. pymodaq/resources/QtDesigner_Ressources/Icon_Library/delay.png +0 -0
  196. pymodaq/resources/QtDesigner_Ressources/Icon_Library/download.png +0 -0
  197. pymodaq/resources/QtDesigner_Ressources/Icon_Library/download2.png +0 -0
  198. pymodaq/resources/QtDesigner_Ressources/Icon_Library/error2.png +0 -0
  199. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ethernet.png +0 -0
  200. pymodaq/resources/QtDesigner_Ressources/Icon_Library/exit2.png +0 -0
  201. pymodaq/resources/QtDesigner_Ressources/Icon_Library/fan.png +0 -0
  202. pymodaq/resources/QtDesigner_Ressources/Icon_Library/filter2.png +0 -0
  203. pymodaq/resources/QtDesigner_Ressources/Icon_Library/g_icon.png +0 -0
  204. pymodaq/resources/QtDesigner_Ressources/Icon_Library/gear2.png +0 -0
  205. pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to.png +0 -0
  206. pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to_1.png +0 -0
  207. pymodaq/resources/QtDesigner_Ressources/Icon_Library/go_to_2.png +0 -0
  208. pymodaq/resources/QtDesigner_Ressources/Icon_Library/grab.png +0 -0
  209. pymodaq/resources/QtDesigner_Ressources/Icon_Library/graph.png +0 -0
  210. pymodaq/resources/QtDesigner_Ressources/Icon_Library/greenLight2.png +0 -0
  211. pymodaq/resources/QtDesigner_Ressources/Icon_Library/greenLight2_32.png +0 -0
  212. pymodaq/resources/QtDesigner_Ressources/Icon_Library/green_light.png +0 -0
  213. pymodaq/resources/QtDesigner_Ressources/Icon_Library/grey_icon.png +0 -0
  214. pymodaq/resources/QtDesigner_Ressources/Icon_Library/greyscale.png +0 -0
  215. pymodaq/resources/QtDesigner_Ressources/Icon_Library/help1.png +0 -0
  216. pymodaq/resources/QtDesigner_Ressources/Icon_Library/help1_32.png +0 -0
  217. pymodaq/resources/QtDesigner_Ressources/Icon_Library/home2.png +0 -0
  218. pymodaq/resources/QtDesigner_Ressources/Icon_Library/information2.png +0 -0
  219. pymodaq/resources/QtDesigner_Ressources/Icon_Library/ini.png +0 -0
  220. pymodaq/resources/QtDesigner_Ressources/Icon_Library/integrator.png +0 -0
  221. pymodaq/resources/QtDesigner_Ressources/Icon_Library/joystick.png +0 -0
  222. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_green.png +0 -0
  223. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_green_16.png +0 -0
  224. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_red.png +0 -0
  225. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_red_16.png +0 -0
  226. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_yellow.png +0 -0
  227. pymodaq/resources/QtDesigner_Ressources/Icon_Library/light_yellow_16.png +0 -0
  228. pymodaq/resources/QtDesigner_Ressources/Icon_Library/limiter.png +0 -0
  229. pymodaq/resources/QtDesigner_Ressources/Icon_Library/load_ROI.png +0 -0
  230. pymodaq/resources/QtDesigner_Ressources/Icon_Library/meshPlot.png +0 -0
  231. pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter.png +0 -0
  232. pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter2.png +0 -0
  233. pymodaq/resources/QtDesigner_Ressources/Icon_Library/meter_32.png +0 -0
  234. pymodaq/resources/QtDesigner_Ressources/Icon_Library/move_contour.png +0 -0
  235. pymodaq/resources/QtDesigner_Ressources/Icon_Library/move_straight_line.png +0 -0
  236. pymodaq/resources/QtDesigner_Ressources/Icon_Library/movie.png +0 -0
  237. pymodaq/resources/QtDesigner_Ressources/Icon_Library/multi_point.png +0 -0
  238. pymodaq/resources/QtDesigner_Ressources/Icon_Library/multiplexer.png +0 -0
  239. pymodaq/resources/QtDesigner_Ressources/Icon_Library/new.png +0 -0
  240. pymodaq/resources/QtDesigner_Ressources/Icon_Library/openArrow.png +0 -0
  241. pymodaq/resources/QtDesigner_Ressources/Icon_Library/openTree.png +0 -0
  242. pymodaq/resources/QtDesigner_Ressources/Icon_Library/oscilloscope2.png +0 -0
  243. pymodaq/resources/QtDesigner_Ressources/Icon_Library/oscilloscope3.png +0 -0
  244. pymodaq/resources/QtDesigner_Ressources/Icon_Library/overlay.png +0 -0
  245. pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass2.png +0 -0
  246. pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass2_16.png +0 -0
  247. pymodaq/resources/QtDesigner_Ressources/Icon_Library/pass_32.png +0 -0
  248. pymodaq/resources/QtDesigner_Ressources/Icon_Library/pause.png +0 -0
  249. pymodaq/resources/QtDesigner_Ressources/Icon_Library/permute.png +0 -0
  250. pymodaq/resources/QtDesigner_Ressources/Icon_Library/phase.png +0 -0
  251. pymodaq/resources/QtDesigner_Ressources/Icon_Library/play.png +0 -0
  252. pymodaq/resources/QtDesigner_Ressources/Icon_Library/polar.png +0 -0
  253. pymodaq/resources/QtDesigner_Ressources/Icon_Library/pole_zero.png +0 -0
  254. pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerMeter.png +0 -0
  255. pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerSwitch.png +0 -0
  256. pymodaq/resources/QtDesigner_Ressources/Icon_Library/powerSwitch_16.png +0 -0
  257. pymodaq/resources/QtDesigner_Ressources/Icon_Library/print2.png +0 -0
  258. pymodaq/resources/QtDesigner_Ressources/Icon_Library/print2_32.png +0 -0
  259. pymodaq/resources/QtDesigner_Ressources/Icon_Library/properties.png +0 -0
  260. pymodaq/resources/QtDesigner_Ressources/Icon_Library/r_icon.png +0 -0
  261. pymodaq/resources/QtDesigner_Ressources/Icon_Library/radiocontrolbutton.png +0 -0
  262. pymodaq/resources/QtDesigner_Ressources/Icon_Library/read2.png +0 -0
  263. pymodaq/resources/QtDesigner_Ressources/Icon_Library/red_light.png +0 -0
  264. pymodaq/resources/QtDesigner_Ressources/Icon_Library/remove.png +0 -0
  265. pymodaq/resources/QtDesigner_Ressources/Icon_Library/reset.png +0 -0
  266. pymodaq/resources/QtDesigner_Ressources/Icon_Library/rgb_icon.png +0 -0
  267. pymodaq/resources/QtDesigner_Ressources/Icon_Library/robot.png +0 -0
  268. pymodaq/resources/QtDesigner_Ressources/Icon_Library/rotation2.png +0 -0
  269. pymodaq/resources/QtDesigner_Ressources/Icon_Library/run2.png +0 -0
  270. pymodaq/resources/QtDesigner_Ressources/Icon_Library/run_all.png +0 -0
  271. pymodaq/resources/QtDesigner_Ressources/Icon_Library/saturation.png +0 -0
  272. pymodaq/resources/QtDesigner_Ressources/Icon_Library/saveTree.png +0 -0
  273. pymodaq/resources/QtDesigner_Ressources/Icon_Library/save_ROI.png +0 -0
  274. pymodaq/resources/QtDesigner_Ressources/Icon_Library/scale_horizontally.png +0 -0
  275. pymodaq/resources/QtDesigner_Ressources/Icon_Library/scale_vertically.png +0 -0
  276. pymodaq/resources/QtDesigner_Ressources/Icon_Library/search2.png +0 -0
  277. pymodaq/resources/QtDesigner_Ressources/Icon_Library/select2.png +0 -0
  278. pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_all.png +0 -0
  279. pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_all2.png +0 -0
  280. pymodaq/resources/QtDesigner_Ressources/Icon_Library/select_none.png +0 -0
  281. pymodaq/resources/QtDesigner_Ressources/Icon_Library/sequence.png +0 -0
  282. pymodaq/resources/QtDesigner_Ressources/Icon_Library/sequence2.png +0 -0
  283. pymodaq/resources/QtDesigner_Ressources/Icon_Library/snap.png +0 -0
  284. pymodaq/resources/QtDesigner_Ressources/Icon_Library/sort_ascend.png +0 -0
  285. pymodaq/resources/QtDesigner_Ressources/Icon_Library/spectrumAnalyzer.png +0 -0
  286. pymodaq/resources/QtDesigner_Ressources/Icon_Library/start.png +0 -0
  287. pymodaq/resources/QtDesigner_Ressources/Icon_Library/status_cancelled.png +0 -0
  288. pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop.png +0 -0
  289. pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop2.png +0 -0
  290. pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop3.png +0 -0
  291. pymodaq/resources/QtDesigner_Ressources/Icon_Library/stop_all.png +0 -0
  292. pymodaq/resources/QtDesigner_Ressources/Icon_Library/sum.png +0 -0
  293. pymodaq/resources/QtDesigner_Ressources/Icon_Library/surfacePlot.png +0 -0
  294. pymodaq/resources/QtDesigner_Ressources/Icon_Library/tree.png +0 -0
  295. pymodaq/resources/QtDesigner_Ressources/Icon_Library/updateTree.png +0 -0
  296. pymodaq/resources/QtDesigner_Ressources/Icon_Library/utility2.png +0 -0
  297. pymodaq/resources/QtDesigner_Ressources/Icon_Library/utility_small.png +0 -0
  298. pymodaq/resources/QtDesigner_Ressources/Icon_Library/vector.png +0 -0
  299. pymodaq/resources/QtDesigner_Ressources/Icon_Library/verify.png +0 -0
  300. pymodaq/resources/QtDesigner_Ressources/Icon_Library/video.png +0 -0
  301. pymodaq/resources/QtDesigner_Ressources/Icon_Library/wait.png +0 -0
  302. pymodaq/resources/QtDesigner_Ressources/Icon_Library/waterfallPlot.png +0 -0
  303. pymodaq/resources/QtDesigner_Ressources/Icon_Library/watershed.png +0 -0
  304. pymodaq/resources/QtDesigner_Ressources/Icon_Library/yellow_light.png +0 -0
  305. pymodaq/resources/QtDesigner_Ressources/Icon_Library/zip_file.png +0 -0
  306. pymodaq/resources/QtDesigner_Ressources/Icon_Library/zoomAuto.png +0 -0
  307. pymodaq/resources/QtDesigner_Ressources/Icon_Library/zoomReset.png +0 -0
  308. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.bat +0 -2
  309. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources.qrc +0 -234
  310. pymodaq/resources/QtDesigner_Ressources/QtDesigner_ressources_rc.py +0 -127150
  311. pymodaq/resources/QtDesigner_Ressources/icons.svg +0 -142
  312. pymodaq/resources/VERSION +0 -1
  313. pymodaq/resources/config_template.toml +0 -94
  314. pymodaq/resources/triangulation_data.npy +0 -0
  315. pymodaq/utils/abstract/__init__.py +0 -48
  316. pymodaq/utils/db/__init__.py +0 -0
  317. pymodaq/utils/db/db_logger/__init__.py +0 -0
  318. pymodaq/utils/enums.py +0 -76
  319. pymodaq/utils/factory.py +0 -82
  320. pymodaq/utils/gui_utils/custom_app.py +0 -133
  321. pymodaq/utils/gui_utils/dock.py +0 -107
  322. pymodaq/utils/gui_utils/file_io.py +0 -93
  323. pymodaq/utils/gui_utils/layout.py +0 -34
  324. pymodaq/utils/gui_utils/list_picker.py +0 -38
  325. pymodaq/utils/gui_utils/widgets/__init__.py +0 -5
  326. pymodaq/utils/gui_utils/widgets/label.py +0 -24
  327. pymodaq/utils/gui_utils/widgets/lcd.py +0 -111
  328. pymodaq/utils/gui_utils/widgets/push.py +0 -149
  329. pymodaq/utils/gui_utils/widgets/qled.py +0 -62
  330. pymodaq/utils/gui_utils/widgets/spinbox.py +0 -24
  331. pymodaq/utils/gui_utils/widgets/table.py +0 -263
  332. pymodaq/utils/gui_utils/widgets/tree_layout.py +0 -188
  333. pymodaq/utils/gui_utils/widgets/tree_toml.py +0 -102
  334. pymodaq/utils/h5modules/backends.py +0 -1022
  335. pymodaq/utils/h5modules/browsing.py +0 -625
  336. pymodaq/utils/h5modules/data_saving.py +0 -1105
  337. pymodaq/utils/h5modules/exporter.py +0 -119
  338. pymodaq/utils/h5modules/exporters/__init__.py +0 -0
  339. pymodaq/utils/h5modules/exporters/base.py +0 -111
  340. pymodaq/utils/h5modules/exporters/flimj.py +0 -63
  341. pymodaq/utils/h5modules/exporters/hyperspy.py +0 -143
  342. pymodaq/utils/h5modules/saving.py +0 -866
  343. pymodaq/utils/h5modules/utils.py +0 -115
  344. pymodaq/utils/managers/action_manager.py +0 -489
  345. pymodaq/utils/managers/parameter_manager.py +0 -282
  346. pymodaq/utils/managers/roi_manager.py +0 -726
  347. pymodaq/utils/messenger.py +0 -66
  348. pymodaq/utils/parameter/ioxml.py +0 -542
  349. pymodaq/utils/parameter/pymodaq_ptypes/__init__.py +0 -38
  350. pymodaq/utils/parameter/pymodaq_ptypes/bool.py +0 -31
  351. pymodaq/utils/parameter/pymodaq_ptypes/date.py +0 -126
  352. pymodaq/utils/parameter/pymodaq_ptypes/filedir.py +0 -143
  353. pymodaq/utils/parameter/pymodaq_ptypes/itemselect.py +0 -265
  354. pymodaq/utils/parameter/pymodaq_ptypes/led.py +0 -44
  355. pymodaq/utils/parameter/pymodaq_ptypes/list.py +0 -150
  356. pymodaq/utils/parameter/pymodaq_ptypes/numeric.py +0 -18
  357. pymodaq/utils/parameter/pymodaq_ptypes/pixmap.py +0 -175
  358. pymodaq/utils/parameter/pymodaq_ptypes/slide.py +0 -145
  359. pymodaq/utils/parameter/pymodaq_ptypes/table.py +0 -135
  360. pymodaq/utils/parameter/pymodaq_ptypes/tableview.py +0 -149
  361. pymodaq/utils/parameter/pymodaq_ptypes/text.py +0 -142
  362. pymodaq/utils/plotting/__init__.py +0 -0
  363. pymodaq/utils/plotting/data_viewers/__init__.py +0 -10
  364. pymodaq/utils/plotting/data_viewers/base.py +0 -286
  365. pymodaq/utils/plotting/data_viewers/viewer.py +0 -274
  366. pymodaq/utils/plotting/data_viewers/viewer0D.py +0 -298
  367. pymodaq/utils/plotting/data_viewers/viewer1D.py +0 -826
  368. pymodaq/utils/plotting/data_viewers/viewer1Dbasic.py +0 -231
  369. pymodaq/utils/plotting/data_viewers/viewer2D.py +0 -1118
  370. pymodaq/utils/plotting/data_viewers/viewer2D_basic.py +0 -146
  371. pymodaq/utils/plotting/data_viewers/viewerND.py +0 -800
  372. pymodaq/utils/plotting/gant_chart.py +0 -123
  373. pymodaq/utils/plotting/image_viewer.py +0 -97
  374. pymodaq/utils/plotting/items/__init__.py +0 -0
  375. pymodaq/utils/plotting/items/axis_scaled.py +0 -93
  376. pymodaq/utils/plotting/items/crosshair.py +0 -94
  377. pymodaq/utils/plotting/items/image.py +0 -388
  378. pymodaq/utils/plotting/navigator.py +0 -353
  379. pymodaq/utils/plotting/plotter/plotter.py +0 -94
  380. pymodaq/utils/plotting/plotter/plotters/__init__.py +0 -0
  381. pymodaq/utils/plotting/plotter/plotters/matplotlib_plotters.py +0 -134
  382. pymodaq/utils/plotting/plotter/plotters/qt_plotters.py +0 -78
  383. pymodaq/utils/plotting/utils/__init__.py +0 -0
  384. pymodaq/utils/plotting/utils/axes_viewer.py +0 -88
  385. pymodaq/utils/plotting/utils/filter.py +0 -585
  386. pymodaq/utils/plotting/utils/lineout.py +0 -226
  387. pymodaq/utils/plotting/utils/plot_utils.py +0 -579
  388. pymodaq/utils/plotting/utils/signalND.py +0 -1347
  389. pymodaq/utils/plotting/widgets.py +0 -76
  390. pymodaq/utils/qvariant.py +0 -12
  391. pymodaq/utils/slicing.py +0 -63
  392. pymodaq/utils/units.py +0 -216
  393. pymodaq-4.2.4.dist-info/RECORD +0 -438
  394. /pymodaq/{post_treatment/daq_analysis → extensions/daq_logger}/__init__.py +0 -0
  395. /pymodaq/{utils/abstract/logger.py → extensions/daq_logger/abstract.py} +0 -0
  396. /pymodaq/{resources/QtDesigner_Ressources → extensions/daq_logger/db}/__init__.py +0 -0
  397. {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/WHEEL +0 -0
  398. {pymodaq-4.2.4.dist-info → pymodaq-5.0.0.dist-info}/entry_points.txt +0 -0
  399. {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)