flimkit 0.13.1__tar.gz → 0.13.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 (109) hide show
  1. {flimkit-0.13.1 → flimkit-0.13.2}/PKG-INFO +3 -2
  2. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/gui.py +49 -15
  3. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/_version.py +2 -1
  4. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit.egg-info/PKG-INFO +3 -2
  5. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit.egg-info/requires.txt +2 -1
  6. {flimkit-0.13.1 → flimkit-0.13.2}/pyproject.toml +2 -1
  7. {flimkit-0.13.1 → flimkit-0.13.2}/LICENSE.md +0 -0
  8. {flimkit-0.13.1 → flimkit-0.13.2}/README.md +0 -0
  9. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/FLIM/__init__.py +0 -0
  10. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/FLIM/assemble.py +0 -0
  11. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/FLIM/batch.py +0 -0
  12. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/FLIM/bg_tools.py +0 -0
  13. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/FLIM/fit_tools.py +0 -0
  14. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/FLIM/fitters.py +0 -0
  15. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/FLIM/irf_tools.py +0 -0
  16. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/FLIM/models.py +0 -0
  17. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/GPU/__init__.py +0 -0
  18. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/GPU/_base.py +0 -0
  19. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/GPU/cuda.py +0 -0
  20. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/GPU/mlx_backend.py +0 -0
  21. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/GPU/mps.py +0 -0
  22. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/GPU/rocm.py +0 -0
  23. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/GPU/torch_backend.py +0 -0
  24. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/app_state.py +0 -0
  25. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/controller.py +0 -0
  26. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/expert_settings.py +0 -0
  27. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/fit_help.py +0 -0
  28. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/fov_preview.py +0 -0
  29. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/icon.icns +0 -0
  30. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/icon.ico +0 -0
  31. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/icon.png +0 -0
  32. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/irf_widget.py +0 -0
  33. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/mode_controller.py +0 -0
  34. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/modes/__init__.py +0 -0
  35. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/modes/base.py +0 -0
  36. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/modes/batch_mode.py +0 -0
  37. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/modes/fov_mode.py +0 -0
  38. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/modes/irf_mode.py +0 -0
  39. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/modes/phasor_mode.py +0 -0
  40. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/modes/stitch_mode.py +0 -0
  41. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/phasor_panel.py +0 -0
  42. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/progress_window.py +0 -0
  43. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/project_panel.py +0 -0
  44. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/results_panel.py +0 -0
  45. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/roi_tools.py +0 -0
  46. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/UI/utils.py +0 -0
  47. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/__init__.py +0 -0
  48. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/cli.py +0 -0
  49. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/configs.py +0 -0
  50. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/dialogs.py +0 -0
  51. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/BH/__init__.py +0 -0
  52. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/BH/reader.py +0 -0
  53. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/BH/writer.py +0 -0
  54. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/ISS/__init__.py +0 -0
  55. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/ISS/fdflim.py +0 -0
  56. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/ISS/image.py +0 -0
  57. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/ISS/reader.py +0 -0
  58. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/PS/__init__.py +0 -0
  59. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/PS/reader.py +0 -0
  60. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/PTU/__init__.py +0 -0
  61. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/PTU/decode.py +0 -0
  62. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/PTU/phu.py +0 -0
  63. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/PTU/reader.py +0 -0
  64. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/PTU/series.py +0 -0
  65. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/PTU/stitch.py +0 -0
  66. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/PTU/tools.py +0 -0
  67. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/__init__.py +0 -0
  68. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/flim_file.py +0 -0
  69. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/phasor.py +0 -0
  70. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/formats/signal.py +0 -0
  71. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/image/tools.py +0 -0
  72. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/interactive.py +0 -0
  73. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/mpl_backend.py +0 -0
  74. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/phasor/__init__.py +0 -0
  75. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/phasor/filters.py +0 -0
  76. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/phasor/fret.py +0 -0
  77. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/phasor/interactive.py +0 -0
  78. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/phasor/peaks.py +0 -0
  79. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/phasor/signal.py +0 -0
  80. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/phasor_launcher.py +0 -0
  81. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/plugins/__init__.py +0 -0
  82. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/plugins/bindings.py +0 -0
  83. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/plugins/builtin/__init__.py +0 -0
  84. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/plugins/builtin/core_tools.py +0 -0
  85. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/plugins/loader.py +0 -0
  86. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/plugins/registry.py +0 -0
  87. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/project.py +0 -0
  88. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/synth.py +0 -0
  89. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/__init__.py +0 -0
  90. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/batch_fit.py +0 -0
  91. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/config_manager.py +0 -0
  92. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/config_snapshot.py +0 -0
  93. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/crash_handler.py +0 -0
  94. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/display.py +0 -0
  95. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/enhanced_outputs.py +0 -0
  96. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/fancy.py +0 -0
  97. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/lifetime_image.py +0 -0
  98. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/misc.py +0 -0
  99. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/plotting.py +0 -0
  100. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/roi.py +0 -0
  101. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/session.py +0 -0
  102. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/update_check.py +0 -0
  103. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/xlsx_tools.py +0 -0
  104. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit/utils/xml_utils.py +0 -0
  105. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit.egg-info/SOURCES.txt +0 -0
  106. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit.egg-info/dependency_links.txt +0 -0
  107. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit.egg-info/entry_points.txt +0 -0
  108. {flimkit-0.13.1 → flimkit-0.13.2}/flimkit.egg-info/top_level.txt +0 -0
  109. {flimkit-0.13.1 → flimkit-0.13.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flimkit
3
- Version: 0.13.1
3
+ Version: 0.13.2
4
4
  Summary: Fluorescence lifetime imaging analysis: reading, fitting, phasors and stitching
5
5
  Author-email: Alex Hunt <alexander.hunt@ed.ac.uk>
6
6
  License-Expression: MIT
@@ -39,8 +39,9 @@ Requires-Dist: tifffile
39
39
  Requires-Dist: tqdm==4.67.3
40
40
  Requires-Dist: xarray==2026.1.0
41
41
  Provides-Extra: gui
42
- Requires-Dist: tkinterdnd2==0.4.3; extra == "gui"
42
+ Requires-Dist: tkinterdnd2>=0.6.2; extra == "gui"
43
43
  Requires-Dist: TKinterModernThemes; extra == "gui"
44
+ Requires-Dist: sv-ttk>=2.6.1; extra == "gui"
44
45
  Provides-Extra: notebook
45
46
  Requires-Dist: ipython==9.10.0; extra == "notebook"
46
47
  Requires-Dist: ipywidgets==8.1.8; extra == "notebook"
@@ -3886,7 +3886,6 @@ if HAS_TKMT:
3886
3886
  self.root.minsize(760, 700)
3887
3887
  self._init_ui()
3888
3888
  self._run_plugin_startups()
3889
- self.run(cleanresize=False)
3890
3889
 
3891
3890
  class FLIMKitGUIFallback(_UIBuilder):
3892
3891
  def __init__(self, root):
@@ -3895,7 +3894,41 @@ class FLIMKitGUIFallback(_UIBuilder):
3895
3894
  self.root.minsize(760, 700)
3896
3895
  self._init_ui()
3897
3896
  self._run_plugin_startups()
3898
- self.root.mainloop()
3897
+
3898
+ def discard_default_root():
3899
+ root = getattr(tk, '_default_root', None)
3900
+ if root is None:
3901
+ return
3902
+ try:
3903
+ root.destroy()
3904
+ except Exception:
3905
+ pass
3906
+ tk._default_root = None
3907
+
3908
+ def plain_root():
3909
+ if HAS_DND:
3910
+ try:
3911
+ from tkinterdnd2 import Tk
3912
+ return Tk()
3913
+ except Exception as exc:
3914
+ print(f'Drag and drop is off, the tkdnd library would not load: {exc}')
3915
+ discard_default_root()
3916
+ return tk.Tk()
3917
+
3918
+ def apply_fallback_theme(root):
3919
+ try:
3920
+ import sv_ttk
3921
+ sv_ttk.set_theme('dark')
3922
+ return 'sun-valley through sv_ttk'
3923
+ except Exception:
3924
+ pass
3925
+ style = ttk.Style(root)
3926
+ names = style.theme_names()
3927
+ for theme_name in ('vista', 'aqua', 'clam', 'alt', 'default'):
3928
+ if theme_name in names:
3929
+ style.theme_use(theme_name)
3930
+ return theme_name
3931
+ return style.theme_use()
3899
3932
 
3900
3933
  def launch_gui():
3901
3934
  global GUI_MODE
@@ -3904,20 +3937,21 @@ def launch_gui():
3904
3937
  init_crash_handler()
3905
3938
  from flimkit import plugins
3906
3939
  plugins.ensure_loaded()
3940
+ themed = None
3907
3941
  if HAS_TKMT:
3908
- app = FLIMKitGUIThemed(theme='sun-valley', mode='dark')
3909
- else:
3910
- if HAS_DND:
3911
- from tkinterdnd2 import Tk
3912
- root = Tk()
3913
- else:
3914
- root = tk.Tk()
3915
- style = ttk.Style(root)
3916
- for theme_name in ('clam', 'alt', 'default'):
3917
- if theme_name in style.theme_names():
3918
- style.theme_use(theme_name)
3919
- break
3920
- app = FLIMKitGUIFallback(root)
3942
+ try:
3943
+ themed = FLIMKitGUIThemed(theme='sun-valley', mode='dark')
3944
+ except tk.TclError as exc:
3945
+ discard_default_root()
3946
+ print(f'The themed window would not start on this Tk: {exc}')
3947
+ print('Falling back. Tk 9 needs tkinterdnd2 0.6.2 or newer and sv-ttk.')
3948
+ if themed is not None:
3949
+ themed.run(cleanresize=False)
3950
+ return
3951
+ root = plain_root()
3952
+ print(f'Theme: {apply_fallback_theme(root)}')
3953
+ FLIMKitGUIFallback(root)
3954
+ root.mainloop()
3921
3955
 
3922
3956
  if __name__ == '__main__':
3923
3957
  launch_gui()
@@ -1,4 +1,4 @@
1
- __version__ = '0.13.1'
1
+ __version__ = '0.13.2'
2
2
  fitter_version = '20'
3
3
 
4
4
  roadmap = '''Flim program roadmap:
@@ -40,5 +40,6 @@ Need to add Phasor once added to the codebase, and update version to 1.0. And ad
40
40
  0.12.0 -> on PyPI, so pip install flimkit gets the analysis core without the desktop, with gui, torch, mlx, notebook, segmentation and test as extras. Plugins now load when a format is looked up, so a plugin-registered format works from a script or a CLI and not only from the GUI. Per-pixel fitting on the GPU works in pixel blocks, so a field larger than a gigabyte reaches the GPU instead of silently falling back to the CPU; a 1024 square field fits in 7.8s against 25.2s on the CPU. The per-pixel tau grid goes from 200 points to 1600, which cuts the error against known-truth synthetic data from 0.021 ns to 0.008 ns, so per-pixel lifetimes will differ slightly from earlier versions. Cancelling a tile fit is honoured through canvas assembly and saving rather than only during the fitting. Leica .xlef projects are read for tile positions.
41
41
  0.13.0 -> per-pixel fitting numbers move, so fitter_version goes to 20. Free-tau per-pixel fits carry their lifetimes in nanoseconds rather than seconds, which roughly halves the error against known truth and makes the CPU, CUDA and Metal paths agree to every digit reported. Pile-up correction was silently discarded on the free-tau path and now runs, and pile-up can instead go in the per-pixel forward model with --pileup-in-model, which leaves the data Poisson. The background can be fitted as a term in the model rather than subtracted, with --bg-in-model, off by default because the two routes are biased in opposite directions rather than one being better. Per-pixel chi-squared is computed in float32, which takes a 512 square fit from 2.02s to 1.50s and the test suite from 280s to 155s. The GPU block budget is per backend, 32 MB on CUDA and ROCm against 256 MB on MLX, worth a flat 2x on an A5000, and is clamped to half of free device memory.
42
42
  0.13.1 -> documentation fixes and two things found on a first run against QuPath on a fresh install. Stitching says how big the photon cube is, where it is going and how long the allocation took, and warns when the output drive cannot make sparse files, because exFAT writes the whole 57.2 GB before the first tile is read. flimkit[cellpose] works as well as flimkit[segmentation]. The docs name flimkit-bridge, say which QuPath pipeline writes the photon cube, document FLIMKIT_GPU_BLOCK_BYTES, and drop two claims that were no longer true: that the GPU backends cannot honour a fit window, and that free-tau per-pixel fitting uses batched Adam on the GPU. No fitted number changes, so fitter_version stays at 20.
43
+ 0.13.2 -> the desktop GUI starts on a Tk 9 interpreter. The Windows python.org build of Python 3.14 ships Tk 9.0 where the macOS build still ships 8.6, and two GUI dependencies were built for Tcl 8.6 only, so the window died before it opened with either an unloadable tkdnd library or an invalid command name set_theme, depending on what was installed. tkinterdnd2 moves to 0.6.2 or newer and sv-ttk joins the gui extra, both of which load on Tk 8.6 and Tk 9. FLIMKit also falls back to a plain window rather than dying when a theme or a Tcl package fails at run time, which it could not do before because it chose its path from whether the imports had worked and both libraries import cleanly before failing inside Tcl. No fitted number changes.
43
44
  1.0.0 -> release version with all core features implemented and tested
44
45
  1.5.0 (or 2.0) -> validation of fitting results with known fluorophores.'''
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flimkit
3
- Version: 0.13.1
3
+ Version: 0.13.2
4
4
  Summary: Fluorescence lifetime imaging analysis: reading, fitting, phasors and stitching
5
5
  Author-email: Alex Hunt <alexander.hunt@ed.ac.uk>
6
6
  License-Expression: MIT
@@ -39,8 +39,9 @@ Requires-Dist: tifffile
39
39
  Requires-Dist: tqdm==4.67.3
40
40
  Requires-Dist: xarray==2026.1.0
41
41
  Provides-Extra: gui
42
- Requires-Dist: tkinterdnd2==0.4.3; extra == "gui"
42
+ Requires-Dist: tkinterdnd2>=0.6.2; extra == "gui"
43
43
  Requires-Dist: TKinterModernThemes; extra == "gui"
44
+ Requires-Dist: sv-ttk>=2.6.1; extra == "gui"
44
45
  Provides-Extra: notebook
45
46
  Requires-Dist: ipython==9.10.0; extra == "notebook"
46
47
  Requires-Dist: ipywidgets==8.1.8; extra == "notebook"
@@ -28,8 +28,9 @@ flimkit[gui,notebook,segmentation]
28
28
  flimkit[segmentation]
29
29
 
30
30
  [gui]
31
- tkinterdnd2==0.4.3
31
+ tkinterdnd2>=0.6.2
32
32
  TKinterModernThemes
33
+ sv-ttk>=2.6.1
33
34
 
34
35
  [mlx]
35
36
  mlx
@@ -49,8 +49,9 @@ dependencies = [
49
49
 
50
50
  [project.optional-dependencies]
51
51
  gui = [
52
- 'tkinterdnd2==0.4.3',
52
+ 'tkinterdnd2>=0.6.2',
53
53
  'TKinterModernThemes',
54
+ 'sv-ttk>=2.6.1',
54
55
  ]
55
56
  notebook = [
56
57
  'ipython==9.10.0',
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes