k-Wave-python 0.6.0__tar.gz → 0.6.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.
- k_wave_python-0.6.2/.git +1 -0
- k_wave_python-0.6.2/CLAUDE.md +95 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/PKG-INFO +34 -42
- k_wave_python-0.6.2/docs/README.md +66 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/__init__.py +60 -7
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/compat.py +4 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/enums.py +12 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/executor.py +8 -1
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kWaveSimulation_helper/create_absorption_variables.py +4 -4
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kgrid.py +1 -1
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kmedium.py +57 -44
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kspaceFirstOrder.py +112 -8
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kspaceFirstOrder2D.py +5 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kspaceFirstOrder3D.py +5 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/solvers/cpp_simulation.py +97 -14
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/solvers/kspace_solver.py +294 -114
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/checks.py +62 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/conversion.py +22 -10
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/filters.py +22 -8
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/kwave_array.py +49 -26
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/mapgen.py +38 -35
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/math.py +2 -4
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/plot.py +2 -2
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/typing.py +16 -2
- k_wave_python-0.6.2/plans/release-strategy.md +364 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/pyproject.toml +17 -15
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/pytest.ini +1 -0
- k_wave_python-0.6.2/uv.lock +2691 -0
- k_wave_python-0.6.0/.claude/settings.local.json +0 -45
- k_wave_python-0.6.0/Makefile +0 -44
- k_wave_python-0.6.0/docs/README.md +0 -76
- k_wave_python-0.6.0/htmlcov/.gitignore +0 -2
- k_wave_python-0.6.0/htmlcov/class_index.html +0 -733
- k_wave_python-0.6.0/htmlcov/coverage_html_cb_6fb7b396.js +0 -733
- k_wave_python-0.6.0/htmlcov/function_index.html +0 -4913
- k_wave_python-0.6.0/htmlcov/index.html +0 -488
- k_wave_python-0.6.0/htmlcov/status.json +0 -1
- k_wave_python-0.6.0/htmlcov/style_cb_8e611ae1.css +0 -337
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2___init___py.html +0 -99
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_checks_py.html +0 -396
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_colormap_py.html +0 -192
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_conversion_py.html +0 -605
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_data_py.html +0 -307
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_dotdictionary_py.html +0 -156
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_filters_py.html +0 -700
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_interp_py.html +0 -492
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_io_py.html +0 -593
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_mapgen_py.html +0 -3212
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_math_py.html +0 -566
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_matlab_py.html +0 -264
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_matrix_py.html +0 -537
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_pml_py.html +0 -250
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_signals_py.html +0 -833
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_tictoc_py.html +0 -143
- k_wave_python-0.6.0/htmlcov/z_008abe0f134486c2_typing_py.html +0 -133
- k_wave_python-0.6.0/htmlcov/z_08ccaf6f6fd0d069___init___py.html +0 -106
- k_wave_python-0.6.0/htmlcov/z_08ccaf6f6fd0d069_create_absorption_variables_py.html +0 -207
- k_wave_python-0.6.0/htmlcov/z_08ccaf6f6fd0d069_display_simulation_params_py.html +0 -191
- k_wave_python-0.6.0/htmlcov/z_08ccaf6f6fd0d069_expand_grid_matrices_py.html +0 -411
- k_wave_python-0.6.0/htmlcov/z_08ccaf6f6fd0d069_retract_transducer_grid_size_py.html +0 -121
- k_wave_python-0.6.0/htmlcov/z_08ccaf6f6fd0d069_save_to_disk_func_py.html +0 -622
- k_wave_python-0.6.0/htmlcov/z_08ccaf6f6fd0d069_scale_source_terms_func_py.html +0 -494
- k_wave_python-0.6.0/htmlcov/z_08ccaf6f6fd0d069_set_sound_speed_ref_py.html +0 -190
- k_wave_python-0.6.0/htmlcov/z_af83d3eb1fd99cb4___init___py.html +0 -110
- k_wave_python-0.6.0/htmlcov/z_af83d3eb1fd99cb4_simulation_execution_options_py.html +0 -342
- k_wave_python-0.6.0/htmlcov/z_af83d3eb1fd99cb4_simulation_options_py.html +0 -449
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1___init___py.html +0 -304
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_data_py.html +0 -220
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_enums_py.html +0 -121
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_executor_py.html +0 -242
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_kWaveSimulation_py.html +0 -1593
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_kgrid_py.html +0 -800
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_kmedium_py.html +0 -331
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_ksensor_py.html +0 -241
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_ksource_py.html +0 -481
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_kspaceFirstOrder2D_py.html +0 -547
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_ktransducer_py.html +0 -863
- k_wave_python-0.6.0/htmlcov/z_c3dba8f0d3a212d1_recorder_py.html +0 -242
- k_wave_python-0.6.0/htmlcov/z_c6e89a0ff279d0c3___init___py.html +0 -110
- k_wave_python-0.6.0/htmlcov/z_c6e89a0ff279d0c3_time_reversal_py.html +0 -243
- k_wave_python-0.6.0/plans/release-strategy.md +0 -283
- k_wave_python-0.6.0/run_examples.py +0 -26
- k_wave_python-0.6.0/uv.lock +0 -2256
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/.gitignore +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/.pre-commit-config.yaml +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/.readthedocs.yaml +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/CITATION.cff +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/Dockerfile +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/LICENSE +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/data.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kWaveSimulation.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kWaveSimulation_helper/__init__.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kWaveSimulation_helper/display_simulation_params.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kWaveSimulation_helper/expand_grid_matrices.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kWaveSimulation_helper/retract_transducer_grid_size.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kWaveSimulation_helper/save_to_disk_func.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kWaveSimulation_helper/scale_source_terms_func.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kWaveSimulation_helper/set_sound_speed_ref.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/ksensor.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/ksource.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kspaceFirstOrderAS.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kspaceLineRecon.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/kspacePlaneRecon.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/ktransducer.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/options/__init__.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/options/simulation_execution_options.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/options/simulation_options.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/reconstruction/__init__.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/reconstruction/beamform.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/reconstruction/time_reversal.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/reconstruction/tools.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/recorder.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/solvers/__init__.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/solvers/native.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/solvers/validation.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/__init__.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/angular_spectrum.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/angular_spectrum_cw.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/atten_comp.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/colormap.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/data.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/dotdictionary.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/interp.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/io.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/matlab.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/matrix.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/pml.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/sharpness_filters.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/signals.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/kwave/utils/tictoc.py +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/make_docs.sh +0 -0
- {k_wave_python-0.6.0 → k_wave_python-0.6.2}/run_tests.sh +0 -0
k_wave_python-0.6.2/.git
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
gitdir: /Users/Walter/git/k-wave-python/.git/worktrees/kwave-v0.6.2
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## What is k-wave-python?
|
|
6
|
+
|
|
7
|
+
Python implementation of the [k-Wave](http://www.k-wave.org/) acoustics toolbox for time-domain acoustic and ultrasound simulations. Two backends: a pure Python/NumPy/CuPy solver and C++ binaries (OMP/CUDA).
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Setup
|
|
13
|
+
uv sync --extra dev --extra test
|
|
14
|
+
uv run pre-commit install
|
|
15
|
+
|
|
16
|
+
# Run tests
|
|
17
|
+
uv run pytest # all tests
|
|
18
|
+
uv run pytest tests/test_kgrid.py # single file
|
|
19
|
+
uv run pytest tests/test_kgrid.py::test_name # single test
|
|
20
|
+
uv run pytest -m integration # MATLAB-reference tests only
|
|
21
|
+
|
|
22
|
+
# Lint/format
|
|
23
|
+
uv run ruff check . --fix
|
|
24
|
+
uv run ruff format .
|
|
25
|
+
uv run pre-commit run --all-files
|
|
26
|
+
|
|
27
|
+
# Run an example
|
|
28
|
+
uv run examples/ivp_homogeneous_medium.py
|
|
29
|
+
|
|
30
|
+
# Build
|
|
31
|
+
uv build
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Always use `uv run` (not `uv run python`) for pytest, examples, and scripts.
|
|
35
|
+
|
|
36
|
+
## Code Style
|
|
37
|
+
|
|
38
|
+
- Line length: 140 (configured in `pyproject.toml` under `[tool.ruff]`)
|
|
39
|
+
- Pre-commit hooks: ruff (lint + format), codespell, nb-clean
|
|
40
|
+
- Ruff ignores F821 (nested function refs) and F722 (jaxtyping annotations)
|
|
41
|
+
- Type annotations use `beartype` + `jaxtyping`
|
|
42
|
+
|
|
43
|
+
## Architecture
|
|
44
|
+
|
|
45
|
+
### Entry point
|
|
46
|
+
|
|
47
|
+
`kwave/kspaceFirstOrder.py` — `kspaceFirstOrder()` is the unified API. It accepts `kgrid`, `medium`, `source`, `sensor` and dispatches to the appropriate backend.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
kspaceFirstOrder(kgrid, medium, source, sensor, backend="python"|"cpp", device="cpu"|"gpu")
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Two backends
|
|
54
|
+
|
|
55
|
+
- **Python backend** (`kwave/solvers/kspace_solver.py`): `Simulation` class implementing k-space pseudospectral method in NumPy/CuPy. Supports 1D/2D/3D. Uses CuPy for GPU when `device="gpu"`.
|
|
56
|
+
- **C++ backend** (`kwave/solvers/cpp_simulation.py` + `kwave/executor.py`): Serializes to HDF5, invokes compiled C++ binary, reads results back. `save_only=True` writes HDF5 without running (for cluster jobs).
|
|
57
|
+
|
|
58
|
+
### Core data classes
|
|
59
|
+
|
|
60
|
+
- `kWaveGrid` (`kwave/kgrid.py`) — domain discretization, spacing, time array
|
|
61
|
+
- `kWaveMedium` (`kwave/kmedium.py`) — sound speed, density, absorption, nonlinearity
|
|
62
|
+
- `kSource` (`kwave/ksource.py`) — pressure/velocity sources with masks and signals
|
|
63
|
+
- `kSensor` (`kwave/ksensor.py`) — sensor mask and recording configuration
|
|
64
|
+
|
|
65
|
+
### Legacy path
|
|
66
|
+
|
|
67
|
+
`kspaceFirstOrder2D()` / `kspaceFirstOrder3D()` in their respective files route through `kWaveSimulation` (`kwave/kWaveSimulation.py`) — a large legacy dataclass used by the C++ backend path. New code should use `kspaceFirstOrder()` directly.
|
|
68
|
+
|
|
69
|
+
### PML handling
|
|
70
|
+
|
|
71
|
+
When `pml_inside=False` (default), `kspaceFirstOrder()` expands the grid by `2*pml_size` before simulation and strips PML from full-grid output fields afterward. `pml_size="auto"` selects optimal sizes via `get_optimal_pml_size()`.
|
|
72
|
+
|
|
73
|
+
### Key utilities
|
|
74
|
+
|
|
75
|
+
- `kwave/utils/pml.py` — PML sizing (`get_pml()`, `get_optimal_pml_size()`)
|
|
76
|
+
- `kwave/utils/mapgen.py` — geometry generators (`make_disc`, `make_ball`, `make_cart_circle`, etc.)
|
|
77
|
+
- `kwave/utils/signals.py` — signal generation (tone bursts, filtering)
|
|
78
|
+
- `kwave/utils/filters.py` — spatial smoothing, Gaussian filters
|
|
79
|
+
- `kwave/utils/io.py` — HDF5 read/write
|
|
80
|
+
- `kwave/utils/conversion.py` — unit conversion, `cart2grid`
|
|
81
|
+
|
|
82
|
+
## Testing
|
|
83
|
+
|
|
84
|
+
- Tests in `tests/`, configured via `[tool.pytest.ini_options]` in `pyproject.toml`
|
|
85
|
+
- Integration tests (`@pytest.mark.integration`) compare against MATLAB reference data
|
|
86
|
+
- Test fixtures in `tests/integration/conftest.py`: `load_matlab_ref` (fixture), `assert_fields_close` (helper function for field comparison)
|
|
87
|
+
- MATLAB reference data for `@pytest.mark.integration` tests lives in `tests/matlab_test_data_collectors/python_testers/collectedValues/` (hardcoded in `conftest.py`)
|
|
88
|
+
- `test_example_parity.py` (MATLAB-parity tests) reads `KWAVE_MATLAB_REF_DIR` (defaults to `~/git/k-wave-cupy/tests` if unset)
|
|
89
|
+
|
|
90
|
+
## Naming Conventions
|
|
91
|
+
|
|
92
|
+
- `backend="python"` or `"cpp"` (not "native")
|
|
93
|
+
- `device="cpu"` or `"gpu"` (not `use_gpu` bool)
|
|
94
|
+
- `quiet=True` to suppress output; `debug=True` for detailed output
|
|
95
|
+
- `pml_size="auto"` for automatic PML sizing (not a separate boolean)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: k-Wave-python
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.2
|
|
4
4
|
Summary: Acoustics toolbox for time domain acoustic and ultrasound simulations in complex and tissue-realistic media.
|
|
5
5
|
Project-URL: Homepage, http://www.k-wave.org/
|
|
6
6
|
Project-URL: Documentation, https://waltersimson.com/k-wave-python/
|
|
7
7
|
Project-URL: Repository, https://github.com/waltsims/k-wave-python
|
|
8
8
|
Project-URL: Bug-tracker, https://github.com/waltsims/k-wave-python/issues
|
|
9
|
-
Author-email: Farid Yagubbayli <farid.yagubbayli@tum.de>, Walter Simson <walter.simson@
|
|
10
|
-
Maintainer-email: Walter Simson <walter.simson@
|
|
9
|
+
Author-email: Farid Yagubbayli <farid.yagubbayli@tum.de>, Walter Simson <walter.a.simson@gmail.com>
|
|
10
|
+
Maintainer-email: Walter Simson <walter.a.simson@gmail.com>, Farid Yagubbayli <farid.yagubbayli@tum.de>, David Sinden <david.sinden@mevis.fraunhofer.de>
|
|
11
11
|
License: GNU LESSER GENERAL PUBLIC LICENSE
|
|
12
12
|
Version 3, 29 June 2007
|
|
13
13
|
|
|
@@ -179,30 +179,32 @@ Classifier: Operating System :: OS Independent
|
|
|
179
179
|
Classifier: Programming Language :: Python :: 3
|
|
180
180
|
Requires-Python: >=3.10
|
|
181
181
|
Requires-Dist: beartype==0.22.9
|
|
182
|
-
Requires-Dist: deepdiff==
|
|
182
|
+
Requires-Dist: deepdiff==9.0.0
|
|
183
183
|
Requires-Dist: deprecated>=1.2.14
|
|
184
|
-
Requires-Dist: h5py==3.
|
|
185
|
-
Requires-Dist: jaxtyping==0.3.
|
|
186
|
-
Requires-Dist: matplotlib==3.10.
|
|
184
|
+
Requires-Dist: h5py==3.16.0
|
|
185
|
+
Requires-Dist: jaxtyping==0.3.7
|
|
186
|
+
Requires-Dist: matplotlib==3.10.9
|
|
187
187
|
Requires-Dist: numpy<2.3.0,>=1.22.2
|
|
188
188
|
Requires-Dist: opencv-python==4.13.0.92
|
|
189
189
|
Requires-Dist: scipy==1.15.3
|
|
190
|
+
Requires-Dist: tqdm>=4.60
|
|
190
191
|
Provides-Extra: dev
|
|
191
|
-
Requires-Dist: pre-commit==4.
|
|
192
|
+
Requires-Dist: pre-commit==4.6.0; extra == 'dev'
|
|
192
193
|
Provides-Extra: docs
|
|
193
|
-
Requires-Dist: furo==
|
|
194
|
+
Requires-Dist: furo==2025.12.19; extra == 'docs'
|
|
194
195
|
Requires-Dist: sphinx-copybutton==0.5.2; extra == 'docs'
|
|
195
196
|
Requires-Dist: sphinx-mdinclude==0.6.2; extra == 'docs'
|
|
196
|
-
Requires-Dist: sphinx-tabs==3.4.
|
|
197
|
-
Requires-Dist: sphinx-toolbox==
|
|
197
|
+
Requires-Dist: sphinx-tabs==3.4.5; extra == 'docs'
|
|
198
|
+
Requires-Dist: sphinx-toolbox==4.1.2; extra == 'docs'
|
|
199
|
+
Requires-Dist: sphinx<9; extra == 'docs'
|
|
198
200
|
Provides-Extra: example
|
|
199
|
-
Requires-Dist: gdown==
|
|
201
|
+
Requires-Dist: gdown==6.0.0; extra == 'example'
|
|
200
202
|
Provides-Extra: test
|
|
201
|
-
Requires-Dist: coverage==7.
|
|
203
|
+
Requires-Dist: coverage==7.14.0; extra == 'test'
|
|
202
204
|
Requires-Dist: phantominator; extra == 'test'
|
|
203
205
|
Requires-Dist: pytest; extra == 'test'
|
|
204
206
|
Requires-Dist: pytest-xdist; extra == 'test'
|
|
205
|
-
Requires-Dist: requests==2.
|
|
207
|
+
Requires-Dist: requests==2.34.0; extra == 'test'
|
|
206
208
|
Requires-Dist: testfixtures==8.3.0; extra == 'test'
|
|
207
209
|
Description-Content-Type: text/markdown
|
|
208
210
|
|
|
@@ -211,52 +213,42 @@ Description-Content-Type: text/markdown
|
|
|
211
213
|
[](https://discord.gg/your-invite-code)
|
|
212
214
|
[](https://k-wave-python.readthedocs.io/en/latest/?badge=latest)
|
|
213
215
|
[](https://codecov.io/gh/waltsims/k-wave-python)
|
|
214
|
-
[](https://mybinder.org/v2/gh/waltsims/k-wave-python/master)
|
|
215
216
|
|
|
216
|
-
|
|
217
|
-
interface to the pre-compiled v1.3 of k-Wave simulation binaries, which support NVIDIA sm 5.0 (Maxwell) to sm 9.0a (Hopper) GPUs.
|
|
218
|
-
|
|
219
|
-
**New in v0.6.0:** Unified `kspaceFirstOrder()` API with a pure NumPy/CuPy solver. See the [API guide](https://k-wave-python.readthedocs.io/en/latest/get_started/new_api.html).
|
|
217
|
+
A Python implementation of [k-Wave](http://www.k-wave.org/) — an acoustics toolbox for time-domain simulation of acoustic wave fields. Includes a pure NumPy/CuPy solver (`backend="python"`) and an interface to the pre-compiled k-Wave C++ binaries (`backend="cpp"`) with NVIDIA GPU support (sm 5.0–9.0a).
|
|
220
218
|
|
|
221
219
|
## Mission
|
|
222
220
|
|
|
223
|
-
|
|
224
|
-
for medical imaging, algorithmic prototyping, and testing. Many tools and methods of [k-Wave](http://www.k-wave.org/) can
|
|
225
|
-
be found here, but this project has and will continue to diverge from the original [k-Wave](http://www.k-wave.org/) APIs
|
|
226
|
-
to leverage pythonic practices.
|
|
221
|
+
Increase the accessibility and reproducibility of [k-Wave](http://www.k-wave.org/) simulations for medical imaging, algorithmic prototyping, and testing.
|
|
227
222
|
|
|
228
223
|
## Getting started
|
|
229
224
|
|
|
230
225
|

|
|
231
226
|
|
|
232
|
-
A
|
|
227
|
+
A [collection of examples](../examples/) covers common simulation scenarios. Run any example locally:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
uv run examples/ivp_homogeneous_medium.py
|
|
231
|
+
```
|
|
233
232
|
|
|
234
|
-
|
|
235
|
-
1. Generating a simulation medium
|
|
236
|
-
2. Configuring a transducer
|
|
237
|
-
3. Running the simulation
|
|
238
|
-
4. Reconstructing the simulation
|
|
233
|
+
No GPU required — all examples run on CPU with NumPy.
|
|
239
234
|
|
|
240
235
|
## Installation
|
|
241
236
|
|
|
242
|
-
|
|
237
|
+
Using [uv](https://docs.astral.sh/uv/) (recommended):
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
uv add k-wave-python
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Or with pip:
|
|
243
244
|
|
|
244
245
|
```bash
|
|
245
246
|
pip install k-wave-python
|
|
246
247
|
```
|
|
247
|
-
> **Note for MacOS:**
|
|
248
|
-
>
|
|
249
|
-
> k-wave-python offers initial support for MacOS, but you will need to install the following dependencies using the [brew package manager](https://docs.brew.sh/Installation) along with the Python package:
|
|
250
|
-
> ```bash
|
|
251
|
-
> brew install fftw hdf5 zlib libomp
|
|
252
|
-
> ```
|
|
253
|
-
After installing the Python package, the required binaries will be downloaded and installed the first time you run a
|
|
254
|
-
simulation.
|
|
255
248
|
|
|
256
249
|
## Development
|
|
257
250
|
|
|
258
|
-
|
|
259
|
-
found [here](https://k-wave-python.readthedocs.io/en/latest/development/development_environment.html).
|
|
251
|
+
Development instructions can be found [here](https://k-wave-python.readthedocs.io/en/latest/development/development_environment.html).
|
|
260
252
|
|
|
261
253
|
## Related Projects
|
|
262
254
|
|
|
@@ -273,7 +265,7 @@ The documentation for k-wave-python can be found [here](https://k-wave-python.re
|
|
|
273
265
|
## Citation
|
|
274
266
|
```bibtex
|
|
275
267
|
@software{k-Wave-Python,
|
|
276
|
-
author = {
|
|
268
|
+
author = {Yagubbayli, Farid and Sinden, David and Simson, Walter},
|
|
277
269
|
license = {GPL-3.0},
|
|
278
270
|
title = {{k-Wave-Python}},
|
|
279
271
|
url = {https://github.com/waltsims/k-wave-python}
|
|
@@ -281,4 +273,4 @@ url = {https://github.com/waltsims/k-wave-python}
|
|
|
281
273
|
```
|
|
282
274
|
## Contact
|
|
283
275
|
|
|
284
|
-
e-mail [
|
|
276
|
+
e-mail [walter.a.simson@gmail.com](mailto:walter.a.simson@gmail.com).
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# k-wave-python
|
|
2
|
+
|
|
3
|
+
[](https://discord.gg/your-invite-code)
|
|
4
|
+
[](https://k-wave-python.readthedocs.io/en/latest/?badge=latest)
|
|
5
|
+
[](https://codecov.io/gh/waltsims/k-wave-python)
|
|
6
|
+
|
|
7
|
+
A Python implementation of [k-Wave](http://www.k-wave.org/) — an acoustics toolbox for time-domain simulation of acoustic wave fields. Includes a pure NumPy/CuPy solver (`backend="python"`) and an interface to the pre-compiled k-Wave C++ binaries (`backend="cpp"`) with NVIDIA GPU support (sm 5.0–9.0a).
|
|
8
|
+
|
|
9
|
+
## Mission
|
|
10
|
+
|
|
11
|
+
Increase the accessibility and reproducibility of [k-Wave](http://www.k-wave.org/) simulations for medical imaging, algorithmic prototyping, and testing.
|
|
12
|
+
|
|
13
|
+
## Getting started
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
A [collection of examples](../examples/) covers common simulation scenarios. Run any example locally:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
uv run examples/ivp_homogeneous_medium.py
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
No GPU required — all examples run on CPU with NumPy.
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
Using [uv](https://docs.astral.sh/uv/) (recommended):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv add k-wave-python
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or with pip:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pip install k-wave-python
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Development
|
|
40
|
+
|
|
41
|
+
Development instructions can be found [here](https://k-wave-python.readthedocs.io/en/latest/development/development_environment.html).
|
|
42
|
+
|
|
43
|
+
## Related Projects
|
|
44
|
+
|
|
45
|
+
1. [k-Wave](https://github.com/ucl-bug/k-wave): A MATLAB toolbox for the time-domain simulation of acoustic wave fields.
|
|
46
|
+
2. [j-wave](https://github.com/ucl-bug/jwave): Differentiable acoustic simulations in JAX.
|
|
47
|
+
3. [ADSeismic.jl](https://github.com/kailaix/ADSeismic.jl): a finite difference acoustic simulator with support for AD
|
|
48
|
+
and JIT compilation in Julia.
|
|
49
|
+
4. [stride](https://github.com/trustimaging/stride): a general optimisation framework for medical ultrasound tomography.
|
|
50
|
+
|
|
51
|
+
## Documentation
|
|
52
|
+
|
|
53
|
+
The documentation for k-wave-python can be found [here](https://k-wave-python.readthedocs.io/en/latest/).
|
|
54
|
+
|
|
55
|
+
## Citation
|
|
56
|
+
```bibtex
|
|
57
|
+
@software{k-Wave-Python,
|
|
58
|
+
author = {Yagubbayli, Farid and Sinden, David and Simson, Walter},
|
|
59
|
+
license = {GPL-3.0},
|
|
60
|
+
title = {{k-Wave-Python}},
|
|
61
|
+
url = {https://github.com/waltsims/k-wave-python}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
## Contact
|
|
65
|
+
|
|
66
|
+
e-mail [walter.a.simson@gmail.com](mailto:walter.a.simson@gmail.com).
|
|
@@ -3,23 +3,45 @@ import json
|
|
|
3
3
|
import logging
|
|
4
4
|
import os
|
|
5
5
|
import platform
|
|
6
|
+
import stat
|
|
7
|
+
import warnings
|
|
6
8
|
from pathlib import Path
|
|
7
9
|
from typing import List
|
|
8
10
|
from urllib.request import urlretrieve
|
|
9
11
|
|
|
10
12
|
# Test installation with:
|
|
11
13
|
# python3 -m pip install -i https://test.pypi.org/simple/ --extra-index-url=https://pypi.org/simple/ k-Wave-python==0.3.0
|
|
12
|
-
__version__ = "0.6.
|
|
14
|
+
__version__ = "0.6.2"
|
|
13
15
|
|
|
14
16
|
# Constants and Configurations
|
|
15
17
|
URL_BASE = "https://github.com/waltsims/"
|
|
16
|
-
BINARY_VERSION = "v1.
|
|
17
|
-
|
|
18
|
+
BINARY_VERSION = "v1.4.1"
|
|
19
|
+
# Pin both Windows binaries to v1.3.0. v1.4.x windows builds switched compiler /
|
|
20
|
+
# OpenMP / FFT / CUDA runtime stacks and neither v1.4.x release ships its runtime
|
|
21
|
+
# DLLs (cufft, cudart, vcomp, vcruntime140_1, fftw3f, etc.). v1.3.0 binaries are
|
|
22
|
+
# self-contained with their Intel-era DLL bundle (listed in WINDOWS_DLLS below,
|
|
23
|
+
# downloaded with the OMP request and used by both .exe files since they share
|
|
24
|
+
# kwave/bin/windows/). OMP DLL bundling is fixed in kspacefirstorder-unified#14
|
|
25
|
+
# (awaiting validation); CUDA DLL bundling is tracked in kspacefirstorder-unified#17.
|
|
26
|
+
WINDOWS_OMP_VERSION = "v1.3.0"
|
|
27
|
+
WINDOWS_CUDA_VERSION = "v1.3.0"
|
|
18
28
|
PLATFORM = platform.system().lower()
|
|
19
29
|
|
|
20
30
|
if PLATFORM not in ["linux", "windows", "darwin"]:
|
|
21
31
|
raise NotImplementedError(f"k-wave-python is currently unsupported on this operating system: {PLATFORM}.")
|
|
22
32
|
|
|
33
|
+
# darwin C++ binary is arm64-only; universal2 coverage tracked for v0.6.5
|
|
34
|
+
DARWIN_BINARY_ARCH = "arm64"
|
|
35
|
+
_darwin_unsupported = PLATFORM == "darwin" and platform.machine() != DARWIN_BINARY_ARCH
|
|
36
|
+
if _darwin_unsupported:
|
|
37
|
+
warnings.warn(
|
|
38
|
+
f"k-wave-python's macOS C++ binary is {DARWIN_BINARY_ARCH}-only. "
|
|
39
|
+
f"Detected {platform.machine()} — the C++ backend (backend='cpp') will not run on this machine. "
|
|
40
|
+
"Use backend='python' instead. Universal2 (Intel + Apple Silicon) coverage is tracked for v0.6.5.",
|
|
41
|
+
RuntimeWarning,
|
|
42
|
+
stacklevel=2,
|
|
43
|
+
)
|
|
44
|
+
|
|
23
45
|
# TODO: install directly in to /bin/ directory system directory is no longer needed
|
|
24
46
|
# TODO: deprecate in 0.5.0
|
|
25
47
|
BINARY_PATH = Path(__file__).parent / "bin" / PLATFORM
|
|
@@ -44,21 +66,24 @@ ARCHITECTURES = ["omp", "cuda"]
|
|
|
44
66
|
|
|
45
67
|
|
|
46
68
|
def get_windows_release_urls(architecture: str) -> list:
|
|
69
|
+
version = WINDOWS_OMP_VERSION if architecture == "omp" else WINDOWS_CUDA_VERSION
|
|
47
70
|
specific_filenames = [EXECUTABLE_PREFIX + architecture + ".exe"]
|
|
48
71
|
if architecture == "omp":
|
|
49
72
|
specific_filenames += WINDOWS_DLLS
|
|
50
|
-
|
|
51
|
-
return
|
|
73
|
+
base = f"{URL_BASE}kspaceFirstOrder-{architecture.upper()}-{PLATFORM.lower()}/releases/download/{version}/"
|
|
74
|
+
return [base + filename for filename in specific_filenames]
|
|
52
75
|
|
|
53
76
|
|
|
54
77
|
URL_DICT = {
|
|
55
78
|
"linux": {
|
|
56
|
-
"cuda": [URL_BASE + f"kspaceFirstOrder-CUDA-{PLATFORM}/releases/download/
|
|
79
|
+
"cuda": [URL_BASE + f"kspaceFirstOrder-CUDA-{PLATFORM}/releases/download/{BINARY_VERSION}/{EXECUTABLE_PREFIX}CUDA"],
|
|
57
80
|
"omp": [URL_BASE + f"kspaceFirstOrder-OMP-{PLATFORM}/releases/download/{BINARY_VERSION}/{EXECUTABLE_PREFIX}OMP"],
|
|
58
81
|
},
|
|
59
82
|
"darwin": {
|
|
60
83
|
"cuda": [],
|
|
61
|
-
"omp":
|
|
84
|
+
"omp": (
|
|
85
|
+
[] if _darwin_unsupported else [URL_BASE + f"k-wave-omp-{PLATFORM}/releases/download/{BINARY_VERSION}/{EXECUTABLE_PREFIX}OMP"]
|
|
86
|
+
),
|
|
62
87
|
},
|
|
63
88
|
"windows": {architecture: get_windows_release_urls(architecture) for architecture in ARCHITECTURES},
|
|
64
89
|
}
|
|
@@ -77,6 +102,31 @@ def _hash_file(filepath: str) -> str:
|
|
|
77
102
|
return md5.hexdigest()
|
|
78
103
|
|
|
79
104
|
|
|
105
|
+
def _ensure_executable(binary_filepath) -> None:
|
|
106
|
+
# Self-heal the executable bit on Linux/macOS. urlretrieve creates files
|
|
107
|
+
# at 0644, and prior versions of this package didn't fix that up, so users
|
|
108
|
+
# upgrading with a cached non-executable binary on disk would otherwise
|
|
109
|
+
# stay stuck (the cache check below returns True and skips re-download).
|
|
110
|
+
# Any OS-level failure here (broken symlink, read-only FS, wrong ownership,
|
|
111
|
+
# TOCTOU race) is degraded to a warning so it never aborts `import kwave`.
|
|
112
|
+
if PLATFORM == "windows":
|
|
113
|
+
return
|
|
114
|
+
try:
|
|
115
|
+
current_mode = os.stat(binary_filepath).st_mode
|
|
116
|
+
desired_mode = current_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
|
|
117
|
+
if current_mode == desired_mode:
|
|
118
|
+
return
|
|
119
|
+
os.chmod(binary_filepath, desired_mode)
|
|
120
|
+
except OSError: # pragma: no cover - defensive; degrades to warning, never fatal
|
|
121
|
+
# Don't abort import. The user can chmod +x manually or reinstall
|
|
122
|
+
# into a writable location.
|
|
123
|
+
logging.warning(
|
|
124
|
+
"kwave: cannot set executable bit on %s — backend='cpp' may fail with "
|
|
125
|
+
"Permission denied. Run `chmod +x` manually or reinstall.",
|
|
126
|
+
binary_filepath,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
|
|
80
130
|
def _is_binary_present(binary_name: str, binary_type: str) -> bool:
|
|
81
131
|
binary_filepath = BINARY_PATH / binary_name
|
|
82
132
|
binary_file_exists = os.path.exists(binary_filepath)
|
|
@@ -106,6 +156,8 @@ def _is_binary_present(binary_name: str, binary_type: str) -> bool:
|
|
|
106
156
|
if existing_metadata["url"] not in latest_urls:
|
|
107
157
|
return False
|
|
108
158
|
|
|
159
|
+
_ensure_executable(binary_filepath)
|
|
160
|
+
|
|
109
161
|
# No need to check `version` field for now
|
|
110
162
|
# because we version is already present in the URL
|
|
111
163
|
return True
|
|
@@ -176,6 +228,7 @@ def download_binaries(system_os: str, bin_type: str):
|
|
|
176
228
|
try:
|
|
177
229
|
binary_filepath = os.path.join(BINARY_PATH, filename)
|
|
178
230
|
urlretrieve(url, binary_filepath)
|
|
231
|
+
_ensure_executable(binary_filepath)
|
|
179
232
|
_record_binary_metadata(binary_version=binary_version, binary_filepath=binary_filepath, binary_url=url, filename=filename)
|
|
180
233
|
|
|
181
234
|
except TimeoutError:
|
|
@@ -70,5 +70,9 @@ def options_to_kwargs(simulation_options=None, execution_options=None):
|
|
|
70
70
|
kwargs["num_threads"] = opts.num_threads
|
|
71
71
|
if opts.device_num is not None:
|
|
72
72
|
kwargs["device_num"] = opts.device_num
|
|
73
|
+
# Read _binary_path directly: the property auto-resolves to a default,
|
|
74
|
+
# so it can't distinguish a user-set path from one.
|
|
75
|
+
if opts._binary_path is not None:
|
|
76
|
+
kwargs["binary_path"] = opts._binary_path
|
|
73
77
|
|
|
74
78
|
return kwargs
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
from enum import Enum
|
|
2
2
|
|
|
3
|
+
|
|
4
|
+
class AlphaMode(str, Enum):
|
|
5
|
+
"""Controls which absorption/dispersion terms are included in the equation of state."""
|
|
6
|
+
|
|
7
|
+
NO_ABSORPTION = "no_absorption"
|
|
8
|
+
NO_DISPERSION = "no_dispersion"
|
|
9
|
+
STOKES = "stokes"
|
|
10
|
+
|
|
11
|
+
def __str__(self):
|
|
12
|
+
return self.value
|
|
13
|
+
|
|
14
|
+
|
|
3
15
|
################################################################
|
|
4
16
|
# literals that link the discrete cosine and sine transform types with
|
|
5
17
|
# their type definitions in the functions dtt1D, dtt2D, and dtt3D
|
|
@@ -52,9 +52,16 @@ class Executor:
|
|
|
52
52
|
raise subprocess.CalledProcessError(proc.returncode, command, stdout, stderr)
|
|
53
53
|
|
|
54
54
|
except subprocess.CalledProcessError as e:
|
|
55
|
-
# This ensures stdout is printed regardless of show_sim_logs value if an error occurs
|
|
56
55
|
print(e.stdout)
|
|
57
56
|
print(e.stderr, file=sys.stderr)
|
|
57
|
+
if sys.platform == "darwin" and e.stderr and any(s in e.stderr for s in ("Library not loaded", "image not found", "dyld")):
|
|
58
|
+
print(
|
|
59
|
+
"\nMissing macOS libraries for the C++ backend.\n"
|
|
60
|
+
"Install them with:\n\n"
|
|
61
|
+
" brew install fftw hdf5 zlib libomp\n\n"
|
|
62
|
+
"Alternatively, use backend='python' which requires no extra dependencies.",
|
|
63
|
+
file=sys.stderr,
|
|
64
|
+
)
|
|
58
65
|
raise
|
|
59
66
|
|
|
60
67
|
sensor_data = self.parse_executable_output(output_filename)
|
|
@@ -12,19 +12,19 @@ def create_absorption_variables(kgrid: kWaveGrid, medium: kWaveMedium, equation_
|
|
|
12
12
|
# define the lossy derivative operators and proportionality coefficients
|
|
13
13
|
"""
|
|
14
14
|
Selects and returns absorption and dispersion operators and coefficients for the given medium based on the equation of state.
|
|
15
|
-
|
|
15
|
+
|
|
16
16
|
Parameters:
|
|
17
17
|
kgrid (kWaveGrid): Grid object providing wavenumber array via `kgrid.k`.
|
|
18
18
|
medium (kWaveMedium): Medium properties used to compute absorption/dispersion coefficients.
|
|
19
19
|
equation_of_state (str): One of `"absorbing"`, `"stokes"`, or `"lossless"` determining which variables to produce.
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
Returns:
|
|
22
22
|
tuple: (nabla1, nabla2, tau, eta)
|
|
23
23
|
- nabla1: First-order absorption operator or `None` when not applicable.
|
|
24
24
|
- nabla2: Dispersion operator or `None` when not applicable.
|
|
25
25
|
- tau: Absorbing coefficient or `None` when not applicable.
|
|
26
26
|
- eta: Dispersive coefficient or `None` when not applicable.
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
Behavior:
|
|
29
29
|
- "absorbing": returns (nabla1, nabla2, tau, eta) computed for an absorbing medium.
|
|
30
30
|
- "stokes": returns (None, None, tau, None) where `tau` is the Stokes absorbing coefficient.
|
|
@@ -127,4 +127,4 @@ def apply_alpha_filter(medium, nabla1, nabla2):
|
|
|
127
127
|
# shift the parameters back
|
|
128
128
|
nabla1 = np.fft.ifftshift(nabla1)
|
|
129
129
|
nabla2 = np.fft.ifftshift(nabla2)
|
|
130
|
-
return nabla1, nabla2
|
|
130
|
+
return nabla1, nabla2
|
|
@@ -108,7 +108,7 @@ class kWaveGrid(object):
|
|
|
108
108
|
@t_array.setter
|
|
109
109
|
def t_array(self, t_array):
|
|
110
110
|
# check for 'auto' input
|
|
111
|
-
if t_array == "auto":
|
|
111
|
+
if isinstance(t_array, str) and t_array == "auto":
|
|
112
112
|
# set values to auto
|
|
113
113
|
self.Nt = "auto"
|
|
114
114
|
self.dt = "auto"
|