microeye 2.4.0rc2__tar.gz → 2.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. {microeye-2.4.0rc2/src/microeye.egg-info → microeye-2.4.2}/PKG-INFO +130 -11
  2. {microeye-2.4.0rc2 → microeye-2.4.2}/README.md +129 -10
  3. microeye-2.4.2/src/microEye/_version.py +2 -0
  4. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/basler/basler_panel.py +25 -9
  5. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/camera_panel.py +5 -3
  6. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/micam.py +32 -16
  7. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/mieye/acquisition_manager.py +7 -5
  8. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/kinesis/kinesis.py +27 -14
  9. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/manager.py +6 -2
  10. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/piezon_concept/foc.py +5 -11
  11. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/pycromanager/core.py +35 -16
  12. microeye-2.4.2/src/microEye/hardware/stages/smaract/mcs2.py +758 -0
  13. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/stabilization/methods.py +24 -10
  14. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/stabilizer.py +94 -35
  15. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/stage.py +91 -24
  16. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/view.py +52 -5
  17. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/widgets/focusWidget.py +41 -1
  18. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/widgets/slides.py +9 -4
  19. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/display.py +6 -1
  20. {microeye-2.4.0rc2 → microeye-2.4.2/src/microeye.egg-info}/PKG-INFO +130 -11
  21. microeye-2.4.0rc2/src/microEye/_version.py +0 -2
  22. microeye-2.4.0rc2/src/microEye/hardware/stages/smaract/mcs2.py +0 -125
  23. {microeye-2.4.0rc2 → microeye-2.4.2}/LICENSE +0 -0
  24. {microeye-2.4.0rc2 → microeye-2.4.2}/MANIFEST.in +0 -0
  25. {microeye-2.4.0rc2 → microeye-2.4.2}/pyproject.toml +0 -0
  26. {microeye-2.4.0rc2 → microeye-2.4.2}/setup.cfg +0 -0
  27. {microeye-2.4.0rc2 → microeye-2.4.2}/setup.py +0 -0
  28. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/__init__.py +0 -0
  29. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/__init__.py +0 -0
  30. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/checklist_dialog.py +0 -0
  31. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/cmosMaps.py +0 -0
  32. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/filters/__init__.py +0 -0
  33. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/filters/base.py +0 -0
  34. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/filters/spatial.py +0 -0
  35. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/filters/temporal.py +0 -0
  36. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/__init__.py +0 -0
  37. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/fit.py +0 -0
  38. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/nena.py +0 -0
  39. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/phasor_fit.py +0 -0
  40. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/processing.py +0 -0
  41. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/__init__.py +0 -0
  42. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/extract.py +0 -0
  43. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/rubost_mean.py +0 -0
  44. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/spline.py +0 -0
  45. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/stats/__init__.py +0 -0
  46. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/stats/core.py +0 -0
  47. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/stats/curve_fit.py +0 -0
  48. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/stats/io.py +0 -0
  49. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/stats/slope_fit.py +0 -0
  50. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/temp.py +0 -0
  51. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/psf/test.py +0 -0
  52. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUfunctions.py +0 -0
  53. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUmleFit_LM.py +0 -0
  54. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUsplineLib.py +0 -0
  55. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/CPU/__init__.py +0 -0
  56. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUfunctions.py +0 -0
  57. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_EMCCD.py +0 -0
  58. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_sCMOS.py +0 -0
  59. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUsplineLib.py +0 -0
  60. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/GPU/__init__.py +0 -0
  61. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/__init__.py +0 -0
  62. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/constants.py +0 -0
  63. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/pyfit3Dcspline/mainfunctions.py +0 -0
  64. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/rcc.py +0 -0
  65. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/results.py +0 -0
  66. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/results_stats.py +0 -0
  67. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/fitting/tardis.py +0 -0
  68. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/multi_viewer.py +0 -0
  69. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/processing/__init__.py +0 -0
  70. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/processing/frc.py +0 -0
  71. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/rendering/__init__.py +0 -0
  72. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/rendering/base.py +0 -0
  73. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/rendering/cloud.py +0 -0
  74. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/rendering/core.py +0 -0
  75. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/rendering/volumetric.py +0 -0
  76. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/__init__.py +0 -0
  77. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/common.py +0 -0
  78. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/dark_cal/__init__.py +0 -0
  79. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/dark_cal/analysis.py +0 -0
  80. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/dark_cal/compare.py +0 -0
  81. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/dark_cal/constants.py +0 -0
  82. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/dark_cal/core.py +0 -0
  83. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/dark_cal/io.py +0 -0
  84. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/dark_cal/plotting.py +0 -0
  85. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/kymograms.py +0 -0
  86. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/photon_cal/__init__.py +0 -0
  87. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/photon_cal/analysis.py +0 -0
  88. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/photon_cal/compare.py +0 -0
  89. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/photon_cal/constants.py +0 -0
  90. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/photon_cal/core.py +0 -0
  91. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/photon_cal/io.py +0 -0
  92. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/photon_cal/models.py +0 -0
  93. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/photon_cal/plotting.py +0 -0
  94. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/photon_cal/table.py +0 -0
  95. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/registration.py +0 -0
  96. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/roi_selectors.py +0 -0
  97. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/tools/sphere_cal.py +0 -0
  98. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/utils/__init__.py +0 -0
  99. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/utils/coordinates.py +0 -0
  100. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/utils/images.py +0 -0
  101. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/utils/windows.py +0 -0
  102. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/viewer/__init__.py +0 -0
  103. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/viewer/image_options_widget.py +0 -0
  104. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/viewer/images.py +0 -0
  105. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/viewer/layers_widget.py +0 -0
  106. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/viewer/localizations.py +0 -0
  107. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/viewer/psf.py +0 -0
  108. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/analysis/viewer/volume.py +0 -0
  109. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/__init__.py +0 -0
  110. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/__init__.py +0 -0
  111. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/basler/__init__.py +0 -0
  112. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/basler/basler_cam.py +0 -0
  113. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/camera_calibration.py +0 -0
  114. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/camera_list.py +0 -0
  115. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/camera_options.py +0 -0
  116. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/dummy/__init__.py +0 -0
  117. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/dummy/dummy_panel.py +0 -0
  118. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/jobs.py +0 -0
  119. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/line_profiler.py +0 -0
  120. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/linescan/IR_Cam.py +0 -0
  121. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/linescan/__init__.py +0 -0
  122. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/pco/__init__.py +0 -0
  123. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/pco/enums.py +0 -0
  124. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/pco/pco_cam.py +0 -0
  125. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/pco/pco_panel.py +0 -0
  126. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/peak/__init__.py +0 -0
  127. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/peak/peak_camera.py +0 -0
  128. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/peak/peak_panel.py +0 -0
  129. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/pycromanager/__init__.py +0 -0
  130. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/pycromanager/pycro_cam.py +0 -0
  131. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/pycromanager/pycro_panel.py +0 -0
  132. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/shortcuts.py +0 -0
  133. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/thorlabs/__init__.py +0 -0
  134. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/thorlabs/thorlabs.py +0 -0
  135. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/thorlabs/thorlabs_panel.py +0 -0
  136. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/ueye/__init__.py +0 -0
  137. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/ueye/ueye_camera.py +0 -0
  138. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/ueye/ueye_panel.py +0 -0
  139. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/vimba/__init__.py +0 -0
  140. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/vimba/vimba_cam.py +0 -0
  141. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/cams/vimba/vimba_panel.py +0 -0
  142. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/device.py +0 -0
  143. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/lasers/__init__.py +0 -0
  144. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/lasers/io_matchbox.py +0 -0
  145. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/lasers/io_params.py +0 -0
  146. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/lasers/io_single_laser.py +0 -0
  147. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/lasers/laser_relay.py +0 -0
  148. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/mieye/__init__.py +0 -0
  149. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/mieye/devices_manager.py +0 -0
  150. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/mieye/miEye.py +0 -0
  151. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/misc/__init__.py +0 -0
  152. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/misc/acquisition_view.py +0 -0
  153. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/misc/reglo.py +0 -0
  154. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/misc/temp.py +0 -0
  155. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/port_config.py +0 -0
  156. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/protocols/__init__.py +0 -0
  157. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/protocols/actions.py +0 -0
  158. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/protocols/actions_items.py +0 -0
  159. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/protocols/designer.py +0 -0
  160. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/protocols/scene_manager.py +0 -0
  161. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/protocols/serialization.py +0 -0
  162. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/pycromanager/__init__.py +0 -0
  163. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/pycromanager/core.py +0 -0
  164. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/pycromanager/devices.py +0 -0
  165. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/pycromanager/enums.py +0 -0
  166. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/pycromanager/headless.py +0 -0
  167. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/pycromanager/utils.py +0 -0
  168. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/pycromanager/widgets/__init__.py +0 -0
  169. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/pycromanager/widgets/bridges.py +0 -0
  170. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/pycromanager/widgets/headless_manager.py +0 -0
  171. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/pycromanager/widgets/headless_options.py +0 -0
  172. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/__init__.py +0 -0
  173. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/__init__.py +0 -0
  174. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/baseDevice.py +0 -0
  175. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/device.py +0 -0
  176. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/deviceID.py +0 -0
  177. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/devicePort.py +0 -0
  178. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/deviceStatus.py +0 -0
  179. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/devicesView.py +0 -0
  180. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/ellDevices.py +0 -0
  181. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/messageUpdater.py +0 -0
  182. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/motorInfo.py +0 -0
  183. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/stage.py +0 -0
  184. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/elliptec/test.py +0 -0
  185. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/kinesis/__init__.py +0 -0
  186. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/kinesis/kdc101/__init__.py +0 -0
  187. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/kinesis/kdc101/enums.py +0 -0
  188. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/kinesis/kdc101/factory.py +0 -0
  189. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/kinesis/kdc101/kdc101.py +0 -0
  190. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/piezon_concept/__init__.py +0 -0
  191. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/pycromanager/__init__.py +0 -0
  192. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/smaract/__init__.py +0 -0
  193. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/stabilization/__init__.py +0 -0
  194. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/stages/stabilization/controller.py +0 -0
  195. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/widgets/__init__.py +0 -0
  196. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/widgets/controller.py +0 -0
  197. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/widgets/devices.py +0 -0
  198. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/widgets/indicator.py +0 -0
  199. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/widgets/qlist_slider.py +0 -0
  200. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/hardware/widgets/scan_acquisition.py +0 -0
  201. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/1024.png +0 -0
  202. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/128.png +0 -0
  203. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/16.png +0 -0
  204. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/24.png +0 -0
  205. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/256.png +0 -0
  206. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/32.png +0 -0
  207. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/48.png +0 -0
  208. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/512.png +0 -0
  209. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/64.png +0 -0
  210. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/__init__.py +0 -0
  211. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/close.svg +0 -0
  212. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/mieye.png +0 -0
  213. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/min.svg +0 -0
  214. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/icons/viewer.png +0 -0
  215. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/images/__init__.py +0 -0
  216. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/images/handlers.py +0 -0
  217. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/images/uImage.py +0 -0
  218. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/images/zarr.py +0 -0
  219. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/launcher.py +0 -0
  220. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/qt.py +0 -0
  221. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/tools/__init__.py +0 -0
  222. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/tools/color.py +0 -0
  223. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/tools/microscopy.py +0 -0
  224. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/__init__.py +0 -0
  225. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/enum_encoder.py +0 -0
  226. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/expandable_groupbox.py +0 -0
  227. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/gui_helper.py +0 -0
  228. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/hid_utils/__init__.py +0 -0
  229. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/hid_utils/controller.py +0 -0
  230. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/hid_utils/device.py +0 -0
  231. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/hid_utils/enums.py +0 -0
  232. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/hid_utils/utils.py +0 -0
  233. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/labelled_slider.py +0 -0
  234. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/metadata.py +0 -0
  235. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/metadata_tree.py +0 -0
  236. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/micro_launcher.py +0 -0
  237. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/parameter_tree.py +0 -0
  238. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/pyscripting.py +0 -0
  239. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/retry_exec.py +0 -0
  240. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/start_gui.py +0 -0
  241. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microEye/utils/thread_worker.py +0 -0
  242. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microeye.egg-info/SOURCES.txt +0 -0
  243. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microeye.egg-info/dependency_links.txt +0 -0
  244. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microeye.egg-info/entry_points.txt +0 -0
  245. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microeye.egg-info/requires.txt +0 -0
  246. {microeye-2.4.0rc2 → microeye-2.4.2}/src/microeye.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: microeye
3
- Version: 2.4.0rc2
3
+ Version: 2.4.2
4
4
  Summary: A python toolkit for fluorescence microscopy that features hardware control, data analysis and vizualization for super-resolution single-molecule localization microscopy and single-partical tracking.
5
5
  Home-page: https://github.com/samhitech/microEye
6
6
  Author: Mohammad Nour Alsamsam
@@ -72,14 +72,15 @@ The **`microEye`** is a Python toolkit for fluorescence microscopy that supports
72
72
  This toolkit is compatible with the [hardware](#hardware) used in our microscope. For further details, refer to the [miEye microscope paper](https://doi.org/10.1016/j.ohx.2022.e00368) and [OSF project](http://doi.org/10.17605/osf.io/j2fqy).
73
73
 
74
74
  ```bash
75
- __ ____ ____ ___ ____ ___ ___
76
- / |/ (_)__________ / __/_ _____ _ __|_ |/ / / / _ \________|_ |
77
- / /|_/ / / __/ __/ _ \/ _// // / -_) | |/ / __//_ _// // / __/ __/ __/
78
- /_/ /_/_/\__/_/ \___/___/\_, /\__/ |___/____(_)_/(_)___/_/ \__/____/
79
- /___/
75
+ __ ____ ____ ___ ____ ___
76
+ / |/ (_)__________ / __/_ _____ _ __|_ |/ / / |_ |
77
+ / /|_/ / / __/ __/ _ \/ _// // / -_) | |/ / __//_ _/ / __/
78
+ /_/ /_/_/\__/_/ \___/___/\_, /\__/ |___/____(_)_/(_)____/
79
+ /___/
80
80
  ```
81
81
 
82
82
  <!-- ![Package Health](https://snyk.io/advisor/python/microEye/badge.svg) -->
83
+
83
84
  ![Python Version](https://img.shields.io/badge/Python-3.11-blue)
84
85
  ![Package Version](https://img.shields.io/pypi/v/microEye.svg)
85
86
  ![Package Version](https://img.shields.io/badge/GUI_Platform-PySide6|PyQt6|PyQt5-navy)
@@ -103,9 +104,132 @@ This toolkit is compatible with the [hardware](#hardware) used in our microscope
103
104
  ![GitHub Forks](https://img.shields.io/github/forks/samhitech/microEye.svg)
104
105
  ![GitHub Stars](https://img.shields.io/github/stars/samhitech/microEye.svg)
105
106
 
107
+ ## What's New in microEye 2.4
108
+
109
+ - **Stage Control Overhaul**
110
+
111
+ Stage management has been completely redesigned with a unified controller
112
+ that handles all stage types through a single, consistent interface. A new
113
+ Stage Manager lets you add, remove, and assign stages to axes on the fly.
114
+ Per-axis soft limits, configurable center positions, and a new Calibrate
115
+ action make setup safer and more repeatable. Dedicated **XY and Z Center
116
+ buttons** in the Controller dock move stages to their configured center
117
+ positions in one click.
118
+
119
+ - **SmarAct MCS2 Support**
120
+
121
+ Full support for SmarAct MCS2 multi-channel controllers, including guided
122
+ setup, calibration, homing, and soft-limit configuration for reliable
123
+ multi-axis motion.
124
+
125
+ - **Slides Widget**
126
+
127
+ A new Slides dock lets you visualize and navigate multi-channel slide
128
+ layouts (Sticky-Slide VI, µ-Slide VI, 8/18 Well, and more). Click any
129
+ channel to move the stage to its center, with live position and delta
130
+ readouts, position overlays, and context menu options for axis orientation
131
+ and inversion. Layout settings persist across sessions.
132
+
133
+ - **Focus Stabilization Improvements**
134
+
135
+ The focus stabilizer has been thoroughly refactored. Each axis now has
136
+ independent PID gains and calibration. New stabilization methods are
137
+ supported — including Reflection peak fitting, Fiducial/Fourier, and a
138
+ Hybrid XYZ mode. Frame statistics (count, mean, median) are now tracked
139
+ and the stabilizer waits for a sufficient number of frames before locking,
140
+ reducing false engagements. Plots dynamically show only the data relevant
141
+ to the active method, and all settings persist across sessions.
142
+
143
+ - **New Analysis & Calibration Tools**
144
+
145
+ Three new calibration workflows are available from the Multi-Viewer Tools
146
+ menu:
147
+ - **Dark Calibration** — directory-based mean/variance analysis with
148
+ results cache, import/export, and dataset comparison.
149
+ - **Photon Transfer Curve (PTC)** — dataset import, run/cache workflows,
150
+ cache comparison, and Dark-Cal JSON export.
151
+ - **Sphere Power Calibration** — calibration utilities integrated into
152
+ the PTC workflow.
153
+
154
+ A new **Image Registration** tool for aligning and merging multi-channel
155
+ stacks (with transformation export/import) is also available in the
156
+ Multi-Viewer Tools menu.
157
+
158
+ - **Expanded Camera Support**
159
+
160
+ Cameras from Basler, Allied Vision (Vimba X SDK), IDS Peak, Thorlabs,
161
+ PCO, and PycroManager now share unified ROI, exposure, and framerate
162
+ handling. Notable additions:
163
+ - **IDS Peak** is newly supported with binning, flash, and full ROI and
164
+ acquisition flow.
165
+ - **Basler** is newly supported.
166
+ - **Vimba X** gains black level, gain, correction, and binning controls,
167
+ plus CTI auto-discovery via `VIMBA_X_HOME` / `VIMBA_X_CTI`.
168
+ - All camera configurations are **automatically saved and restored** on
169
+ next launch when detected.
170
+
171
+ - **Laser & Device Controls**
172
+
173
+ The Controller dock now shows color-coded, wavelength-aware indicators
174
+ for each laser and relay. Clicking an indicator toggles the laser state
175
+ directly from the main UI. Relay mode labels (ON/F1/F2) are shown
176
+ alongside each laser.
177
+
178
+ - **Experiment Protocol Designer**
179
+
180
+ The protocol action list gains a new **ListLoop** action type for
181
+ repeating sequences of steps. The parameter adjustment UI now sorts
182
+ target objects, shows readable labels, and correctly handles integer and
183
+ float editors.
184
+
185
+ - **Program-Wide Logging**
186
+
187
+ Structured logging replaces scattered print statements across the entire
188
+ codebase. Log level, file output, and console output are configurable via
189
+ the launcher UI or CLI flags (`--log-level`, `--no-log-file`,
190
+ `--no-log-console`). Logs are written per session under `./logs` for
191
+ easier troubleshooting.
192
+
193
+ - **Image I/O & Data Handling**
194
+
195
+ Image handling has been refactored into a dedicated `microEye.images`
196
+ package. Zarr V3 is now fully supported for streaming and saving
197
+ acquisition data, with both zipped and directory store support.
198
+
199
+ - **Multi-Viewer Improvements**
200
+
201
+ The Multi-Viewer gains an **"Opened Files" dock** for quick switching
202
+ between open datasets, a **Registration Tool** for stack alignment, and
203
+ new menu entries for the Dark Calibration and PTC tools — all accessible
204
+ as MDI subwindows.
205
+
206
+ - **Display & Performance**
207
+
208
+ Focus widget plots have been rewritten to eliminate GUI freezes at high
209
+ framerates (tested at ~165 Hz). A new optional **crosshair overlay** can
210
+ be enabled on any camera display. OpenGL rendering is now used for image
211
+ display. Application startup is faster thanks to deferred initialization
212
+ of heavy components.
213
+
214
+ - **Stability & Compatibility**
215
+ - GPU imports are safely guarded on CPU-only systems.
216
+ - Qt binding selection is configurable at launch via CLI or environment
217
+ variable.
218
+ - Spatial filters (DoG, PointGaussFilter, Fourier) are faster via FFT
219
+ convolution and Numba acceleration.
220
+ - Qt6 compatibility fixes for mouse event handling.
221
+ - `PiezoConcept FOC` stage adapter fixes a float/int mismatch that caused
222
+ random Z jumps.
223
+
224
+ ---
225
+
226
+ > ⚠️ **Breaking Change:** Zarr V3 support requires **Python 3.11 or
227
+ > newer**. Python 3.9 and 3.10 are no longer supported.
228
+
106
229
  ## Table of Contents
107
230
 
108
231
  - [The microEye](#the-microeye)
232
+ - [What's New in microEye 2.4](#whats-new-in-microeye-24)
109
233
  - [Table of Contents](#table-of-contents)
110
234
  - [How to Install microEye](#how-to-install-microeye)
111
235
  - [Troubleshooting Installation](#troubleshooting-installation)
@@ -151,7 +275,6 @@ This toolkit is compatible with the [hardware](#hardware) used in our microscope
151
275
  ```
152
276
 
153
277
  3. **Install specific hardware drivers: (Optional)**
154
-
155
278
  - Allied Vision CMOS cameras:
156
279
 
157
280
  Install the [`Vimba X SDK`](https://www.alliedvision.com/en/products/software/vimba-x-sdk/) (_avoid installing it inside the Program Files directory_). After installation, navigate to the `Python API` directory (e.g., `C:\Allied Vision\Vimba X\api\python`) where the `vmbpy` wheel file (`.whl`) is located, and install it using:
@@ -165,7 +288,6 @@ This toolkit is compatible with the [hardware](#hardware) used in our microscope
165
288
  It has been observed that `vmbpy` can hang when initializing `GenICAM` transport layers (TLs) if the `GENICAM_GENTL64_PATH` environment variable contains `.cti` folders from other providers (e.g., `IDS Peak` or `pylon`). To avoid this, restrict `Vimba X` to load only its own TLs by explicitly specifying the `Vimba X` `.cti` directory in `VmbC.xml`.
166
289
 
167
290
  **Steps**
168
-
169
291
  1. **Auto (recommended)**
170
292
 
171
293
  Set the `VIMBA_X_HOME` environment variable to your `Vimba X` installation directory. `microEye` will read `VIMBA_X_HOME` at startup and use it to point the Vimba X transport-layer (`.cti`) configuration (e.g., `VIMBA_X_HOME/cti`).
@@ -178,7 +300,6 @@ This toolkit is compatible with the [hardware](#hardware) used in our microscope
178
300
 
179
301
  - Basler CMOS cameras: Install [`pylon`](https://www.baslerweb.com/en/downloads/software/?srsltid=AfmBOoqsMrbQT24hcWiCw-0ptD9PR7nCrPMBZSzi0YlI1CVItNQikMKW&downloadCategory.values.label.data=pylon) (_avoid installing it inside the Program Files directory_).
180
302
  - IDS CMOS cameras:
181
-
182
303
  - Install [`IDS Software Suite 4.96.1`](https://en.ids-imaging.com/download-details/AB00604.html?os=windows&version=win10&bus=64&floatcalc=) for Windows 32/64-bit.
183
304
  - Alternatively, [`IDS Peak Extended Setup`](https://en.ids-imaging.com/download-peak.html) is prefered as it support old uEye models and the new uEye+ ones.
184
305
 
@@ -389,14 +510,12 @@ The following table lists the hardware devices that are integrated and supported
389
510
  ### How to Use
390
511
 
391
512
  1. **Headless Manager**:
392
-
393
513
  - Open the `miEye_module` and navigate to `Tools -> Micro-Manager Headless Manager` in the main menu.
394
514
  - Start a new headless instance using a specific configuration file.
395
515
  - Stop individual running instances or terminate all instances simultaneously.
396
516
  - Save configurations for future use or load previously saved configurations for headless instances.
397
517
 
398
518
  2. **Core Instances**:
399
-
400
519
  - Open the `miEye_module` and navigate to `Tools -> Micro-Manager Core Bridges` in the main menu.
401
520
  - Click on `Add Core Bridge` and provide the port address in the dialog box.
402
521
  - A list of connected devices will be displayed, allowing you to view each device's properties.
@@ -7,14 +7,15 @@ The **`microEye`** is a Python toolkit for fluorescence microscopy that supports
7
7
  This toolkit is compatible with the [hardware](#hardware) used in our microscope. For further details, refer to the [miEye microscope paper](https://doi.org/10.1016/j.ohx.2022.e00368) and [OSF project](http://doi.org/10.17605/osf.io/j2fqy).
8
8
 
9
9
  ```bash
10
- __ ____ ____ ___ ____ ___ ___
11
- / |/ (_)__________ / __/_ _____ _ __|_ |/ / / / _ \________|_ |
12
- / /|_/ / / __/ __/ _ \/ _// // / -_) | |/ / __//_ _// // / __/ __/ __/
13
- /_/ /_/_/\__/_/ \___/___/\_, /\__/ |___/____(_)_/(_)___/_/ \__/____/
14
- /___/
10
+ __ ____ ____ ___ ____ ___
11
+ / |/ (_)__________ / __/_ _____ _ __|_ |/ / / |_ |
12
+ / /|_/ / / __/ __/ _ \/ _// // / -_) | |/ / __//_ _/ / __/
13
+ /_/ /_/_/\__/_/ \___/___/\_, /\__/ |___/____(_)_/(_)____/
14
+ /___/
15
15
  ```
16
16
 
17
17
  <!-- ![Package Health](https://snyk.io/advisor/python/microEye/badge.svg) -->
18
+
18
19
  ![Python Version](https://img.shields.io/badge/Python-3.11-blue)
19
20
  ![Package Version](https://img.shields.io/pypi/v/microEye.svg)
20
21
  ![Package Version](https://img.shields.io/badge/GUI_Platform-PySide6|PyQt6|PyQt5-navy)
@@ -38,9 +39,132 @@ This toolkit is compatible with the [hardware](#hardware) used in our microscope
38
39
  ![GitHub Forks](https://img.shields.io/github/forks/samhitech/microEye.svg)
39
40
  ![GitHub Stars](https://img.shields.io/github/stars/samhitech/microEye.svg)
40
41
 
42
+ ## What's New in microEye 2.4
43
+
44
+ - **Stage Control Overhaul**
45
+
46
+ Stage management has been completely redesigned with a unified controller
47
+ that handles all stage types through a single, consistent interface. A new
48
+ Stage Manager lets you add, remove, and assign stages to axes on the fly.
49
+ Per-axis soft limits, configurable center positions, and a new Calibrate
50
+ action make setup safer and more repeatable. Dedicated **XY and Z Center
51
+ buttons** in the Controller dock move stages to their configured center
52
+ positions in one click.
53
+
54
+ - **SmarAct MCS2 Support**
55
+
56
+ Full support for SmarAct MCS2 multi-channel controllers, including guided
57
+ setup, calibration, homing, and soft-limit configuration for reliable
58
+ multi-axis motion.
59
+
60
+ - **Slides Widget**
61
+
62
+ A new Slides dock lets you visualize and navigate multi-channel slide
63
+ layouts (Sticky-Slide VI, µ-Slide VI, 8/18 Well, and more). Click any
64
+ channel to move the stage to its center, with live position and delta
65
+ readouts, position overlays, and context menu options for axis orientation
66
+ and inversion. Layout settings persist across sessions.
67
+
68
+ - **Focus Stabilization Improvements**
69
+
70
+ The focus stabilizer has been thoroughly refactored. Each axis now has
71
+ independent PID gains and calibration. New stabilization methods are
72
+ supported — including Reflection peak fitting, Fiducial/Fourier, and a
73
+ Hybrid XYZ mode. Frame statistics (count, mean, median) are now tracked
74
+ and the stabilizer waits for a sufficient number of frames before locking,
75
+ reducing false engagements. Plots dynamically show only the data relevant
76
+ to the active method, and all settings persist across sessions.
77
+
78
+ - **New Analysis & Calibration Tools**
79
+
80
+ Three new calibration workflows are available from the Multi-Viewer Tools
81
+ menu:
82
+ - **Dark Calibration** — directory-based mean/variance analysis with
83
+ results cache, import/export, and dataset comparison.
84
+ - **Photon Transfer Curve (PTC)** — dataset import, run/cache workflows,
85
+ cache comparison, and Dark-Cal JSON export.
86
+ - **Sphere Power Calibration** — calibration utilities integrated into
87
+ the PTC workflow.
88
+
89
+ A new **Image Registration** tool for aligning and merging multi-channel
90
+ stacks (with transformation export/import) is also available in the
91
+ Multi-Viewer Tools menu.
92
+
93
+ - **Expanded Camera Support**
94
+
95
+ Cameras from Basler, Allied Vision (Vimba X SDK), IDS Peak, Thorlabs,
96
+ PCO, and PycroManager now share unified ROI, exposure, and framerate
97
+ handling. Notable additions:
98
+ - **IDS Peak** is newly supported with binning, flash, and full ROI and
99
+ acquisition flow.
100
+ - **Basler** is newly supported.
101
+ - **Vimba X** gains black level, gain, correction, and binning controls,
102
+ plus CTI auto-discovery via `VIMBA_X_HOME` / `VIMBA_X_CTI`.
103
+ - All camera configurations are **automatically saved and restored** on
104
+ next launch when detected.
105
+
106
+ - **Laser & Device Controls**
107
+
108
+ The Controller dock now shows color-coded, wavelength-aware indicators
109
+ for each laser and relay. Clicking an indicator toggles the laser state
110
+ directly from the main UI. Relay mode labels (ON/F1/F2) are shown
111
+ alongside each laser.
112
+
113
+ - **Experiment Protocol Designer**
114
+
115
+ The protocol action list gains a new **ListLoop** action type for
116
+ repeating sequences of steps. The parameter adjustment UI now sorts
117
+ target objects, shows readable labels, and correctly handles integer and
118
+ float editors.
119
+
120
+ - **Program-Wide Logging**
121
+
122
+ Structured logging replaces scattered print statements across the entire
123
+ codebase. Log level, file output, and console output are configurable via
124
+ the launcher UI or CLI flags (`--log-level`, `--no-log-file`,
125
+ `--no-log-console`). Logs are written per session under `./logs` for
126
+ easier troubleshooting.
127
+
128
+ - **Image I/O & Data Handling**
129
+
130
+ Image handling has been refactored into a dedicated `microEye.images`
131
+ package. Zarr V3 is now fully supported for streaming and saving
132
+ acquisition data, with both zipped and directory store support.
133
+
134
+ - **Multi-Viewer Improvements**
135
+
136
+ The Multi-Viewer gains an **"Opened Files" dock** for quick switching
137
+ between open datasets, a **Registration Tool** for stack alignment, and
138
+ new menu entries for the Dark Calibration and PTC tools — all accessible
139
+ as MDI subwindows.
140
+
141
+ - **Display & Performance**
142
+
143
+ Focus widget plots have been rewritten to eliminate GUI freezes at high
144
+ framerates (tested at ~165 Hz). A new optional **crosshair overlay** can
145
+ be enabled on any camera display. OpenGL rendering is now used for image
146
+ display. Application startup is faster thanks to deferred initialization
147
+ of heavy components.
148
+
149
+ - **Stability & Compatibility**
150
+ - GPU imports are safely guarded on CPU-only systems.
151
+ - Qt binding selection is configurable at launch via CLI or environment
152
+ variable.
153
+ - Spatial filters (DoG, PointGaussFilter, Fourier) are faster via FFT
154
+ convolution and Numba acceleration.
155
+ - Qt6 compatibility fixes for mouse event handling.
156
+ - `PiezoConcept FOC` stage adapter fixes a float/int mismatch that caused
157
+ random Z jumps.
158
+
159
+ ---
160
+
161
+ > ⚠️ **Breaking Change:** Zarr V3 support requires **Python 3.11 or
162
+ > newer**. Python 3.9 and 3.10 are no longer supported.
163
+
41
164
  ## Table of Contents
42
165
 
43
166
  - [The microEye](#the-microeye)
167
+ - [What's New in microEye 2.4](#whats-new-in-microeye-24)
44
168
  - [Table of Contents](#table-of-contents)
45
169
  - [How to Install microEye](#how-to-install-microeye)
46
170
  - [Troubleshooting Installation](#troubleshooting-installation)
@@ -86,7 +210,6 @@ This toolkit is compatible with the [hardware](#hardware) used in our microscope
86
210
  ```
87
211
 
88
212
  3. **Install specific hardware drivers: (Optional)**
89
-
90
213
  - Allied Vision CMOS cameras:
91
214
 
92
215
  Install the [`Vimba X SDK`](https://www.alliedvision.com/en/products/software/vimba-x-sdk/) (_avoid installing it inside the Program Files directory_). After installation, navigate to the `Python API` directory (e.g., `C:\Allied Vision\Vimba X\api\python`) where the `vmbpy` wheel file (`.whl`) is located, and install it using:
@@ -100,7 +223,6 @@ This toolkit is compatible with the [hardware](#hardware) used in our microscope
100
223
  It has been observed that `vmbpy` can hang when initializing `GenICAM` transport layers (TLs) if the `GENICAM_GENTL64_PATH` environment variable contains `.cti` folders from other providers (e.g., `IDS Peak` or `pylon`). To avoid this, restrict `Vimba X` to load only its own TLs by explicitly specifying the `Vimba X` `.cti` directory in `VmbC.xml`.
101
224
 
102
225
  **Steps**
103
-
104
226
  1. **Auto (recommended)**
105
227
 
106
228
  Set the `VIMBA_X_HOME` environment variable to your `Vimba X` installation directory. `microEye` will read `VIMBA_X_HOME` at startup and use it to point the Vimba X transport-layer (`.cti`) configuration (e.g., `VIMBA_X_HOME/cti`).
@@ -113,7 +235,6 @@ This toolkit is compatible with the [hardware](#hardware) used in our microscope
113
235
 
114
236
  - Basler CMOS cameras: Install [`pylon`](https://www.baslerweb.com/en/downloads/software/?srsltid=AfmBOoqsMrbQT24hcWiCw-0ptD9PR7nCrPMBZSzi0YlI1CVItNQikMKW&downloadCategory.values.label.data=pylon) (_avoid installing it inside the Program Files directory_).
115
237
  - IDS CMOS cameras:
116
-
117
238
  - Install [`IDS Software Suite 4.96.1`](https://en.ids-imaging.com/download-details/AB00604.html?os=windows&version=win10&bus=64&floatcalc=) for Windows 32/64-bit.
118
239
  - Alternatively, [`IDS Peak Extended Setup`](https://en.ids-imaging.com/download-peak.html) is prefered as it support old uEye models and the new uEye+ ones.
119
240
 
@@ -324,14 +445,12 @@ The following table lists the hardware devices that are integrated and supported
324
445
  ### How to Use
325
446
 
326
447
  1. **Headless Manager**:
327
-
328
448
  - Open the `miEye_module` and navigate to `Tools -> Micro-Manager Headless Manager` in the main menu.
329
449
  - Start a new headless instance using a specific configuration file.
330
450
  - Stop individual running instances or terminate all instances simultaneously.
331
451
  - Save configurations for future use or load previously saved configurations for headless instances.
332
452
 
333
453
  2. **Core Instances**:
334
-
335
454
  - Open the `miEye_module` and navigate to `Tools -> Micro-Manager Core Bridges` in the main menu.
336
455
  - Click on `Add Core Bridge` and provide the port address in the dialog box.
337
456
  - A list of connected devices will be displayed, allowing you to view each device's properties.
@@ -0,0 +1,2 @@
1
+ version_info = (2, 4, 2)
2
+ __version__ = '.'.join(map(str, version_info))
@@ -1,10 +1,16 @@
1
1
  import logging
2
2
  import traceback
3
3
  from time import perf_counter_ns
4
+ from typing import Optional
4
5
 
5
6
  from microEye.hardware.cams.basler.basler_cam import BaslerParams, basler_cam, pylon
6
7
  from microEye.hardware.cams.camera_options import CamParams
7
- from microEye.hardware.cams.camera_panel import AcquisitionJob, Camera_Panel, Queue
8
+ from microEye.hardware.cams.camera_panel import (
9
+ AcquisitionJob,
10
+ Camera_Panel,
11
+ Parameter,
12
+ Queue,
13
+ )
8
14
  from microEye.qt import (
9
15
  QDateTime,
10
16
  QtCore,
@@ -164,7 +170,7 @@ class Basler_Panel(Camera_Panel):
164
170
  # start a timer to update the camera params
165
171
  self.timer = QtCore.QTimer(self)
166
172
  self.timer.setSingleShot(True)
167
- self.timer.setInterval(1000)
173
+ self.timer.setInterval(250) # Update every 250 ms after a change
168
174
  self.timer.timeout.connect(self.update_params)
169
175
  self.timer.start()
170
176
 
@@ -192,10 +198,6 @@ class Basler_Panel(Camera_Panel):
192
198
  )
193
199
 
194
200
  with param.treeChangeBlocker():
195
- if value != param.value():
196
- param.setValue(value)
197
- if enabled != param.opts.get('enabled', True):
198
- param.setOpts(enabled=enabled)
199
201
  if limits and (
200
202
  len(limits) != len(param.opts.get('limits', []))
201
203
  or any(
@@ -206,6 +208,10 @@ class Basler_Panel(Camera_Panel):
206
208
  )
207
209
  ):
208
210
  param.setLimits(limits)
211
+ if value != param.value():
212
+ param.setValue(value)
213
+ if enabled != param.opts.get('enabled', True):
214
+ param.setOpts(enabled=enabled)
209
215
  except Exception as e:
210
216
  logging.getLogger(__name__).error(
211
217
  f"Error updating parameter {prop.get('name', 'unknown')}: {e}"
@@ -215,12 +221,22 @@ class Basler_Panel(Camera_Panel):
215
221
  self.refresh_exposure()
216
222
 
217
223
  worker = QThreadWorker(update)
218
- worker.signals.finished.connect(
219
- self.timer.start
220
- ) # Restart the timer after fetching stats
224
+ # worker.signals.finished.connect(
225
+ # self.timer.start
226
+ # ) # Restart the timer after fetching stats
221
227
 
222
228
  QtCore.QThreadPool.globalInstance().start(worker)
223
229
 
230
+ def update_cam(self, param: Optional[Parameter], param_value):
231
+ path = super().update_cam(param, param_value)
232
+
233
+ # Restart the timer to update the camera params after a change
234
+ if hasattr(self, 'timer') and self.timer is not None:
235
+ self.timer.start()
236
+
237
+ if path is None:
238
+ return
239
+
224
240
  @property
225
241
  def cam(self):
226
242
  '''The basler_cam property.
@@ -4,7 +4,7 @@ import re
4
4
  import threading
5
5
  import traceback
6
6
  from queue import Queue
7
- from typing import Union
7
+ from typing import Optional, Union
8
8
 
9
9
  import numpy as np
10
10
  from pyqtgraph.parametertree import Parameter
@@ -520,14 +520,16 @@ class Camera_Panel(QtWidgets.QGroupBox):
520
520
 
521
521
  self.camera_options.set_roi_info(x, y, w, h)
522
522
 
523
- def update_cam(self, param: Union[Parameter, None], param_value):
523
+ def update_cam(self, param: Optional[Parameter], param_value):
524
524
  path = self.camera_options.param_tree.childPath(param)
525
525
 
526
526
  if path is None:
527
- return
527
+ return None
528
528
 
529
529
  self.cam.update_cam(param, path, param_value)
530
530
 
531
+ return path
532
+
531
533
  def refresh_framerate(self, value=None):
532
534
  pass
533
535
 
@@ -781,32 +781,48 @@ class miDummy(miCamera):
781
781
  '''
782
782
  noise = kwargs.get('noise', 0) # noise to add to fiducial positions
783
783
  drift = kwargs.get('drift', [0, 0, 0]) # drift in x, y, z
784
+ psf_model = kwargs.get('psf_model', 'airy').lower()
785
+ airy_scale = kwargs.get('airy_scale', 1.22)
784
786
  kernel_size = int(6 * max(sigma_x, sigma_y)) | 1 # odd size, covers >99% of PSF
785
787
 
786
- x = np.arange(self.width)
787
- y = np.arange(self.height)
788
- X, Y = np.meshgrid(x, y)
789
-
790
- pattern = np.zeros((self.width, self.height), dtype=np.float64)
788
+ pattern = np.zeros((self.height, self.width), dtype=np.float64)
791
789
 
792
- ax, ay = 1 / (2 * sigma_x**2), 1 / (2 * sigma_y**2)
790
+ eps = np.finfo(np.float64).eps
791
+ ax, ay = 1 / (2 * sigma_x**2 + eps), 1 / (2 * sigma_y**2 + eps)
793
792
  for fid in fiducials:
794
793
  x = fid[0]
795
794
  y = fid[1]
796
795
 
797
796
  x += drift[0] + (np.random.random_sample() - 0.5) * noise
798
797
  y += drift[1] + (np.random.random_sample() - 0.5) * noise
799
- x_slice = slice(
800
- int(max(x - kernel_size, 0)), int(min(x + kernel_size, self.width))
801
- )
802
- y_slice = slice(
803
- int(max(y - kernel_size, 0)), int(min(y + kernel_size, self.height))
804
- )
798
+ x0 = int(max(x - kernel_size, 0))
799
+ x1 = int(min(x + kernel_size, self.width))
800
+ y0 = int(max(y - kernel_size, 0))
801
+ y1 = int(min(y + kernel_size, self.height))
802
+
803
+ if x1 <= x0 or y1 <= y0:
804
+ continue
805
+
806
+ x_local = np.arange(x0, x1, dtype=np.float64) - x
807
+ y_local = np.arange(y0, y1, dtype=np.float64) - y
808
+
809
+ if psf_model == 'airy':
810
+ # Airy-like approximation using sinc^2 radial profile.
811
+ r = np.sqrt(
812
+ np.add.outer(
813
+ (y_local / (sigma_y + np.random.random_sample() * 0.1 + eps))
814
+ ** 2,
815
+ (x_local / (sigma_x + np.random.random_sample() * 0.1 + eps))
816
+ ** 2,
817
+ )
818
+ )
819
+ patch = np.sinc(r / (airy_scale + eps)) ** 2
820
+ else:
821
+ gx = np.exp(-(x_local**2) * ax)
822
+ gy = np.exp(-(y_local**2) * ay)
823
+ patch = np.multiply.outer(gy, gx)
805
824
 
806
- pattern[y_slice, x_slice] += self.drift_amplitude * np.exp(
807
- -((X[y_slice, x_slice] - x) ** 2) * ax
808
- - ((Y[y_slice, x_slice] - y) ** 2) * ay
809
- )
825
+ pattern[y0:y1, x0:x1] += self.drift_amplitude * patch
810
826
 
811
827
  if pattern.min() < 0:
812
828
  pattern += abs(pattern.min())
@@ -366,9 +366,13 @@ def z_stack_acquisition(
366
366
 
367
367
  if (
368
368
  FocusStabilizer.instance().isFocusStabilized(Axis.Z)
369
- and FocusStabilizer.instance().useCal()
369
+ and FocusStabilizer.instance().isAdjustSetPoint()
370
370
  ):
371
- value = FocusStabilizer.instance().calCoeff(Axis.Z) * step_size
371
+ value = step_size
372
+ if not FocusStabilizer.instance().useCal():
373
+ value /= FocusStabilizer.instance().calCoeff(
374
+ Axis.Z
375
+ )
372
376
  if reverse:
373
377
  value *= -1
374
378
  FocusStabilizer.instance().setParameter(value, True)
@@ -463,9 +467,7 @@ def z_calibration(
463
467
  QtCore.QThread.msleep(delay * nFrames)
464
468
  positions[x, 0] = x * step_size
465
469
  _, snapshot = FocusStabilizer.instance().tracker_snapshot
466
- positions[x, 1] = np.mean(
467
- snapshot[-nFrames:, 2]
468
- )
470
+ positions[x, 1] = np.mean(snapshot[-nFrames:, 2])
469
471
  else:
470
472
  logger.warning('Z-calibration failed!')
471
473
  info = [{'Z-Stage Open': stage_manager.z_stage().is_open()}]
@@ -1,3 +1,4 @@
1
+ import logging
1
2
  import traceback
2
3
  from typing import Optional
3
4
 
@@ -16,6 +17,8 @@ from microEye.qt import QtCore, QtSerialPort, QtWidgets, Signal
16
17
  from microEye.utils.parameter_tree import Tree
17
18
  from microEye.utils.thread_worker import QThreadWorker
18
19
 
20
+ logger = logging.getLogger(__name__)
21
+
19
22
 
20
23
  class KinesisXY(AbstractStage):
21
24
  '''Class for controlling Two Kinesis Devices as an XY Stage'''
@@ -30,6 +33,7 @@ class KinesisXY(AbstractStage):
30
33
  axes=(Axis.X, Axis.Y),
31
34
  readyRead=None,
32
35
  center=kwargs.get('center', [17, 13]),
36
+ min_factor=kwargs.get('min_factor', 0),
33
37
  )
34
38
 
35
39
  self.X = KDC101Controller(portName=x_port)
@@ -58,8 +62,11 @@ class KinesisXY(AbstractStage):
58
62
  force = kwargs.get('force', False)
59
63
  is_async = kwargs.get('is_async', True)
60
64
 
61
- x = round(max(0, min(self.x_max, x)), self.prec)
62
- y = round(max(0, min(self.y_max, y)), self.prec)
65
+ x = self._clamp(Axis.X, x)
66
+ y = self._clamp(Axis.Y, y)
67
+
68
+ x = round(x, self.prec)
69
+ y = round(y, self.prec)
63
70
  if x != self.X.position or force:
64
71
  self.run_async(self.X.move_absolute, x, is_async=is_async)
65
72
  if y != self.Y.position or force:
@@ -71,6 +78,7 @@ class KinesisXY(AbstractStage):
71
78
 
72
79
  x = round(x, self.prec)
73
80
  y = round(y, self.prec)
81
+
74
82
  if x != 0:
75
83
  self.run_async(self.X.move_relative, x, is_async=is_async)
76
84
  if y != 0:
@@ -120,18 +128,23 @@ class KinesisXY(AbstractStage):
120
128
  if not isinstance(config, dict):
121
129
  raise ValueError('Config must be a dictionary.')
122
130
 
123
- super().load_config(config)
124
-
125
- x_config = config.get('X', {})
126
- y_config = config.get('Y', {})
127
-
128
- if isinstance(x_config, dict):
129
- self.X.setBaudRate(x_config.get('baudrate', 115200))
130
- self.X.setPortName(x_config.get('port', 'COM12'))
131
-
132
- if isinstance(y_config, dict):
133
- self.Y.setBaudRate(y_config.get('baudrate', 115200))
134
- self.Y.setPortName(y_config.get('port', 'COM13'))
131
+ try:
132
+ x_config = config.get('X', {})
133
+ y_config = config.get('Y', {})
134
+
135
+ if isinstance(x_config, dict):
136
+ self.X.setBaudRate(x_config.get('baudrate', 115200))
137
+ self.X.setPortName(x_config.get('port', 'COM12'))
138
+
139
+ if isinstance(y_config, dict):
140
+ self.Y.setBaudRate(y_config.get('baudrate', 115200))
141
+ self.Y.setPortName(y_config.get('port', 'COM13'))
142
+ except Exception as e:
143
+ logger.error(
144
+ f'Error loading KinesisXY config: {e}\n{traceback.format_exc()}'
145
+ )
146
+ finally:
147
+ super().load_config(config)
135
148
 
136
149
 
137
150
  if __name__ == '__main__':