Skip to content

Commit d0d2a6a

Browse files
PiMaVcursoragent
andcommitted
1.5.1: win and ubuntu build, minor bugfixes, code restructuring
Co-authored-by: Cursor <[email protected]>
1 parent 853a8f6 commit d0d2a6a

16 files changed

Lines changed: 59 additions & 46 deletions

File tree

.dockerignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,4 @@ tests/
2020
scripts/
2121
TODO.md
2222
profile_load.prof
23-
pyinstaller_command.md
2423
resources/public/

.github/workflows/build.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ jobs:
7676
steps:
7777
- uses: actions/checkout@v4
7878

79+
- name: Install system dependencies
80+
shell: bash
81+
run: |
82+
sudo apt-get update
83+
sudo apt-get install -y libgl1-mesa-glx libxcb-cursor0
84+
7985
- name: Set up Python
8086
uses: actions/setup-python@v5
8187
with:
@@ -162,10 +168,10 @@ jobs:
162168
git tag "$tag" "${{ github.sha }}"
163169
git push origin "$tag"
164170
165-
- name: Publish Release (tag created automatically on this commit)
171+
- name: Publish Release
166172
uses: softprops/action-gh-release@v2
167173
with:
168-
tag_name: ${{ needs.windows.outputs.tag }}
174+
tag_name: ${{ github.event_name == 'workflow_dispatch' && needs.windows.outputs.tag || github.ref_name }}
169175
name: BLITZ ${{ needs.windows.outputs.version }}
170176
target_commitish: ${{ github.sha }}
171177
files: |

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ __pycache__/
88

99
# BLITZ related stuff:
1010
_cache.ini
11-
# QSettings atomic-write temp files (leftover if app was killed during save)
11+
# QSettings and user config (created at CWD when app runs)
12+
settings.blitz
1213
settings.blitz.*
1314
boot_bench_results.json
1415
boot_bench_results/

TODO.md

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,7 @@
22

33
## Known Issues (Bugs)
44

5-
* **Timeline / Aggregation:**
6-
* Transition between Aggregate and Frame mode is not intuitive. Consider separate timelines?
7-
* "Running Mean" has issues.
8-
* Aggregate function is deactivated when starting a grayscale web stream (32 frames). Ops tab allows opening Aggregate, but Range is not initially FULL.
9-
* Switching from Aggregate to Frame mode causes an error in some cases.
10-
* **Live View:**
11-
* Background Subtraction in Live Stream causes error messages.
12-
* RAM usage warning needed in Buffer Dialog.
13-
* Display FPS is currently fixed at 10 FPS; should be configurable.
5+
- ...
146

157
## High Priority Features
168

@@ -20,17 +12,16 @@
2012

2113
## Medium Priority
2214

23-
* **Dual-Build Setup:** Ability to build Standard and Full EXE.
24-
* **CSV Converter:** Dialog with Preview, Column Selection -> .npy export.
25-
* **Tests:** Expand tests for `ReduceDict` edge cases.
15+
* **Dual-Build Setup:** Ability to build Standard and Full EXE (= Exotic Data flavours).
16+
* **Proper Exporter:** Dialog with Options to export as *.npy or image for Raw / Pipeline / PCA data
2617
* **RoSEE:** Check Isolines and normalization (Autozoom should activate).
2718
* **Mouse Wheel Zoom:** Allow zooming only on one axis (in extraction plots?).
2819
* **Docker:** Verify Docker deployment.
20+
* **Ubuntu:** Verify Ubuntu deployment.
2921

30-
## Low Priority / Long Term
22+
## Low Priority / Long Term / Discussion
3123

32-
* **Video Optimization:** Strategy for handling compressed video data vs. full float32 matrices (mmap, Chunked, Range-Load). See `docs/OPTIMIZATION.md`.
33-
* **Project Files:** Restore Load/Save project file functionality (currently removed). See `docs/MISSING_FEATURES.md`.
24+
* **Project Files:** Restore Load/Save project file functionality in a different way than before?. See `docs/MISSING_FEATURES.md`.
3425

3526
## Notes on "Missing" Features
3627

benchmarks/bench_numba_full.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,9 @@ def _print_results(times_numba, times_numpy):
200200

201201
def main() -> None:
202202
# Use larger dimensions for more realistic benchmark
203-
run_benchmark(T=200, H=512, W=512, C=1)
203+
run_benchmark(T=200, H=512, W=512, C=1) # 200MB
204+
# run_benchmark(T=300, H=800, W=600, C=1) # 580MB
205+
# run_benchmark(T=500, H=1200, W=900, C=1) # 2.2GB
204206

205207

206208
if __name__ == "__main__":

blitz/layout/dialogs.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,20 +1310,21 @@ def _start(self, HandlerClass) -> None:
13101310
self._set_stream_controls_enabled(False)
13111311

13121312
def _stop(self) -> None:
1313-
if self._handler is None:
1313+
handler = self._handler
1314+
self._handler = None # clear immediately to avoid re-entrancy (e.g. closeEvent)
1315+
if handler is None:
13141316
return
1315-
self._handler.stop()
1316-
if not self._handler.wait_stopped(4000):
1317+
handler.stop()
1318+
if not handler.wait_stopped(4000):
13171319
from ..tools import log
13181320
log("[CAM] Timeout beim Stoppen", color="orange")
13191321
try:
13201322
if self._on_frame:
1321-
self._handler.frame_ready.disconnect(self._on_frame)
1322-
self._handler.buffer_status.disconnect(self._on_buffer_status)
1323-
self._handler.buffer_time_span_sec.disconnect(self._on_buffer_time_span)
1323+
handler.frame_ready.disconnect(self._on_frame)
1324+
handler.buffer_status.disconnect(self._on_buffer_status)
1325+
handler.buffer_time_span_sec.disconnect(self._on_buffer_time_span)
13241326
except (TypeError, RuntimeError):
13251327
pass
1326-
self._handler = None
13271328
self._buffer_actual_sec = None
13281329
self._update_fps_label()
13291330
if self._on_stop:

blitz/layout/main.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,8 +1290,22 @@ def _update_bench_timer(self) -> None:
12901290
self._bench_timer.stop()
12911291
self.ui.label_bench_live.setText("")
12921292

1293+
def _sync_pca_target_comp_to_data(self) -> None:
1294+
"""Update Target Comp max and default from current data (e.g. when PCA tab is shown)."""
1295+
data = getattr(self.ui.image_viewer, "data", None)
1296+
n_frames = max(1, data.n_images) if data else 1
1297+
target_max = min(n_frames, 500)
1298+
target = self.ui.spinbox_pcacomp_target
1299+
target.setMaximum(target_max)
1300+
current = target.value()
1301+
if current < 1 or current > target_max or (current == 1 and target_max > 1):
1302+
default_target = min(n_frames // 2, 50, target_max)
1303+
default_target = max(1, default_target)
1304+
target.setValue(default_target)
1305+
self._pca_update_target_spinner_state()
1306+
12931307
def _on_option_tab_changed(self, index: int) -> None:
1294-
"""Toggle LIVE indicator and timer when Bench tab visible."""
1308+
"""Toggle LIVE indicator and timer when Bench tab visible. Sync PCA Target Comp when PCA tab shown."""
12951309
bench_idx = getattr(
12961310
self.ui, "bench_tab_index",
12971311
self.ui.option_tabwidget.count() - 1,
@@ -1302,6 +1316,9 @@ def _on_option_tab_changed(self, index: int) -> None:
13021316
else:
13031317
self.ui.label_bench_live.setText("")
13041318
self._update_bench_timer()
1319+
pca_idx = getattr(self.ui, "pca_tab_index", -1)
1320+
if index == pca_idx:
1321+
self._sync_pca_target_comp_to_data()
13051322

13061323
def _bench_tick(self) -> None:
13071324
"""Sample CPU/RAM/Disk, feed shared BenchData, refresh Bench tab + compact (if shown)."""

blitz/layout/ui.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,7 @@ def _set_timeline_splitter_sizes():
961961

962962
pca_layout.addStretch()
963963
self.create_option_tab(pca_layout, "PCA")
964+
self.pca_tab_index = self.option_tabwidget.count() - 1
964965

965966
# --- Bench ---
966967
bench_layout = QVBoxLayout()

blitz/layout/viewer.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@ def setImage(self, *args, keep_timestep: bool = False, skip_roi_init: bool = Fal
274274
self.image_changed.emit()
275275

276276
def updateImage(self, autoHistogramRange: bool = False) -> None:
277-
super().updateImage(autoHistogramRange)
277+
"""Override: when Auto fit is off, never recalc LUT on frame change (timeline click/drag)."""
278+
super().updateImage(autoHistogramRange=self._auto_fit)
278279

279280
def toggle_auto_colormap(self) -> None:
280281
self._auto_colormap = not self._auto_colormap
@@ -454,8 +455,9 @@ def unravel(self) -> None:
454455
autoRange=False,
455456
autoLevels=self._auto_fit,
456457
)
457-
self.setLevels(min=mn, max=mx)
458-
self.ui.histogram.setHistogramRange(mn, mx)
458+
if self._auto_fit:
459+
self.setLevels(min=mn, max=mx)
460+
self.ui.histogram.setHistogramRange(mn, mx)
459461
self.image_size_changed.emit()
460462

461463
def reduce(
File renamed without changes.

0 commit comments

Comments
 (0)