Add tqdm progress bar to Python solver#681
Conversation
Shows a progress bar during simulation when quiet=False (default). Suppressed with quiet=True. Uses tqdm with step count and rate. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #681 +/- ##
==========================================
+ Coverage 74.23% 74.26% +0.02%
==========================================
Files 56 56
Lines 8012 8020 +8
Branches 1566 1568 +2
==========================================
+ Hits 5948 5956 +8
Misses 1441 1441
Partials 623 623
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
kwave/solvers/kspace_solver.py
Outdated
| self.step() | ||
| remaining = self.Nt - self.t | ||
| if not self.quiet and remaining > 0: | ||
| from tqdm import tqdm |
There was a problem hiding this comment.
Lazy import for a required dependency
tqdm is now a required runtime dependency (added to pyproject.toml), so the deferred from tqdm import tqdm inside the conditional block is unnecessary. Moving it to the module-level imports at the top of the file keeps the import style consistent with the rest of the module and makes the dependency visible at a glance.
Or simply add from tqdm import tqdm at the top of kspace_solver.py alongside the other imports and remove the inline import here.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
tqdm is a required dependency — no need for lazy import. Also regenerates uv.lock so tqdm appears in the resolved dependency list for plain installs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@greptile-app |
Shows a progress bar during simulation when quiet=False (default). Suppressed with quiet=True. Uses tqdm with step count and rate.
Greptile Summary
This PR adds a
tqdmprogress bar to the Python solver'srun()loop, giving users real-time feedback (step count, rate, and ETA) during simulations. The bar is shown by default (quiet=False) and suppressed withquiet=True, which was already an accepted parameter inkspaceFirstOrderand is now correctly threaded through to theSimulationclass.Key changes:
tqdmpromoted to a module-level import inkspace_solver.pyand declared as a runtime dependency (>=4.60).Simulation.__init__gains aquietkeyword argument (defaultFalse), stored asself.quiet.run()wraps the step loop in atqdmcontext manager whennot self.quietandremaining > 0; thetotalis set toremaining = self.Nt - self.t, so the bar is accurate even if some steps were already executed manually beforerun()was called.quietflag (C++ path already forwarded it tocpp_sim.run()).quiet=True.Confidence Score: 5/5
Safe to merge — the change is additive, correctly scoped to the Python backend's run loop, and covered by new smoke tests.
No P0 or P1 issues found. The
tqdmintegration is minimal and correct:totaltracks remaining steps accurately, both backends honourquiet, the import is at module level, and the dependency version floor is sensible. All existing behaviour is preserved whenquiet=True.No files require special attention.
Important Files Changed
quietparameter toSimulation.__init__and wraps the run loop with atqdmprogress bar whenquiet=False;tqdmis now a module-level import.quietparameter through toSimulation; the C++ backend already forwardedquiettocpp_sim.run(), so both backends are consistent.tqdm>=4.60as a runtime dependency; the minimum version is reasonable given the stable context-manager API used.TestProgressBarwith two smoke tests coveringquiet=False(bar shown) andquiet=True(bar suppressed); both assert on result shape.tqdmin the dependency graph; no concerns.Sequence Diagram
sequenceDiagram participant User participant kspaceFirstOrder participant Simulation participant tqdm User->>kspaceFirstOrder: call(kgrid, medium, source, sensor, quiet=False) kspaceFirstOrder->>Simulation: __init__(..., quiet=False) kspaceFirstOrder->>Simulation: run() Simulation->>Simulation: setup() if not _is_setup Simulation->>Simulation: remaining = Nt - t alt quiet=False and remaining > 0 Simulation->>tqdm: __enter__(total=remaining, desc="k-Wave", unit="step") loop t < Nt Simulation->>Simulation: step() Simulation->>tqdm: update(1) end Simulation->>tqdm: __exit__() else quiet=True loop t < Nt Simulation->>Simulation: step() end end Simulation-->>kspaceFirstOrder: result dict kspaceFirstOrder-->>User: result dictComments Outside Diff (1)
uv.lock, line 763-773 (link)tqdmdependencytqdm>=4.60was added topyproject.tomlbut theuv.lockwas not properly regenerated. Thek-wave-pythonpackage entry in the lock file is missingtqdmin two places:dependenciessection (lines 763–773) listsbeartype,deepdiff,deprecated,h5py,jaxtyping,matplotlib,numpy,opencv-python, andscipy— but nottqdm.[package.metadata] requires-distsection (lines 804–827) also does not include{ name = "tqdm", specifier = ">=4.60" }.Because
tqdmcurrently appears in the lock file only as a transitive dependency ofgdown(an optionalexampleextra) andssfp(a transitive dep of thetestextra), a plainpip install k-wave-pythonoruv syncwithout those extras would not installtqdm, causing anImportErrorat runtime whenquiet=False(the default).Additionally, running
uv lock --checkwill fail because the lock file does not matchpyproject.toml, which will break CI pipelines that verify lock-file integrity.Fix: Run
uv lockto regenerate the lock file sotqdmis recorded as a direct runtime dependency ofk-wave-python.Reviews (2): Last reviewed commit: "Add tests for tqdm progress bar (quiet=F..." | Re-trigger Greptile