microeye 2.3.9__tar.gz → 2.3.11__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 (203) hide show
  1. {microeye-2.3.9/src/microeye.egg-info → microeye-2.3.11}/PKG-INFO +7 -6
  2. {microeye-2.3.9 → microeye-2.3.11}/README.md +5 -5
  3. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/_version.py +1 -1
  4. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/filters/spatial.py +52 -48
  5. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/processing.py +34 -7
  6. microeye-2.3.11/src/microEye/analysis/fitting/rcc.py +183 -0
  7. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/results.py +66 -11
  8. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/viewer/localizations.py +32 -11
  9. microeye-2.3.11/src/microEye/hardware/cams/basler/basler_cam.py +413 -0
  10. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/camera_options.py +1 -1
  11. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/mieye/devices_manager.py +15 -1
  12. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/core.py +12 -9
  13. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/stabilizer.py +197 -200
  14. microeye-2.3.11/src/microEye/tools/__init__.py +0 -0
  15. {microeye-2.3.9 → microeye-2.3.11/src/microeye.egg-info}/PKG-INFO +7 -6
  16. {microeye-2.3.9 → microeye-2.3.11}/src/microeye.egg-info/SOURCES.txt +3 -0
  17. {microeye-2.3.9 → microeye-2.3.11}/src/microeye.egg-info/requires.txt +1 -0
  18. {microeye-2.3.9 → microeye-2.3.11}/LICENSE +0 -0
  19. {microeye-2.3.9 → microeye-2.3.11}/MANIFEST.in +0 -0
  20. {microeye-2.3.9 → microeye-2.3.11}/pyproject.toml +0 -0
  21. {microeye-2.3.9 → microeye-2.3.11}/setup.cfg +0 -0
  22. {microeye-2.3.9 → microeye-2.3.11}/setup.py +0 -0
  23. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/__init__.py +0 -0
  24. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/__init__.py +0 -0
  25. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/checklist_dialog.py +0 -0
  26. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/cmosMaps.py +0 -0
  27. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/filters/__init__.py +0 -0
  28. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/filters/base.py +0 -0
  29. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/filters/temporal.py +0 -0
  30. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/__init__.py +0 -0
  31. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/fit.py +0 -0
  32. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/nena.py +0 -0
  33. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/phasor_fit.py +0 -0
  34. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/__init__.py +0 -0
  35. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/extract.py +0 -0
  36. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/rubost_mean.py +0 -0
  37. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/spline.py +0 -0
  38. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/stats/__init__.py +0 -0
  39. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/stats/core.py +0 -0
  40. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/stats/curve_fit.py +0 -0
  41. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/stats/io.py +0 -0
  42. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/stats/slope_fit.py +0 -0
  43. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/temp.py +0 -0
  44. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/psf/test.py +0 -0
  45. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUfunctions.py +0 -0
  46. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUmleFit_LM.py +0 -0
  47. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/CPU/CPUsplineLib.py +0 -0
  48. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/CPU/__init__.py +0 -0
  49. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUfunctions.py +0 -0
  50. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_EMCCD.py +0 -0
  51. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUmleFit_LM_sCMOS.py +0 -0
  52. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/GPU/GPUsplineLib.py +0 -0
  53. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/GPU/__init__.py +0 -0
  54. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/__init__.py +0 -0
  55. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/constants.py +0 -0
  56. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/pyfit3Dcspline/mainfunctions.py +0 -0
  57. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/results_stats.py +0 -0
  58. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/fitting/tardis.py +0 -0
  59. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/multi_viewer.py +0 -0
  60. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/processing/__init__.py +0 -0
  61. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/processing/frc.py +0 -0
  62. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/rendering/__init__.py +0 -0
  63. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/rendering/base.py +0 -0
  64. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/rendering/cloud.py +0 -0
  65. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/rendering/core.py +0 -0
  66. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/rendering/volumetric.py +0 -0
  67. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/tools/__init__.py +0 -0
  68. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/tools/kymograms.py +0 -0
  69. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/tools/roi_selectors.py +0 -0
  70. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/utils/__init__.py +0 -0
  71. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/utils/coordinates.py +0 -0
  72. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/utils/images.py +0 -0
  73. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/utils/windows.py +0 -0
  74. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/viewer/__init__.py +0 -0
  75. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/viewer/image_options_widget.py +0 -0
  76. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/viewer/images.py +0 -0
  77. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/viewer/layers_widget.py +0 -0
  78. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/viewer/psf.py +0 -0
  79. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/analysis/viewer/volume.py +0 -0
  80. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/__init__.py +0 -0
  81. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/__init__.py +0 -0
  82. {microeye-2.3.9/src/microEye/hardware/misc → microeye-2.3.11/src/microEye/hardware/cams/basler}/__init__.py +0 -0
  83. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/camera_calibration.py +0 -0
  84. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/camera_list.py +0 -0
  85. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/camera_panel.py +0 -0
  86. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/dummy/__init__.py +0 -0
  87. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/dummy/dummy_panel.py +0 -0
  88. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/jobs.py +0 -0
  89. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/line_profiler.py +0 -0
  90. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/linescan/IR_Cam.py +0 -0
  91. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/linescan/__init__.py +0 -0
  92. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/micam.py +0 -0
  93. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/pco/__init__.py +0 -0
  94. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/pco/enums.py +0 -0
  95. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/pco/pco_cam.py +0 -0
  96. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/pco/pco_panel.py +0 -0
  97. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/shortcuts.py +0 -0
  98. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/thorlabs/__init__.py +0 -0
  99. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/thorlabs/thorlabs.py +0 -0
  100. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/thorlabs/thorlabs_panel.py +0 -0
  101. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/ueye/__init__.py +0 -0
  102. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/ueye/ueye_camera.py +0 -0
  103. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/ueye/ueye_panel.py +0 -0
  104. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/vimba/__init__.py +0 -0
  105. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/vimba/vimba_cam.py +0 -0
  106. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/cams/vimba/vimba_panel.py +0 -0
  107. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/device.py +0 -0
  108. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/lasers/__init__.py +0 -0
  109. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/lasers/io_matchbox.py +0 -0
  110. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/lasers/io_params.py +0 -0
  111. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/lasers/io_single_laser.py +0 -0
  112. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/lasers/laser_relay.py +0 -0
  113. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/mieye/__init__.py +0 -0
  114. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/mieye/acquisition_manager.py +0 -0
  115. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/mieye/miEye.py +0 -0
  116. {microeye-2.3.9/src/microEye/hardware/protocols → microeye-2.3.11/src/microEye/hardware/misc}/__init__.py +0 -0
  117. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/misc/acquisition_view.py +0 -0
  118. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/misc/reglo.py +0 -0
  119. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/misc/temp.py +0 -0
  120. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/port_config.py +0 -0
  121. {microeye-2.3.9/src/microEye/hardware/stages → microeye-2.3.11/src/microEye/hardware/protocols}/__init__.py +0 -0
  122. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/protocols/actions.py +0 -0
  123. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/protocols/actions_items.py +0 -0
  124. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/protocols/designer.py +0 -0
  125. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/protocols/scene_manager.py +0 -0
  126. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/protocols/serialization.py +0 -0
  127. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/__init__.py +0 -0
  128. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/devices.py +0 -0
  129. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/enums.py +0 -0
  130. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/headless.py +0 -0
  131. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/utils.py +0 -0
  132. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/widgets/__init__.py +0 -0
  133. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/widgets/bridges.py +0 -0
  134. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/widgets/headless_manager.py +0 -0
  135. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/widgets/headless_options.py +0 -0
  136. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/pycromanager/widgets/pycro_panel.py +0 -0
  137. {microeye-2.3.9/src/microEye/icons → microeye-2.3.11/src/microEye/hardware/stages}/__init__.py +0 -0
  138. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/__init__.py +0 -0
  139. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/baseDevice.py +0 -0
  140. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/device.py +0 -0
  141. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/deviceID.py +0 -0
  142. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/devicePort.py +0 -0
  143. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/deviceStatus.py +0 -0
  144. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/devicesView.py +0 -0
  145. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/ellDevices.py +0 -0
  146. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/messageUpdater.py +0 -0
  147. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/motorInfo.py +0 -0
  148. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/stage.py +0 -0
  149. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/elliptec/test.py +0 -0
  150. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/kinesis/__init__.py +0 -0
  151. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/kinesis/kdc101/__init__.py +0 -0
  152. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/kinesis/kdc101/enums.py +0 -0
  153. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/kinesis/kdc101/factory.py +0 -0
  154. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/kinesis/kdc101/kdc101.py +0 -0
  155. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/kinesis/kinesis.py +0 -0
  156. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/piezo_concept.py +0 -0
  157. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/stages/stage.py +0 -0
  158. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/widgets/__init__.py +0 -0
  159. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/widgets/controller.py +0 -0
  160. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/widgets/devices.py +0 -0
  161. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/widgets/focusWidget.py +0 -0
  162. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/widgets/qlist_slider.py +0 -0
  163. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/hardware/widgets/scan_acquisition.py +0 -0
  164. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/1024.png +0 -0
  165. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/128.png +0 -0
  166. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/16.png +0 -0
  167. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/24.png +0 -0
  168. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/256.png +0 -0
  169. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/32.png +0 -0
  170. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/48.png +0 -0
  171. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/512.png +0 -0
  172. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/64.png +0 -0
  173. {microeye-2.3.9/src/microEye/tools → microeye-2.3.11/src/microEye/icons}/__init__.py +0 -0
  174. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/close.svg +0 -0
  175. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/mieye.png +0 -0
  176. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/min.svg +0 -0
  177. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/icons/viewer.png +0 -0
  178. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/launcher.py +0 -0
  179. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/qt.py +0 -0
  180. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/tools/microscopy.py +0 -0
  181. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/__init__.py +0 -0
  182. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/display.py +0 -0
  183. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/enum_encoder.py +0 -0
  184. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/expandable_groupbox.py +0 -0
  185. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/gui_helper.py +0 -0
  186. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/hid_utils/__init__.py +0 -0
  187. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/hid_utils/controller.py +0 -0
  188. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/hid_utils/device.py +0 -0
  189. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/hid_utils/enums.py +0 -0
  190. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/hid_utils/utils.py +0 -0
  191. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/labelled_slider.py +0 -0
  192. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/metadata.py +0 -0
  193. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/metadata_tree.py +0 -0
  194. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/micro_launcher.py +0 -0
  195. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/parameter_tree.py +0 -0
  196. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/pyscripting.py +0 -0
  197. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/retry_exec.py +0 -0
  198. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/start_gui.py +0 -0
  199. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/thread_worker.py +0 -0
  200. {microeye-2.3.9 → microeye-2.3.11}/src/microEye/utils/uImage.py +0 -0
  201. {microeye-2.3.9 → microeye-2.3.11}/src/microeye.egg-info/dependency_links.txt +0 -0
  202. {microeye-2.3.9 → microeye-2.3.11}/src/microeye.egg-info/entry_points.txt +0 -0
  203. {microeye-2.3.9 → microeye-2.3.11}/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.3.9
3
+ Version: 2.3.11
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
@@ -32,6 +32,7 @@ Requires-Dist: pyfiglet==1.0.2
32
32
  Requires-Dist: pyflakes==3.2.0
33
33
  Requires-Dist: pyjokes==0.6.0
34
34
  Requires-Dist: PyOpenGL==3.1.7
35
+ Requires-Dist: pypylon==4.2.0
35
36
  Requires-Dist: pyqtdarktheme==2.1.0
36
37
  Requires-Dist: pyqtgraph==0.13.7
37
38
  Requires-Dist: pyserial==3.5
@@ -71,11 +72,11 @@ The **`microEye`** is a Python toolkit for fluorescence microscopy that supports
71
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).
72
73
 
73
74
  ```bash
74
- __ __ _ ___ ___ ____ ___
75
- | \/ (_)__ _ _ ___| __| _ ___ __ _|_ ) |__ // _ \
76
- | |\/| | / _| '_/ _ \ _| || / -_) \ V // / _ |_ \\_, /
77
- |_| |_|_\__|_| \___/___\_, \___| \_//___(_)___(_)_/
78
- |__/
75
+ __ ____ ____ ___ ____ ______
76
+ / |/ (_)__________ / __/_ _____ _ __|_ | |_ / < < /
77
+ / /|_/ / / __/ __/ _ \/ _// // / -_) | |/ / __/_ _/_ <_ / // /
78
+ /_/ /_/_/\__/_/ \___/___/\_, /\__/ |___/____(_)____(_)_//_/
79
+ /___/
79
80
  ```
80
81
 
81
82
  ![Package Health](https://snyk.io/advisor/python/microEye/badge.svg)
@@ -7,11 +7,11 @@ 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
- | |\/| | / _| '_/ _ \ _| || / -_) \ V // / _ |_ \\_, /
13
- |_| |_|_\__|_| \___/___\_, \___| \_//___(_)___(_)_/
14
- |__/
10
+ __ ____ ____ ___ ____ ______
11
+ / |/ (_)__________ / __/_ _____ _ __|_ | |_ / < < /
12
+ / /|_/ / / __/ __/ _ \/ _// // / -_) | |/ / __/_ _/_ <_ / // /
13
+ /_/ /_/_/\__/_/ \___/___/\_, /\__/ |___/____(_)____(_)_//_/
14
+ /___/
15
15
  ```
16
16
 
17
17
  ![Package Health](https://snyk.io/advisor/python/microEye/badge.svg)
@@ -1,2 +1,2 @@
1
- version_info = (2, 3, 9)
1
+ version_info = (2, 3, 11)
2
2
  __version__ = '.'.join(map(str, version_info))
@@ -117,54 +117,58 @@ class DoG_Filter(SpatialFilter):
117
117
  }
118
118
 
119
119
 
120
- # class GaussFilter(SpatialFilter):
121
- # def __init__(self, sigma=1) -> None:
122
- # '''Gaussian filter initialization.'''
123
- # params = {'sigma': sigma}
124
- # super().__init__(name='Gaussian Filter', parameters=params)
125
- # self.set_params(sigma)
126
-
127
- # def set_params(self, sigma):
128
- # '''Set the sigma parameter for the Gaussian filter.'''
129
- # self._show_filter = False
130
- # self.parameters['sigma'] = sigma
131
- # self.gauss = GaussFilter.gaussian_kernel(
132
- # max(3, math.ceil(3 * sigma + 1)), sigma
133
- # )
134
-
135
- # def gaussian_kernel(dim, sigma):
136
- # x = cv2.getGaussianKernel(dim, sigma)
137
- # kernel = x.dot(x.T)
138
- # return kernel
139
-
140
- # def run(self, image: np.ndarray) -> np.ndarray:
141
- # return cv2.normalize(
142
- # signal.convolve2d(image, np.rot90(self.gauss), mode='same'),
143
- # None,
144
- # 0,
145
- # 255,
146
- # cv2.NORM_MINMAX,
147
- # cv2.CV_8U,
148
- # )
149
-
150
- # def get_tree_parameters(self):
151
- # '''Return the parameters for the pyqtgraph tree view.'''
152
- # return {
153
- # 'name': self.name,
154
- # 'type': 'group',
155
- # 'visible': False,
156
- # 'children': [
157
- # {
158
- # 'name': 'Sigma',
159
- # 'type': 'float',
160
- # 'value': self.parameters['sigma'],
161
- # 'limits': [0.0, 100.0],
162
- # 'step': 0.1,
163
- # 'decimals': 2,
164
- # 'tip': 'Standard deviation (\u03c3) for the filter',
165
- # },
166
- # ],
167
- # }
120
+ class PointGaussFilter(SpatialFilter):
121
+ def __init__(self, sigma=1) -> None:
122
+ '''Gaussian filter initialization.'''
123
+ params = {'sigma': sigma}
124
+ super().__init__(name='Point Gaussian Filter', parameters=params)
125
+ self.set_params(sigma)
126
+
127
+ self.point_kernel = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]])
128
+
129
+ def set_params(self, sigma):
130
+ '''Set the sigma parameter for the Gaussian filter.'''
131
+ self._show_filter = False
132
+ self.parameters['sigma'] = sigma
133
+ self.gauss = PointGaussFilter.gaussian_kernel(
134
+ max(3, math.ceil(3 * sigma + 1)), sigma
135
+ )
136
+
137
+ def gaussian_kernel(dim, sigma):
138
+ x = cv2.getGaussianKernel(dim, sigma)
139
+ kernel = x.dot(x.T)
140
+ return kernel
141
+
142
+ def run(self, image: np.ndarray) -> np.ndarray:
143
+ point = signal.fftconvolve(image, np.rot90(self.point_kernel), mode='same')
144
+
145
+ return cv2.normalize(
146
+ signal.fftconvolve(point, np.rot90(self.gauss), mode='same'),
147
+ None,
148
+ 0,
149
+ 255,
150
+ cv2.NORM_MINMAX,
151
+ cv2.CV_8U,
152
+ )
153
+
154
+ def get_tree_parameters(self):
155
+ '''Return the parameters for the pyqtgraph tree view.'''
156
+ return {
157
+ 'name': self.name,
158
+ 'type': 'group',
159
+ 'visible': False,
160
+ 'children': [
161
+ {
162
+ 'name': 'Sigma',
163
+ 'type': 'float',
164
+ 'value': self.parameters['sigma'],
165
+ 'limits': [0.0, 100.0],
166
+ 'step': 0.1,
167
+ 'decimals': 2,
168
+ 'tip': 'Standard deviation (\u03c3) for the filter',
169
+ },
170
+ ],
171
+ }
168
172
 
169
173
 
170
174
  class FourierFilter(SpatialFilter):
@@ -249,7 +249,14 @@ def shift_correction(interpx, interpy, frame_bins, datax, datay):
249
249
  datay[mask] -= shift_y
250
250
 
251
251
 
252
- def plot_drift(frames_new, interpx, interpy, title='Drift Cross-Correlation'):
252
+ def plot_drift(
253
+ frames_new,
254
+ interpx,
255
+ interpy,
256
+ error_x=None,
257
+ error_y=None,
258
+ title='Drift Cross-Correlation',
259
+ ):
253
260
  print('Shift Plot ...', end='\r')
254
261
 
255
262
  # plot results
@@ -272,8 +279,29 @@ def plot_drift(frames_new, interpx, interpy, title='Drift Cross-Correlation'):
272
279
  # setting vertical range
273
280
  # plt.setYRange(0, 1)
274
281
 
275
- plt.plot(frames_new, interpx, pen='r', symbol=None, symbolBrush=0.2, name='x-drift')
276
- plt.plot(frames_new, interpy, pen='y', symbol=None, symbolBrush=0.2, name='y-drift')
282
+ # Plot x-drift with error bars
283
+ if error_x is not None:
284
+ err_x = pg.ErrorBarItem(
285
+ x=frames_new, y=interpx, top=error_x, bottom=error_x, beam=0.5,
286
+ pen=pg.mkPen(color=(255, 0, 0, 24)) # red color with transparency
287
+ )
288
+ plt.addItem(err_x)
289
+
290
+ # Plot y-drift with error bars
291
+ if error_y is not None:
292
+ err_y = pg.ErrorBarItem(
293
+ x=frames_new, y=interpy, top=error_y, bottom=error_y, beam=0.5,
294
+ pen=pg.mkPen(color=(255, 255, 0, 24)) # yellow color with transparency
295
+ )
296
+ plt.addItem(err_y)
297
+
298
+ # Plot x and y drift curves
299
+ x_curve = plt.plot(
300
+ frames_new, interpx, pen='r', symbol=None, symbolBrush=0.2, name='x-drift'
301
+ )
302
+ y_curve = plt.plot(
303
+ frames_new, interpy, pen='y', symbol=None, symbolBrush=0.2, name='y-drift'
304
+ )
277
305
 
278
306
  print('Done ...', end='\r')
279
307
 
@@ -285,10 +313,9 @@ def plot_animation_stats(
285
313
 
286
314
  # Calculate bin edges from centers
287
315
  bin_width = frame_bin_centers[1] - frame_bin_centers[0]
288
- bin_edges = np.concatenate([
289
- frame_bin_centers - bin_width/2,
290
- [frame_bin_centers[-1] + bin_width/2]
291
- ])
316
+ bin_edges = np.concatenate(
317
+ [frame_bin_centers - bin_width / 2, [frame_bin_centers[-1] + bin_width / 2]]
318
+ )
292
319
 
293
320
  # plot results
294
321
  plt = pg.plot()
@@ -0,0 +1,183 @@
1
+ import cv2
2
+ import numba as nb
3
+ import numpy as np
4
+
5
+ from microEye.analysis.fitting.pyfit3Dcspline.CPU.CPUmleFit_LM import (
6
+ kernel_MLEFit_LM_Sigma,
7
+ )
8
+
9
+
10
+ def cross_correlation(image1, image2):
11
+ """
12
+ Compute the cross-correlation of two images using FFT.
13
+ Equivalent to MATLAB's CrossCorrelation function.
14
+ """
15
+ f1 = np.fft.fft2(image1)
16
+ f2 = np.fft.fft2(image2)
17
+ corr = np.fft.fftshift(np.real(np.fft.ifft2(f1 * np.conj(f2))))
18
+ return corr
19
+
20
+
21
+ @nb.njit
22
+ def _process_single_image(image, reference, pixelSize, box):
23
+ with nb.objmode(result='float32[:]'):
24
+ xcorr = cross_correlation(image, reference)
25
+ y_max_, x_max_ = np.unravel_index(xcorr.argmax(), xcorr.shape)
26
+
27
+ halfBoxSize = int(box / 2)
28
+
29
+ xcorr = xcorr[
30
+ y_max_ - halfBoxSize : y_max_ + halfBoxSize + 1,
31
+ x_max_ - halfBoxSize : x_max_ + halfBoxSize + 1,
32
+ ]
33
+
34
+ result, crb, ll = kernel_MLEFit_LM_Sigma(
35
+ xcorr.flatten().astype(np.float32), 1.0, int(box + 1), 60, None
36
+ )
37
+
38
+ result[0] += x_max_ - halfBoxSize
39
+ result[1] += y_max_ - halfBoxSize
40
+
41
+ shift = result[0:2] * pixelSize
42
+
43
+ return shift
44
+
45
+
46
+ @nb.njit(parallel=True, cache=True)
47
+ def rcc_shift_estimation(sub_images, pixelSize, box=12):
48
+ n_bins = sub_images.shape[0]
49
+ total_pairs = n_bins * (n_bins - 1) // 2
50
+
51
+ # Pre-compute all (i,j) pairs and their corresponding linear indices
52
+ pairs = []
53
+ for i in range(n_bins - 1):
54
+ for j in range(i + 1, n_bins):
55
+ pairs.append((i, j))
56
+
57
+ imshift = np.zeros((total_pairs, 2), dtype=np.float32)
58
+ A = np.zeros((total_pairs, n_bins - 1), dtype=np.float32)
59
+
60
+ # Process reference image once
61
+ origins = {}
62
+ for i in nb.prange(n_bins - 1):
63
+ yorigin, xorigin = _process_single_image(
64
+ sub_images[i], sub_images[i], pixelSize, box
65
+ )
66
+ origins[i] = (yorigin, xorigin)
67
+
68
+ # Process all pairs
69
+ for idx in nb.prange(len(pairs)):
70
+ i, j = pairs[idx]
71
+ y, x = _process_single_image(sub_images[i], sub_images[j], pixelSize, box)
72
+ yorigin, xorigin = origins[i]
73
+ imshift[idx, 0] = xorigin - x
74
+ imshift[idx, 1] = yorigin - y
75
+ A[idx, i:j] = 1
76
+
77
+ return imshift, A
78
+
79
+
80
+ def rcc_solve(imshift, A, n_bins, rmax=10.0):
81
+ # imshift: (N, 2) or (N, 3)
82
+ # A: (N, n_bins-1)
83
+ # use_z: if True, expects imshift.shape[1] == 3
84
+
85
+ # Initial solve
86
+ drift = np.matmul(np.linalg.pinv(A), imshift)
87
+ error = np.matmul(A, drift) - imshift
88
+
89
+ # Compute error magnitude
90
+ rowerr = np.zeros((A.shape[0], 2))
91
+ if error.shape[1] == 3:
92
+ rowerr[:, 0] = np.sqrt(error[:, 0] ** 2 + error[:, 1] ** 2 + error[:, 2] ** 2)
93
+ else:
94
+ rowerr[:, 0] = np.sqrt(error[:, 0] ** 2 + error[:, 1] ** 2)
95
+ rowerr[:, 1] = np.arange(A.shape[0])
96
+
97
+ # Sort by error (descending)
98
+ rowerr = np.flipud(np.sort(rowerr, axis=0))
99
+
100
+ # Outlier rejection
101
+ mask = rowerr[:, 0] > rmax
102
+ index = rowerr[mask, 1].astype(np.int64)
103
+
104
+ # Remove outliers (one by one, check rank)
105
+ for idx in range(len(index)):
106
+ flag = int(index[idx])
107
+ tmp = np.delete(A, flag, axis=0)
108
+ if np.linalg.matrix_rank(tmp, tol=1) == (n_bins - 1):
109
+ A = np.delete(A, flag, axis=0)
110
+ imshift = np.delete(imshift, flag, axis=0)
111
+ index[index > flag] -= 1
112
+
113
+ # Final solve and cumulative sum
114
+ return np.cumsum(np.matmul(np.linalg.pinv(A), imshift), axis=0)
115
+
116
+
117
+ @nb.njit(parallel=True, cache=True)
118
+ def dcc_shift_estimation(sub_images, pixelSize, box=12):
119
+ n_bins = sub_images.shape[0]
120
+
121
+ imshift = np.zeros((n_bins - 1, 2), dtype=np.float32)
122
+
123
+ yorigin, xorigin = _process_single_image(
124
+ sub_images[0], sub_images[0], pixelSize, box
125
+ )
126
+ # Process
127
+ for i in range(1, n_bins):
128
+ y, x = _process_single_image(sub_images[0], sub_images[i], pixelSize, box)
129
+ imshift[i - 1, 0] = xorigin - x
130
+ imshift[i - 1, 1] = yorigin - y
131
+
132
+ return imshift
133
+
134
+ @nb.njit(parallel=True, cache=True)
135
+ def mcc_shift_estimation(sub_images, pixelSize, box=12):
136
+ n_bins = sub_images.shape[0]
137
+ total_pairs = n_bins * (n_bins - 1) // 2
138
+
139
+ # Pre-compute all (i,j) pairs and their corresponding linear indices
140
+ pairs = []
141
+ for i in range(n_bins - 1):
142
+ for j in range(i + 1, n_bins):
143
+ pairs.append((i, j))
144
+
145
+ imshift = np.zeros((total_pairs, 2), dtype=np.float32)
146
+ drift = np.zeros((n_bins, 2), dtype=np.float32)
147
+
148
+ # Process reference image once
149
+ origins = {}
150
+ for i in nb.prange(n_bins - 1):
151
+ yorigin, xorigin = _process_single_image(
152
+ sub_images[i], sub_images[i], pixelSize, box
153
+ )
154
+ origins[i] = (yorigin, xorigin)
155
+
156
+ # Process all pairs
157
+ for idx in nb.prange(len(pairs)):
158
+ i, j = pairs[idx]
159
+ y, x = _process_single_image(sub_images[i], sub_images[j], pixelSize, box)
160
+ yorigin, xorigin = origins[i]
161
+ imshift[idx, 0] = xorigin - x
162
+ imshift[idx, 1] = yorigin - y
163
+
164
+ # For each bin, sum the shifts as per MCC
165
+ for i in nb.prange(n_bins):
166
+ # Subtract shifts to later bins
167
+ for j in range(i + 1, n_bins):
168
+ idx = (i * (2 * n_bins - i - 1)) // 2 + (j - i - 1)
169
+ drift[i, 0] -= imshift[idx, 0]
170
+ drift[i, 1] -= imshift[idx, 1]
171
+ # Add shifts from earlier bins
172
+ for j in range(i):
173
+ idx = (j * (2 * n_bins - j - 1)) // 2 + (i - j - 1)
174
+ drift[i, 0] += imshift[idx, 0]
175
+ drift[i, 1] += imshift[idx, 1]
176
+
177
+
178
+ drift /= n_bins
179
+
180
+ drift[:, 0] -= drift[0, 0]
181
+ drift[:, 1] -= drift[0, 1]
182
+
183
+ return drift
@@ -6,6 +6,12 @@ from numpy.core._exceptions import _ArrayMemoryError
6
6
  from scipy.interpolate import interp1d
7
7
 
8
8
  from microEye.analysis.fitting.processing import *
9
+ from microEye.analysis.fitting.rcc import (
10
+ dcc_shift_estimation,
11
+ mcc_shift_estimation,
12
+ rcc_shift_estimation,
13
+ rcc_solve,
14
+ )
9
15
  from microEye.analysis.rendering import BaseRenderer, Projection, RenderModes
10
16
 
11
17
  UNIQUE_COLUMNS = [
@@ -584,10 +590,16 @@ class FittingResults:
584
590
  sub_images.append(image)
585
591
  print(f'Bins: {f + 1:d}/{n_bins:d}', end='\r')
586
592
 
587
- return np.array(sub_images), np.array(frames), np.array(locs_per_bin),
593
+ return (
594
+ np.array(sub_images),
595
+ np.array(frames),
596
+ np.array(locs_per_bin),
597
+ )
588
598
 
589
- def drift_cross_correlation(self, n_bins=10, pixelSize=10, upsampling=100):
590
- '''Corrects the XY drift using cross-correlation measurments
599
+ def drift_cross_correlation(
600
+ self, n_bins=10, pixelSize=10, upsampling=100, rmax=20, method='phase'
601
+ ):
602
+ """Corrects the XY drift using cross-correlation measurments
591
603
 
592
604
  Parameters
593
605
  ----------
@@ -598,12 +610,31 @@ class FittingResults:
598
610
  upsampling : int, optional
599
611
  phase_cross_correlation upsampling (check skimage.registration),
600
612
  by default 100
613
+ rmax : int, optional
614
+ Maximum error for redundant cross-correlation, by default 20, should be
615
+ 0.2 of projected pixel size.
616
+ method : str, optional
617
+ Drift estimation method, by default 'phase'
618
+ Options: 'rcc', 'mcc', 'dcc', 'phase'
619
+
620
+ - 'rcc' - redundant cross-correlation [1]
621
+ - 'mcc' - mean cross-correlation [1]
622
+ - 'dcc' - drift cross-correlation [1]
623
+ - 'phase' - phase cross-correlation
601
624
 
602
625
  Returns
603
626
  -------
604
627
  tuple(FittingResults, np.ndarray)
605
628
  returns the drift corrected fittingResults and recontructed image
606
- '''
629
+
630
+
631
+ References
632
+ ----------
633
+ [1] Yina Wang, Joerg Schnitzbauer, Zhe Hu, Xueming Li, Yifan Cheng,
634
+ Zhen-Li Huang, and Bo Huang, "Localization events-based sample
635
+ drift correction for localization microscopy with redundant
636
+ cross-correlation algorithm," Opt. Express 22, 15982-15991 (2014)
637
+ """
607
638
  unique_frames = np.unique(self.data[DataColumns.FRAME])
608
639
  if len(unique_frames) < 2:
609
640
  print('Drift cross-correlation failed: no frame info.')
@@ -625,9 +656,7 @@ class FittingResults:
625
656
  )
626
657
  max_frame = np.max(self.data[DataColumns.FRAME])
627
658
 
628
- # grouped_data = []
629
659
  sub_images = []
630
- shifts = []
631
660
  frames = []
632
661
 
633
662
  for f in range(0, n_bins):
@@ -647,23 +676,46 @@ class FittingResults:
647
676
  sub_images.append(image)
648
677
  print(f'Bins: {f + 1:d}/{n_bins:d}', end='\r')
649
678
 
679
+ sub_images = np.array(sub_images)
680
+
650
681
  print('Shift Estimation ...', end='\r')
651
682
  try:
652
- shifts = shift_estimation(np.array(sub_images), pixelSize, upsampling)
683
+ if method == 'rcc':
684
+ imshift, A = rcc_shift_estimation(sub_images, pixelSize)
685
+
686
+ print('Shift Optimization ...', end='\r')
687
+ drift = rcc_solve(imshift, A, n_bins, rmax=rmax)
688
+ elif method == 'mcc':
689
+ drift = mcc_shift_estimation(sub_images, pixelSize)
690
+ elif method == 'dcc':
691
+ drift = dcc_shift_estimation(sub_images, pixelSize)
692
+ elif method == 'phase':
693
+ drift = shift_estimation(np.array(sub_images), pixelSize, upsampling)
694
+ else:
695
+ raise ValueError(f'Unknown drift estimation method: {method}')
653
696
  except _ArrayMemoryError as e:
654
697
  print(f'Drift cross-correlation failed: {e}')
655
698
  return
656
699
 
657
- shifts = np.c_[shifts, np.array(frames)]
658
700
  print('Shift Correction ...', end='\r')
659
701
 
702
+ frames_interp = np.concatenate(([0], np.array(frames), [max_frame - 1]))
703
+
704
+ # Prepare drift arrays with padding zeros at start and last value at end
705
+ base = [
706
+ 0,
707
+ ] * (1 if method in ['mcc', 'phase'] else 2)
708
+
709
+ drift_x = np.concatenate((base, drift[:, 0], [drift[-1, 0]]))
710
+ drift_y = np.concatenate((base, drift[:, 1], [drift[-1, 1]]))
711
+
660
712
  # An one-dimensional interpolation is applied
661
713
  # to drift traces in X and Y dimensions separately.
662
714
  interpy = interp1d(
663
- shifts[:, -1], shifts[:, 0], kind='quadratic', fill_value='extrapolate'
715
+ frames_interp, drift_x, kind='cubic', fill_value='extrapolate'
664
716
  )
665
717
  interpx = interp1d(
666
- shifts[:, -1], shifts[:, 1], kind='quadratic', fill_value='extrapolate'
718
+ frames_interp, drift_y, kind='cubic', fill_value='extrapolate'
667
719
  )
668
720
  # And this interpolation is used to get the shift at every frame-point
669
721
  frames_new = np.arange(0, max_frame, 1)
@@ -848,6 +900,9 @@ class FittingResults:
848
900
  drift_x = np.mean(fiducial_markers[:, :, 0], axis=0)
849
901
  drift_y = np.mean(fiducial_markers[:, :, 1], axis=0)
850
902
 
903
+ error_bar_x = np.std(fiducial_markers[:, :, 0], axis=0)
904
+ error_bar_y = np.std(fiducial_markers[:, :, 1], axis=0)
905
+
851
906
  print('Drift correction ... ', end='\r')
852
907
  ids = np.cumsum(np.bincount(self.data[DataColumns.FRAME].astype(np.int64)))
853
908
 
@@ -863,7 +918,7 @@ class FittingResults:
863
918
 
864
919
  # drift_corrected = FittingResults.fromDataFrame(df, self.pixelSize)
865
920
 
866
- return self, (unique_frames, drift_x, drift_y)
921
+ return self, (unique_frames, drift_x, drift_y, error_bar_x, error_bar_y)
867
922
 
868
923
  def zero_coordinates(self):
869
924
  # Use vectorized operations with optional masking
@@ -488,10 +488,11 @@ class LocalizationsView(QtWidgets.QWidget):
488
488
  def work_func(**kwargs):
489
489
  try:
490
490
  return self.currentResults.toAnimation(
491
- self.frame_bins.value(), self.xy_binsize.value(),
491
+ self.frame_bins.value(),
492
+ self.xy_binsize.value(),
492
493
  z_pixel_size=self.z_binsize.value(),
493
494
  projection=Projection(self.projection_cbox.currentData()),
494
- renderMode=RenderModes(self.render_cbox.currentData())
495
+ renderMode=RenderModes(self.render_cbox.currentData()),
495
496
  )
496
497
  except Exception:
497
498
  traceback.print_exc()
@@ -668,16 +669,24 @@ class LocalizationsView(QtWidgets.QWidget):
668
669
  self.drift_cross_up = create_spin_box(
669
670
  min_value=0, max_value=1000, initial_value=100
670
671
  )
672
+ self.drift_rmax = create_spin_box(min_value=0, max_value=1000, initial_value=23)
671
673
 
672
674
  self.drift_cross_args.addWidget(self.drift_cross_bins)
673
675
  self.drift_cross_args.addWidget(self.drift_cross_px)
674
676
  self.drift_cross_args.addWidget(self.drift_cross_up)
677
+ self.drift_cross_args.addWidget(self.drift_rmax)
678
+
679
+ self.cross_method_cbox = QtWidgets.QComboBox()
680
+ self.cross_method_cbox.addItem('Phase', 'phase')
681
+ self.cross_method_cbox.addItem('Direct', 'dcc')
682
+ self.cross_method_cbox.addItem('Mean', 'mcc')
683
+ self.cross_method_cbox.addItem('Redundant', 'rcc')
675
684
 
676
685
  self.drift_cross_btn = QtWidgets.QPushButton(
677
- 'Drift cross-correlation', clicked=lambda: self.drift_cross()
686
+ 'Drift X-Corr', clicked=lambda: self.drift_cross()
678
687
  )
679
688
  self.drift_fdm_btn = QtWidgets.QPushButton(
680
- 'Fiducial marker drift correction', clicked=lambda: self.drift_fdm()
689
+ 'Fiducial markers', clicked=lambda: self.drift_fdm()
681
690
  )
682
691
 
683
692
  # Drift GroupBox
@@ -685,9 +694,15 @@ class LocalizationsView(QtWidgets.QWidget):
685
694
  fdrift = QtWidgets.QFormLayout()
686
695
  drift.setLayout(fdrift)
687
696
 
688
- fdrift.addRow(QtWidgets.QLabel('Drift X-Corr. (bins, pixelSize, upsampling):'))
697
+ fdrift.addRow(
698
+ QtWidgets.QLabel('Drift X-Corr. (bins, pixelSize, upsampling, rmax):')
699
+ )
689
700
  fdrift.addRow(self.drift_cross_args)
690
- fdrift.addRow(create_hbox_layout(self.drift_cross_btn, self.drift_fdm_btn))
701
+ fdrift.addRow(
702
+ create_hbox_layout(
703
+ self.cross_method_cbox, self.drift_cross_btn, self.drift_fdm_btn
704
+ )
705
+ )
691
706
  # End Drift GroupBox
692
707
 
693
708
  self.frc_cbox = QtWidgets.QComboBox()
@@ -961,9 +976,7 @@ class LocalizationsView(QtWidgets.QWidget):
961
976
  self.currentResults.locY,
962
977
  self.currentResults.locZ,
963
978
  )
964
- self.tardis.startWorker.connect(
965
- lambda worker: self._threadpool.start(worker)
966
- )
979
+ self.tardis.startWorker.connect(lambda worker: self._threadpool.start(worker))
967
980
  self.tardis.show()
968
981
 
969
982
  def drift_cross(self):
@@ -974,12 +987,17 @@ class LocalizationsView(QtWidgets.QWidget):
974
987
  if len(self.currentResults) <= 0:
975
988
  return
976
989
 
990
+ method = self.cross_method_cbox.currentData()
991
+ label = self.cross_method_cbox.currentText()
992
+
977
993
  def work_func(**kwargs):
978
994
  try:
979
995
  return self.currentResults.drift_cross_correlation(
980
996
  self.drift_cross_bins.value(),
981
997
  self.drift_cross_px.value(),
982
998
  self.drift_cross_up.value(),
999
+ self.drift_rmax.value(),
1000
+ method=method,
983
1001
  )
984
1002
  except Exception:
985
1003
  traceback.print_exc()
@@ -991,7 +1009,10 @@ class LocalizationsView(QtWidgets.QWidget):
991
1009
  self.render_loc()
992
1010
  self.currentResults = results[0]
993
1011
  self.results_plot.setData(self.currentResults.dataFrame())
994
- plot_drift(*results[2])
1012
+ plot_drift(
1013
+ *results[2],
1014
+ title=f'{label} Cross-Correlation',
1015
+ )
995
1016
 
996
1017
  self.worker = QThreadWorker(work_func)
997
1018
  self.worker.signals.result.connect(done)
@@ -1019,7 +1040,7 @@ class LocalizationsView(QtWidgets.QWidget):
1019
1040
  if results is not None:
1020
1041
  self.currentResults = results[0]
1021
1042
  self.results_plot.setData(self.currentResults.dataFrame())
1022
- plot_drift(*results[1])
1043
+ plot_drift(*results[1], title='Fiducial Marker Drift Correction')
1023
1044
  self.render_loc()
1024
1045
 
1025
1046
  self.worker = QThreadWorker(work_func)