dct-toolkit 0.6.0__tar.gz → 2.0.0__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.
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/AGENTS.md +67 -27
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/CHANGELOG.md +109 -0
- dct_toolkit-2.0.0/PKG-INFO +425 -0
- dct_toolkit-2.0.0/README.md +379 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/dct_toolkit/__init__.py +39 -21
- dct_toolkit-2.0.0/dct_toolkit/_gaussian.py +50 -0
- dct_toolkit-2.0.0/dct_toolkit/_geometry.py +560 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/dct_toolkit/_kernels.py +1 -1
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/dct_toolkit/cartesian.py +7 -3
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/dct_toolkit/core.py +15 -3
- dct_toolkit-2.0.0/dct_toolkit/polar.py +448 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/dct_toolkit/stats.py +309 -107
- dct_toolkit-2.0.0/docs/API_REFERENCE.md +499 -0
- dct_toolkit-2.0.0/docs/MATHEMATICAL_BASIS.md +406 -0
- dct_toolkit-2.0.0/docs/RELEASING.md +127 -0
- dct_toolkit-2.0.0/examples/nd_polar.py +96 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/pyproject.toml +2 -2
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/tests/test_core.py +4 -4
- dct_toolkit-2.0.0/tests/test_gaussian.py +194 -0
- dct_toolkit-2.0.0/tests/test_geometry_precision.py +282 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/tests/test_polar_kernels.py +13 -4
- dct_toolkit-2.0.0/tests/test_polar_nd.py +619 -0
- dct_toolkit-2.0.0/tests/test_polar_nd_fallback.py +341 -0
- dct_toolkit-2.0.0/tests/test_polar_nd_stats.py +552 -0
- dct_toolkit-0.6.0/PKG-INFO +0 -199
- dct_toolkit-0.6.0/README.md +0 -153
- dct_toolkit-0.6.0/dct_toolkit/polar.py +0 -295
- dct_toolkit-0.6.0/docs/API_REFERENCE.md +0 -329
- dct_toolkit-0.6.0/docs/MATHEMATICAL_BASIS.md +0 -178
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/.gitignore +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/LICENSE +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/dct_toolkit/_widths.py +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/dct_toolkit/gap_filling.py +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/examples/basic_polar.py +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/examples/comprehensive_demo.py +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/tests/test_api.py +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/tests/test_cartesian.py +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/tests/test_gap_filling.py +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/tests/test_polar.py +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/tests/test_polar_robustness.py +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/tests/test_stats.py +0 -0
- {dct_toolkit-0.6.0 → dct_toolkit-2.0.0}/tests/test_stats_nd.py +0 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# AGENTS.md - DCT Toolkit Agent Guidelines
|
|
2
2
|
|
|
3
3
|
**Project**: dct-toolkit
|
|
4
|
-
**Version**: 0.
|
|
5
|
-
|
|
6
|
-
**
|
|
4
|
+
**Version**: 2.0.0
|
|
5
|
+
|
|
6
|
+
**Status**: Full sampled Gaussian statistics release track
|
|
7
|
+
|
|
8
|
+
**Last Updated**: 2026-11-11
|
|
7
9
|
|
|
8
10
|
---
|
|
9
11
|
|
|
@@ -45,7 +47,16 @@ conda activate dct-publish
|
|
|
45
47
|
- xarray, matplotlib, cmweather (radar colormaps)
|
|
46
48
|
- open-radar-data (sample radar datasets)
|
|
47
49
|
- build, twine (for PyPI publishing)
|
|
48
|
-
- dct-toolkit
|
|
50
|
+
- dct-toolkit editable install (verify the runtime and installed-distribution versions)
|
|
51
|
+
|
|
52
|
+
After changing the package version, refresh editable installation metadata:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
conda run -n dct-publish python -m pip install --no-deps -e .
|
|
56
|
+
conda run -n dct-publish python -c 'from importlib.metadata import version; import dct_toolkit as dct; assert dct.__version__ == version("dct-toolkit")'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
An editable source import alone does not update installed distribution metadata.
|
|
49
60
|
|
|
50
61
|
### PYTHONPATH
|
|
51
62
|
When running tests or examples from project root:
|
|
@@ -158,8 +169,9 @@ dct_toolkit/ # PROJECT ROOT
|
|
|
158
169
|
├── dct_toolkit/ # INSTALLABLE PACKAGE ⚠️ CODE GOES HERE
|
|
159
170
|
│ ├── __init__.py # Public API exports
|
|
160
171
|
│ ├── core.py # Transfer functions & 1D primitives
|
|
161
|
-
│ ├── cartesian.py #
|
|
162
|
-
│ ├── polar.py # 2D
|
|
172
|
+
│ ├── cartesian.py # N-D Cartesian separable smoothing
|
|
173
|
+
│ ├── polar.py # Legacy 2D and explicit geometry-aware N-D smoothing
|
|
174
|
+
│ ├── _geometry.py # Shared axis/coordinate/width validation and support
|
|
163
175
|
│ ├── stats.py # Statistical ops (Normalized Convolution)
|
|
164
176
|
│ └── gap_filling.py # Gap-filling methods (deferred for public stats-first release)
|
|
165
177
|
│
|
|
@@ -189,7 +201,7 @@ dct_toolkit/ # PROJECT ROOT
|
|
|
189
201
|
├── docs/ # DOCUMENTATION
|
|
190
202
|
│ ├── API_REFERENCE.md
|
|
191
203
|
│ ├── MATHEMATICAL_BASIS.md
|
|
192
|
-
│ └──
|
|
204
|
+
│ └── RELEASING.md # Local build, artifact checks, and publication handoff
|
|
193
205
|
│
|
|
194
206
|
├── README.md # Main documentation
|
|
195
207
|
├── CHANGELOG.md # Version history
|
|
@@ -215,7 +227,8 @@ dct_toolkit/ # PROJECT ROOT
|
|
|
215
227
|
|
|
216
228
|
3. **Review Documentation**
|
|
217
229
|
- Check `docs/MATHEMATICAL_BASIS.md` for theory
|
|
218
|
-
-
|
|
230
|
+
- Gap filling outside the exported statistics API remains research-internal;
|
|
231
|
+
inspect `dct_toolkit/gap_filling.py` only when that scope is requested
|
|
219
232
|
- Check `docs/API_REFERENCE.md` for existing API
|
|
220
233
|
|
|
221
234
|
### Making Changes
|
|
@@ -245,6 +258,10 @@ python -m pytest /path/to/dct_toolkit/tests/ -v
|
|
|
245
258
|
|
|
246
259
|
**Expected Output**: all tests passing
|
|
247
260
|
|
|
261
|
+
CI additionally runs the installed package outside the checkout, checks runtime
|
|
262
|
+
and distribution versions agree, and exercises the N-D example. Its minimum
|
|
263
|
+
dependency job uses Python 3.8, NumPy 1.20.0, and SciPy 1.8.0.
|
|
264
|
+
|
|
248
265
|
**If Tests Fail**:
|
|
249
266
|
- Fix the code, not the tests
|
|
250
267
|
- Tests represent ground truth requirements
|
|
@@ -302,8 +319,19 @@ Before declaring task complete:
|
|
|
302
319
|
- [x] Tag `v0.4.0` release
|
|
303
320
|
- [x] Create `research/gap-filling` branch for long-term research
|
|
304
321
|
|
|
305
|
-
###
|
|
306
|
-
|
|
322
|
+
### v1.0.0 Development Scope
|
|
323
|
+
|
|
324
|
+
- Geometry-aware N-D polar arrays with selectable azimuth, elevation, range,
|
|
325
|
+
time, linear, and batch roles in arbitrary array order.
|
|
326
|
+
- Per-axis kernels, boundaries, grid/physical width units, and filtering selection.
|
|
327
|
+
- Complete propagation through normalized moments, support, prefill, and fallback.
|
|
328
|
+
- Unfiltered axes remain isolated domains, including all-missing batches.
|
|
329
|
+
- Keep existing 2D calls compatible; explicit physical-coordinate mode is opt-in.
|
|
330
|
+
- New public APIs need independent numerical tests and an independent code/docs review.
|
|
331
|
+
- Do not modify manuscripts or review trackers as part of this software task.
|
|
332
|
+
|
|
333
|
+
### Future Beyond v2.0.0
|
|
334
|
+
|
|
307
335
|
- [ ] Additional kernels (Savitzky-Golay, Hanning)
|
|
308
336
|
- [ ] Performance optimizations (numba?)
|
|
309
337
|
- [ ] Jupyter notebook examples
|
|
@@ -317,17 +345,31 @@ Before declaring task complete:
|
|
|
317
345
|
### Transfer Functions
|
|
318
346
|
- **Boxcar (Analytical)**: `H[k] = sin(W·θ)/(W·sin(θ))`, θ = πk/(2n)
|
|
319
347
|
- **Boxcar (Discrete)**: Sum of cosines for discrete kernels
|
|
320
|
-
- **Gaussian**:
|
|
348
|
+
- **Gaussian (default)**: full normalized sampled Gaussian, σ = width/√12;
|
|
349
|
+
evaluate its cosine sum or equivalent frequency-alias sum to float64 precision.
|
|
350
|
+
No fixed spatial cutoff; nonnegative spatial weights support statistical moments.
|
|
351
|
+
- **Gaussian (spectral compatibility)**: `gaussian_spectral` retains
|
|
352
|
+
`H[k] = exp(-0.5·(ω·σ)²)`, σ = width/√12; spatial weights can be signed.
|
|
321
353
|
|
|
322
354
|
### Normalized Convolution
|
|
323
355
|
Formula for robust mean with gaps:
|
|
324
356
|
```
|
|
325
|
-
μ = smooth(
|
|
357
|
+
μ = smooth(zero_filled_valid_data) / smooth(valid_mask)
|
|
326
358
|
```
|
|
359
|
+
Apply the complete smoothing operator to each input before normalizing once.
|
|
360
|
+
The denominator must be strictly greater than the floor (default `1e-3`);
|
|
361
|
+
unsupported locations use the documented selective prefill fallback. This is
|
|
362
|
+
not additive-epsilon regularization. `dct_count` reports nominal weighted
|
|
363
|
+
support, not statistical effective sample size.
|
|
327
364
|
|
|
328
365
|
### Polar Coordinates
|
|
329
|
-
- **Data Layout**: (n_azimuth, n_range)
|
|
330
|
-
- **
|
|
366
|
+
- **Legacy Data Layout**: (n_azimuth, n_range), retaining index-based width units.
|
|
367
|
+
- **Explicit N-D Mode**: axis roles, coordinates, and units define the geometry.
|
|
368
|
+
- **Physical Angular Widths**: azimuth scales with `1 / (r * cos(elevation) * dθ)`;
|
|
369
|
+
elevation scales with `1 / (r * dφ)`. Use actual coordinates, not gate indices.
|
|
370
|
+
- **Filter Order**: azimuth, elevation, range, then independent time/linear axes;
|
|
371
|
+
this is an ordered nonstationary operator, not one global separable transform.
|
|
372
|
+
- **Fallback Domains**: never borrow support across unfiltered/batch axes.
|
|
331
373
|
- **Boundary Conditions**:
|
|
332
374
|
- Reflective: DCT-II (even symmetry)
|
|
333
375
|
- Periodic: Real FFT (circular convolution)
|
|
@@ -412,25 +454,23 @@ git merge feature/hanning-window
|
|
|
412
454
|
```
|
|
413
455
|
|
|
414
456
|
### Repository Status
|
|
415
|
-
- GitHub:
|
|
416
|
-
- PyPI: **Public**
|
|
417
|
-
- conda-forge: **
|
|
418
|
-
|
|
419
|
-
**Check conda-forge PR Status**:
|
|
420
|
-
```bash
|
|
421
|
-
gh pr view 32930 --repo conda-forge/staged-recipes
|
|
422
|
-
# Or visit: https://github.com/conda-forge/staged-recipes/pull/32930
|
|
423
|
-
```
|
|
457
|
+
- GitHub: **Public** — `JValdivia23/dct-toolkit`
|
|
458
|
+
- PyPI: **Public** distribution channel; local version changes do not publish a release
|
|
459
|
+
- conda-forge: **Approved & Merged** — Feedstock live at `conda-forge/dct-toolkit-feedstock`
|
|
424
460
|
|
|
425
461
|
### Current Version
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
462
|
+
|
|
463
|
+
- Version: `2.0.0`, using the full sampled Gaussian by default across smoothing
|
|
464
|
+
and statistics. Use `gaussian_spectral` to reproduce pre-2.0 Gaussian results.
|
|
465
|
+
- Preserve the historical `v1.0.0`, `v0.6.0`, and older release records.
|
|
466
|
+
- Do not tag, push, upload to PyPI/conda-forge, or create a public archival record
|
|
467
|
+
without approval.
|
|
468
|
+
- See `docs/RELEASING.md` for local artifact verification and release handoff.
|
|
429
469
|
|
|
430
470
|
### Gap-Filling Status
|
|
431
471
|
- Code exists in `dct_toolkit/gap_filling.py` (available for import directly)
|
|
432
472
|
- **Not exported** in public API (`__init__.py`) — research-internal
|
|
433
|
-
- Full gap-filling to be released in future
|
|
473
|
+
- Full gap-filling to be released in a future version after research matures
|
|
434
474
|
|
|
435
475
|
---
|
|
436
476
|
|
|
@@ -5,6 +5,115 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [2.0.0] - 2026-11-11
|
|
11
|
+
|
|
12
|
+
Major release changing the default Gaussian's numerical definition. Existing
|
|
13
|
+
calls remain accepted, but Gaussian outputs change. For reproducible pre-2.0
|
|
14
|
+
results, explicitly select `'gaussian_spectral'` wherever Gaussian filtering was
|
|
15
|
+
previously used, including each Gaussian entry in hybrid kernel sequences.
|
|
16
|
+
Widths, coordinate conventions, and the public function signatures are unchanged.
|
|
17
|
+
|
|
18
|
+
### Breaking Changes
|
|
19
|
+
- Redefine `'gaussian'`, the default kernel, as the full normalized sampled
|
|
20
|
+
Gaussian rather than the exponential spectral response used in v1.0.0.
|
|
21
|
+
This affects existing smoothing/statistics calls even when `kernel_type`
|
|
22
|
+
is omitted. Use `'gaussian_spectral'` to retain the previous response.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- Make the default `'gaussian'` kernel the full normalized sampled Gaussian,
|
|
26
|
+
evaluated to floating-point precision without a fixed spatial truncation.
|
|
27
|
+
Cartesian, legacy polar, explicit N-D polar, both boundaries, normalized
|
|
28
|
+
moments, prefill, and fallback now share this nonnegative spatial kernel.
|
|
29
|
+
Numerical results change, particularly for widths near or below one grid cell.
|
|
30
|
+
- Preserve the previous exponential response as `'gaussian_spectral'` for
|
|
31
|
+
reproducing v1.0.0 Gaussian results, including per-axis hybrid selections.
|
|
32
|
+
Its spatial weights can be signed; it is not the default for statistics.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- Remove substantive negative raw variances caused by Gaussian spatial ringing.
|
|
36
|
+
The final variance clamp remains for floating-point cancellation. Positivity
|
|
37
|
+
requires nonnegative kernels on every selected axis; fractional analytical
|
|
38
|
+
boxcars and `'gaussian_spectral'` do not provide that guarantee.
|
|
39
|
+
- Evaluate broad sampled Gaussians with an equivalent frequency-alias sum,
|
|
40
|
+
avoiding allocations proportional to potentially enormous effective widths.
|
|
41
|
+
|
|
42
|
+
### Documentation
|
|
43
|
+
- Document sampled Gaussian normalization, numerical evaluation, narrow-width
|
|
44
|
+
behavior, statistical guarantees, and migration to `'gaussian_spectral'`.
|
|
45
|
+
- Clarify required N-D polar metadata, the default physical width units, and
|
|
46
|
+
coordinate dependencies; add a runnable coordinate-free grid-width example.
|
|
47
|
+
- Compare Cartesian and explicit polar N-D processing, including boundaries,
|
|
48
|
+
axis selection, and the conditions for equivalent finite-data smoothing.
|
|
49
|
+
- Explain input-NaN restoration and the low-level polar width argument in the README.
|
|
50
|
+
|
|
51
|
+
## [1.0.0] - 2026-10-26
|
|
52
|
+
|
|
53
|
+
Geometry-aware N-D polar release, preserving the v0.6.0 legacy 2D interface.
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
- Explicit N-D polar geometry through keyword-only `axis_types`, `axis_coords`,
|
|
57
|
+
`boundary`, `width_units`, `angle_units`, and `filter_axes` in `smooth_polar`,
|
|
58
|
+
forwarded by the smoothing wrapper and statistics with `coordinates='polar'`.
|
|
59
|
+
- Named azimuth/elevation/range axes in arbitrary array order, plus time, linear
|
|
60
|
+
(`cartesian` alias), and independent batch axes; per-axis widths, kernels,
|
|
61
|
+
boundaries, and physical/grid units follow array order.
|
|
62
|
+
- Physical angular widths use actual range and elevation geometry:
|
|
63
|
+
`L_az / (R*cos(elevation)*delta_az)` and `L_el / (R*delta_el)` in grid cells.
|
|
64
|
+
Regular coordinate validation rejects singular origins/poles and incomplete
|
|
65
|
+
non-singleton physical periodic azimuth grids rather than capping widths.
|
|
66
|
+
- Synthetic, plotting-free `examples/nd_polar.py` demonstrates a
|
|
67
|
+
`(time, elevation, azimuth, range)` field, missing data, mixed kernels/boundaries,
|
|
68
|
+
axis permutation, and isolation of unfiltered time slices.
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
- Explicit geometry uses canonical azimuth/elevation/range/time/linear filter
|
|
72
|
+
order independently of array storage order. The generally nonseparable,
|
|
73
|
+
noncommuting operator is not an exact isotropic or cell-volume convolution.
|
|
74
|
+
- Batch and unfiltered dimensions remain independent through smoothing,
|
|
75
|
+
normalized statistics, iterative filling, and every fallback. They do not
|
|
76
|
+
contribute nominal support area; wholly missing independent domains stay NaN.
|
|
77
|
+
- Documented `dct_count` as nominal weighted support, distinct from literal
|
|
78
|
+
neighbor counts and squared-weight statistical ESS, including repeated samples
|
|
79
|
+
at reflective/periodic boundaries.
|
|
80
|
+
|
|
81
|
+
### Documentation corrections
|
|
82
|
+
- Removed the additive-epsilon description: the normal public mean ratio uses
|
|
83
|
+
the full operator once on data and mask and requires a denominator strictly
|
|
84
|
+
greater than `1e-3`. Variance estimates both moments independently, including
|
|
85
|
+
separate fallback prefills of `x` and `x**2`, then clamps negative results.
|
|
86
|
+
- Qualified nonnegative-weight statistical guarantees: arbitrary fractional
|
|
87
|
+
spectral kernels need not have nonnegative spatial weights.
|
|
88
|
+
- Replaced the broken mathematical-guide link to the removed gap-filling basis
|
|
89
|
+
with research-internal module documentation, without adding a public export.
|
|
90
|
+
|
|
91
|
+
### Fixed
|
|
92
|
+
- Validate integer coordinate spacing before floating-point conversion, including
|
|
93
|
+
large time origins and overflow-safe signed/unsigned integer differences.
|
|
94
|
+
- Promote low-precision floating coordinates before spacing validation, avoiding
|
|
95
|
+
subtraction overflow and concealed irregular grids without downcasting wider types.
|
|
96
|
+
- Compute nominal support lazily with exponent scaling. An unrepresentable count
|
|
97
|
+
factor no longer prevents valid smoothing or normalized-moment computations;
|
|
98
|
+
individual effective widths remain validated.
|
|
99
|
+
- Remove array-layout bias from repeated time/linear-role fallback through joint
|
|
100
|
+
mixed-boundary nearest completion and symmetric averaging of exact global ties.
|
|
101
|
+
Legacy 2D axis-wise tie rules remain unchanged.
|
|
102
|
+
- Preserve zero-dimensional array outputs during count, variance, and standard
|
|
103
|
+
deviation mask restoration, consistently with smoothing and mean operations.
|
|
104
|
+
- Check installed runtime/distribution version alignment and run the suite against
|
|
105
|
+
the installed package in CI, including Python 3.8 with NumPy 1.20.0/SciPy 1.8.0.
|
|
106
|
+
- Document editable metadata refresh and the coordinated PyPI/conda-forge release
|
|
107
|
+
process, including checksums of the exact published source archive.
|
|
108
|
+
|
|
109
|
+
### Compatibility
|
|
110
|
+
- Existing `smooth_polar` positional arguments, the `width_pixels` name, and
|
|
111
|
+
positional `width` in high-level functions are unchanged.
|
|
112
|
+
- `axis_types=None` preserves the legacy 2D `(azimuth, range)` path, index-based
|
|
113
|
+
range convention, scalar/pair widths and kernels, and existing boundary rules.
|
|
114
|
+
Nondefault new geometry options require explicit `axis_types`; old widths are
|
|
115
|
+
not silently reinterpreted as physical distances.
|
|
116
|
+
|
|
8
117
|
## [0.6.0] - 2026-09-21
|
|
9
118
|
|
|
10
119
|
### Changed
|