diff --git a/CHANGELOG.md b/CHANGELOG.md index 691273a..39266e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,332 @@ All notable changes to cuPeriod are documented here. The format is based on ## [Unreleased] +## [1.2.0] - 2026-08-14 + +### Added + +- **SuperSmoother — a fully non-parametric period search** (`"SuperSmoother"`, + `cuperiod.SuperSmootherSettings`): Friedman's (1984) variable-span smoother + applied to every phase-fold — three local-linear smooths over span fractions + `(0.05, 0.2, 0.5)`, leave-one-out cross-validation picking the best span at each phase + point, and a final pass over the blended curve. The statistic follows gatspy, + `1 - mean|y - model|/dy / mean|y - mu|/dy`, the fractional reduction in mean absolute + (error-standardized) deviation about the inverse-variance weighted mean, *maximized* at + the true period (`1` a perfect fit, `0` no better than a constant, slightly negative + when the fold fits worse than the mean). Fitting the fold itself instead of a harmonic + model is the point: no harmonic budget to choose, and an RR Lyrae sawtooth, an eclipse, + or a shape nothing analytic describes are all captured — this was the period finder + behind the Stripe 82 RR Lyrae work (Sesar et al.) and one of the methods compared by + VanderPlas & Ivezić (2015). The price is cost and a soft spectrum, plus one caveat worth + stating plainly: a fold at an integer *multiple* of the true period is still a coherent + repeating curve, so `2P`, `3P`, … score nearly as high as `P` — read the shortest period + of a high-scoring family as the candidate, bound the trial periods from above by raising + `minimum_frequency` (the longest period searched is `1/minimum_frequency`), or let + `cuperiod.alias_diagnostics` arbitrate the family. +- **SuperSmoother on every backend.** One vectorized array-API kernel serves `numpy` on the + CPU, `cupy` on NVIDIA and `torch` on any device, alongside a numba-parallel CPU tier that + becomes the default with the `[fast]` extra: 20 000 trial frequencies on a 600-point + curve take **0.05 s** there against 6.6 s for plain numpy on the same 32-thread machine. + Every window sum comes from prefix sums over circularly padded folds, so the periodic + path is exact and the plain smoother's edge pathologies cannot arise, and the + leave-one-out span selection subtracts each point's own contribution rather than + refitting. float32 is available on cupy/torch, automatic only where the device forces it + (MPS). +- **Multi-band SuperSmoother** — gatspy's `SuperSmootherMultiband` exactly. Being + non-parametric there is no shared-phase model to pool into, so each band is smoothed + independently on the shared trial grid and the per-band scores are combined with + baseline-error weights `B_k = mean|y - mu_k|/dy`. `B_k` is the denominator of that band's + own score, which makes the combination the *total* fractional reduction in mean absolute + deviation across all bands: a flat or noisy band contributes little weight, and with one + band it collapses exactly to the single-band score. A band participates with at least 3 + finite points. Since nothing ties the bands' phases together, the GLS `"offsets"` model + remains the right tool for a sparse Rubin-cadence *search*; this one is for + characterizing an arbitrary fold shape when the bands are individually decent. +- **SuperSmoother is pinned against the reference implementations** — the `supersmoother` + package (VanderPlas) and `gatspy.periodic.SuperSmoother` / `SuperSmootherMultiband`, to + ~1e-9 in `tests/test_supersmoother.py` on the point counts where the window conventions + coincide; both join the `dev` extra as test-only pins (BSD-2-Clause). Four deviations + from the reference are deliberate and documented in the module: span windows are forced + to odd point counts (upstream master's fix of the released 0.4 truncation), folding is + always periodic, degenerate duplicate-phase windows fall back to the weighted mean + instead of raising, and the bass-enhancement factor is clamped to close the reference's + `alpha` ∈ (9, 10) NaN bug. Cross-backend parity (numba, torch, cupy against numpy) is + asserted at ~1e-11. +- **A native multi-band GLS, replacing the astropy delegation** on every backend + (finufft on the CPU, cufinufft on CUDA, torch on any device). Three joint models are + selected with `GLSSettings.mb_model`. The default `"offsets"` is the shared-phase + `(1, 0)` model of VanderPlas & Ivezić (2015) — one sinusoid on a phase shared by every + band plus an independent constant offset per band, their recommended search model for + sparse multi-band data. The offsets are profiled out in closed form, which leaves the + Zechmeister-Kürster assembly with every trigonometric sum replaced by its band-centered + counterpart and costs `K + 2` NUFFTs for `K` bands: on a six-band, 100-point star over + 200 000 frequencies, **55 s through astropy becomes 0.13 s** (~400×). With one band it + reduces exactly to single-band GLS. +- **`mb_model="perband"`** — the multi-phase `(0, 1)` model: independent per-band + floating-mean sinusoids combined with the paper's reference-chi-squared weights + (eq. 23), `P = sum_k chi2_0k P_k / sum_k chi2_0k`. astropy's `method="fast"` intends + this model but weighs the bands by the summed *squared periodogram* instead of + `chi2_0k`, which makes its output depend on the frequency grid it was evaluated on; + that differs from the published weighting. gatspy uses `chi2_0k`, and so does cuPeriod. +- **`mb_model="flex"`** — astropy's flexible regularized model (`mb_nterms_base` shared + harmonics plus `mb_nterms_band` harmonics-with-offset per band, trace-scaled ridge + `mb_reg_band=1e-6` on the band columns), reproduced from per-band harmonic trig sums + and batched normal-equation solves. Parity with astropy is ~2e-10 across term counts + and under both ridge conventions (`tests/test_multiband_gls.py`). +- **Multi-band false-alarm probabilities** (`cuperiod.multiband_fap`), which + astropy's `LombScargleMultiband` does not offer at all — its FAP methods raise + `NotImplementedError`, because the single-band analytic formulas assume one sinusoid fit + to one band. cuPeriod calibrates the joint periodogram by within-band bootstrap: each + band's `(value, error)` pairs are resampled with replacement while every observation + *time* stays fixed, which preserves the window function, the per-band sample sizes and + the heteroskedastic errors while destroying phase coherence. `MultibandFAP` carries the + null sample with `.fap(power)` and `.level(fap)`; `GLSSettings(mb_fap_bootstrap=N)` + attaches `extras["fap"]` at the spectrum's peaks plus `meta["fap_level_10pct"]` / + `fap_level_1pct`. On the NUFFT backends the whole bootstrap runs as the *same* `K + 2` + transforms as one power evaluation, with the resamples stacked along `n_trans`; the + perband/flex models and torch fall back to a per-resample loop. The smallest resolvable + false-alarm probability is `1/(n_bootstrap + 1)`, and asking for less raises. +- **Every method is now multi-band** — pooled PDM, conditional entropy, and string length + join the existing MHAOV (pooled `F`) and BLS (shared ephemeris, stacked depth-SNR); only + TLS remains single-band. Each band keeps its own mean curve, histogram, and + normalization, and only the resulting statistics are pooled: PDM by within-bin degrees + of freedom `max(n_k - n_bins, 1)`, CE and string length by point count. Forcing the + filters onto one common fold would smear it by the band offsets alone and look + disordered at *every* trial period. +- **Multi-band ingestion everywhere a light curve loads.** + `MultiBandLightCurve.from_file` reads a long-format CSV/ECSV/FITS/Parquet table and + splits it on an auto-detected or named band column, with no pandas dependency. The CLI's + `cuperiod run FILE --band COL` now performs a true joint fit — it silently dropped to + single-band before — and `batch_periodograms` honors `band_column` for file, glob, and + directory inputs, so a directory of survey tables runs multi-band end to end. +- **Alias diagnostics for any periodogram** (`cuperiod.alias_diagnostics`). A peak + quoted without an alias check is a period a referee will ask about, so this measures the + spectral window of *this* light curve's sampling, predicts the alias family it implies + (`f0 ± m·f_w` off the window's own peaks, plus harmonics and subharmonics; the classic + sidereal-day/solar-day/synodic-month/year suspects when no light curve is supplied), + matches each prediction to a local optimum of the periodogram within a Rayleigh + tolerance, and scores the competitors on one scale where `1.0` means "as good as the + peak being diagnosed". Harmonics are reported but never make a result `ambiguous`, since + `2f` is expected structure. Works for maximized and minimized statistics alike and for + multi-band input; `AliasReport.summary()` prints the competitor table a period-search + paper is expected to show. +- **LINCC Frameworks interoperability** (`cuperiod.interop`, new `[nested]` and `[lsdb]` + extras): run a period search directly on nested-pandas / lsdb light curves — one row per + object, the epochs in a nested column — with no flattening, no `groupby`, and no + per-object DataFrames. `cuperiod.interop.nested_periodogram` is the row-wise tier + (`map_rows`, composable, right for a CPU backend or a quick look); + `cuperiod.interop.partition_periodogram` is the throughput tier, reading a + partition's flat Arrow buffers and list offsets once and evaluating every object in it + against **one** GPU engine, so plan/kernel setup is amortized over thousands of stars + instead of paid per star. Both accept an in-memory `NestedFrame` or a lazy lsdb + `Catalog`, resolve their columns from the nest's schema without computing, and turn a + failed object into NaN result columns rather than an aborted run. `COLUMN_PRESETS` + carries verified layouts for `"ztf_dr22"`, `"ztf_alerts"`, `"rubin_dp1_object"` and + `"rubin_dp1_dia"`; the Rubin presets search in the **flux** domain because DP1 fluxes + are nJy and can legitimately be negative. One code path supports both ecosystem worlds — + nested-pandas 0.6.10 (the lsdb / pandas-2 pin) and 0.7.x (pandas 3) — using only + `map_rows` / `map_partitions` / `join_nested`, never the `reduce` that 0.7.0 removed. +- **A multi-band recovery benchmark** (`benchmarks/multiband_recovery.py`): faint + RRab-like stars on a simulated Rubin-like six-band cadence (3-year span, WFD epoch + shares, 0.20 mag per-point noise ≈ an *r* ≈ 23 halo RR Lyrae), 300 stars per cell, + recovery = top period within 1% with no harmonic credit. At 30 total epochs across all + six bands the best single band recovers 0.0% and any-single-band 0.0%, while multi-band + `perband` reaches 17.7%, `flex` 20.0%, and the shared-phase `offsets` model **81.7%**; + at 60 epochs, 37.3% / 49.3% versus 97.0% / 97.0% / **99.7%**; by 120 epochs everything + converges. The cadence is deliberately simplified (random nights, no rolling cadence), + so the result to read is the *ordering*: sharing the phase is what buys sparse-cadence + recovery, consistent with Rubin's own alert-production study and with VanderPlas & + Ivezić (2015) — and it is why `"offsets"` is the default. +- **A bundled real multi-band validation set** (`benchmarks/dataset/s82_rrlyrae.parquet`, + built by the re-runnable `benchmarks/dataset/download_s82_rrlyrae.py`): 100 SDSS Stripe 82 + RR Lyrae from Sesar et al. 2010 (ApJ 708, 717) — real *ugriz* photometry on the real + ground-based cadence, ~55 epochs per band over a ~3200 d baseline, 80 RRab and 20 RRc with + periods 0.26–0.91 d, each carrying the discovery paper's literature period. It is the + canonical real multi-band test set: VanderPlas & Ivezić (2015) developed the multiband + periodogram on these very stars. The script fetches the paper's tables from the astroML-data + mirror (the original MPIA host is dead) and keeps the first 100 stars by ascending Sesar ID, + a deterministic cut with no quality selection and no filtering on how any method performs. + At ~390 KB the bundle is committed, so the validation reproduces offline. +- **Every multi-band method validated on that real data** (`benchmarks/multiband_real.py`, + written up as a new REPORT.md §4): one identical blind search per star — periods 0.15–1.2 d + at 5 samples per Rayleigh width (~97 000 trial frequencies), every method at its default + settings — scored **strict** (top period within 1% of the literature value, no harmonic + credit) and **harmonic-aware** (a small-integer harmonic within 2%). The pooled fold + statistics lead on curves this well sampled: PDM and string length reach **93%** strict, + with string length at **97%** harmonic-aware and SuperSmoother at **96%**, against 76–78% + for the three GLS models — about what the best single band manages (78%, or 92% if any of + the five bands is allowed to be the right one). That is the mirror image of the simulated + sparse-cadence benchmark above, where `"offsets"` leads: dense per-band data reward fold + shape, sparse data reward parsimony. SuperSmoother's strict-vs-harmonic gap is exactly the + documented integer-multiples family (11 of 21 fold-family harmonic picks land on precisely + 2P; 55% strict on the near-sinusoidal RRc against 92.5% on RRab), and 54% of the 163 + non-harmonic misses across all models sit on the ±1 or ±2 cycle/day window-alias loci — the + ground-based window function, not noise. BLS is reported for completeness (22%) and stays + the wrong tool for a pulsator. +- **Automated, uncertainty-aware pre-whitening for classical pulsators** + (`cuperiod.prewhiten`). Frequency analysis of δ Scuti, γ Doradus and SPB stars + has funnelled through interactive Period04-style sessions one star at a time; this + runs the whole loop — amplitude spectrum, peak selection, simultaneous non-linear + re-fit of every component, significance test — end to end, and makes every judgement + call an explicit, recorded setting. A `PreWhitenResult` carries the ranked components + with their uncertainties, the residuals and their spectrum, the fit statistics, and + the reason the run stopped. +- **A batch-capable GPU/NUFFT amplitude spectrum** (`cuperiod.amplitude_spectrum`, + `SpectrumEngine`) on the cufinufft / finufft / torch / numpy backends. The terms of + the least-squares normal equations that depend only on the observation times are + computed once and cached, so each pre-whitening iteration costs a *single* transform: + a 50-frequency solution needs ~52 transforms rather than ~150. A 20 000-point TESS + sector with 15 modes takes about a second on a laptop CPU. +- **Principled stopping criteria**, combinable and always reported in `stop_reason`: + the Breger et al. (1993) signal-to-noise ratio, the Baluev false-alarm probability, + a ΔBIC improvement threshold, and an absolute amplitude floor. After the final + simultaneous polish the solution is re-checked and components that no longer pass are + pruned — the re-check is the S/N test, so it runs when `"snr"` is among the criteria, + and every reported frequency then satisfies it. +- **Error propagation** with three estimators (`uncertainty=`): the linearised + least-squares covariance of the joint fit (the default, and the only one that accounts + for correlations between close frequencies), the classical Montgomery & O'Donoghue + (1999) formulae, and a residual bootstrap. All optionally inflated by the + Schwarzenberg-Czerny (1991) correlation factor. Phases are referenced to the weighted + mean epoch, at which a phase is uncorrelated with its own frequency — validated + against Monte Carlo: reported 1-sigma errors match the realised scatter to within + ~5% in frequency, amplitude, and phase. +- **Combination-frequency identification** + (`cuperiod.identify_combinations`) with uncertainty-aware tolerances — a match + must fall within `max(3σ, 0.25/T)` of the *propagated* prediction — and a + chance-coincidence rate reported per identification, so a spurious match is visible as + such. `PreWhitenResult.independent()` returns the candidate independent-mode list. +- **g-mode period-spacing tools**: a comb scan over trial spacings + (`cuperiod.spacing_spectrum`, unaffected by missing radial orders, and immune to + the sub-multiple ambiguity that makes a naive scan report ΔΠ/2), extraction of the + longest *tilted* series `ΔP(P) = a + bP` bridging missing orders + (`cuperiod.find_period_spacing`), échelle coordinates + (`cuperiod.echelle`), and the buoyancy radius Π₀ + (`cuperiod.buoyancy_radius`). +- **Batch pre-whitening** (`cuperiod.batch_prewhiten`) over the existing CPU/GPU + worker pools, writing one row per extracted component to Parquet/CSV with resumable + directory sinks. +- **CLI**: `cuperiod prewhiten` (with `--spacing`, JSON/CSV/npz output) and + `cuperiod batch-prewhiten`. +- **The spectral window as a first-class diagnostic**: `SpectrumEngine.window()`, + `cuperiod.spectral_window`, and `PreWhitenResult.window` expose `|W(f)|` of the + sampling — the alias-lobe pattern every real peak is convolved with — at zero extra + transforms (its sums are already part of the cached normal equations). The GUI + spectrum view gains a *window* overlay toggle (scaled to the tallest peak, + Period04-style) and `cuperiod prewhiten --save-spectrum` writes it into the `.npz`. +- **GUI: the data curve has its own toggle**, so the residual and window traces it + draws over can be read on their own, and **double-clicking the spectrum restores the + default view** (what the *Reset* button does). The *peaks* toggle now also hides the + shaded selection band — it marks a peak, so it belongs to the same layer — while + keeping the selection itself, so the folded period does not change underneath you. +- **An amplitude-reliability flag.** Every component now records + `spectrum_amplitude` — the amplitude spectrum read directly at its frequency, a + single-frequency measurement independent of the joint fit — alongside the derived + `amplitude_ratio` and a `blended` flag (`blend_tolerance`, default 2×). A ratio far + from 1 says the amplitude is entangled with a component it is correlated with, which + in ground-based data usually means the mode's own alias sidelobe: on the bundled + ASAS-SN HADS demo the 3f harmonic is fitted at nearly twice what the data holds + there. It is explicitly *not* a significance test — a blended component can be real — + and nothing is dropped because of it. `PreWhitenResult.n_blended` counts them, + `summary()` gains an `A/Asp` column, the batch catalogue gains both floats, and the + GUI's Frequencies dock marks the affected rows. +- **A native Baluev (2008) false-alarm probability** (`cuperiod.baluev_fap`) + matching astropy's `false_alarm_probability(method="baluev")` to machine precision on + centred times — and staying accurate on raw Julian dates, where the one-pass time + variance loses ~11 digits. Pre-whitening no longer imports `astropy.timeseries`, + which was ~1 s of first-solution latency in the CLI/GUI and per batch worker. +- **GUI**: an **Analysis** picker switches the desktop app between *Periodogram* and + *Pre-whitening* without disturbing anything else — same inputs, same spectrum, phased + and raw views, same source browser, same off-thread compute and result caching. In + pre-whitening mode the spectrum shows the amplitude spectrum with the residual + spectrum overlaid and the components marked, a **Frequencies** dock lists them with + uncertainties and S/N (click to fold, right-click to export), and a **Period spacing** + dock scans for a regular spacing and draws the échelle diagram. The settings form is + generated from `PreWhitenSettings` by the existing machinery, so every knob is exposed + with no bespoke widgets. + +### Performance + +- **The GPU plan cache is now reused for multi-band periodograms too.** The batch runner + and the interop partition kernel built a `CufinufftGLS` engine per worker/partition but + dropped it on the multi-band branch, so every star paid full plan setup again. + `multiband_power` accepts the same engine the single-band path uses, and the `"offsets"` + model's `K + 2` transforms, the flex harmonic sums, and the perband per-band powers all + route through its bucketed plan cache — a plan is fixed by mode count and `n_trans` + alone, so one pair serves every band, harmonic, and star in a partition. The + bootstrap-FAP pass deliberately stays planless: its `n_trans` varies with the grid, and + caching a plan per value would balloon device memory. The fold methods accept and ignore + the parameter; their kernels are already module-cached. +- **Single-shot GPU calls of MHAOV and SuperSmoother no longer pay per-chunk dispatch + overhead.** Both kernels walked the trial grid in small fixed chunks (512/1024), and on + a ~100k-frequency grid the hundreds of chunk iterations — each a burst of kernel + launches, for SuperSmoother plus a device→host copy that synchronized the stream every + chunk — dominated the wall clock: on the Stripe 82 validation stars a single multi-band + call took ~24 s on GPU against ~0.3–0.5 s on the numba CPU tier. `batch_periods` now + defaults to `0` = auto-sized from a transient-memory budget (`~512 MiB` of workspaces + on device backends, the previous chunk sizes on host numpy, always adapted to the + light-curve length so long curves cannot blow memory), and SuperSmoother accumulates + scores on the device and crosses to the host once. Chunking never affects the result — + the same stars now run at CPU-tier speed on the GPU (MHAOV ~0.5 s, SuperSmoother + ~0.8 s single-shot; identical spectra). An explicit `batch_periods` value is honored + as before. The single-curve benchmark sweep was re-measured under the new defaults + (single-band MHAOV GPU 0.135 s → 0.038 s, from ~5× slower than the numba CPU tier to a + near-wash across the whole grid-size sweep), and SuperSmoother joined the sweep with + its first recorded single-curve and scaling numbers. + +- `cuperiod.gui.models.ResultCache` is now generic over its value type, so the app keeps + one cache per analysis and switching back and forth is instant. +- `batch_prewhiten` forces `store_spectra=False`: catalogue rows never carry spectra, + so keeping them only made each worker hold megabytes of grid arrays per star. + +### Fixed + +- **The automatic pre-whitening band could sit entirely below a δ Scuti star.** The + default topped out at the median-gap pseudo-Nyquist (with `nyquist_factor=1`), which + for nightly ground-based sampling is ~0.5–2.5 cycles/day — so on the bundled ASAS-SN + HADS demo (P = 0.0898 d, f = 11.14 c/d) the extraction fitted a spurious low-frequency + solution instead (P = 9.00 d, residual rms 0.245), while the GUI — whose own ceiling + was 10 c/d — fitted the signal's daily alias (P = 0.123 d). The auto band is now + `max(pseudo-Nyquist × nyquist_factor, 50 c/d)` with `nyquist_factor=5` (matching the + periodogram methods), exposed as + `cuperiod.prewhiten.default_maximum_frequency`, and the GUI's auto value uses + the same helper. The demo star now yields P = 0.089757 d — the VSX period to the + last digit — with its 2f, 3f, 4f harmonics extracted and combination-labelled + (residual rms 0.073). The GUI applies the same floor to the **GLS and MHAOV** + periodograms — a trial frequency costs them a trig sum, so the wider band is free — + and GLS now also recovers the demo star's period; the fold-based methods (PDM, CE, + string-length), which pay a full fold per trial frequency, keep their 10 c/d auto + ceiling. +- **`MultiBandLightCurve.from_dataframe` ignored `band_column` when `columns=` was also + given.** An explicit `ColumnMap` replaced the map built from `band_column` outright, so + `from_dataframe(df, band_column="filter", columns=ColumnMap(time=..., value=...))` + raised `ColumnResolutionError` telling the caller to pass `band_column` — which they + had. The two are now merged, matching `from_file`. +- **GUI: hiding the peaks left their hover label behind.** The label is anchored to a + marker, but nothing dismissed it when the markers went away — so unchecking *peaks* + right after hovering one to read it (the natural order) stranded the numbers over an + empty plot, and the same label survived a new result and axis/log switches that moved + its anchor. It is now dismissed whenever the markers are redrawn, and reappears on + the next hover. +- **GUI: the Frequencies table ignored its own number formats.** The sort key was + written to `EditRole`, which `QTableWidgetItem` stores in the same slot as + `DisplayRole`, so every numeric column silently rendered Qt's six-significant-digit + default — too few digits for a frequency (`11.1412` where the solution knows + `11.1412066`) and too many for an uncertainty. The sort key now lives on the item. +- **GUI: component markers floated above the amplitude spectrum.** They were drawn at + each component's *fitted* amplitude while the curve shows the single-frequency + amplitude spectrum. Those agree for a well-separated mode but diverge as soon as + components are correlated — on the bundled HADS demo, whose harmonics each carry + yearly alias sidelobes (Δf = 1/365.25 d), the two differ by up to a factor of 4.6 — + so markers hung in empty space claiming peaks the spectrum does not have. Markers + now sit at the height of the curve they annotate; the fitted amplitude and S/N moved + to the hover readout, alongside the Frequencies dock that already reported them. +- **Bootstrap frequency errors were exactly zero for every component but the newest.** + The engine handed its per-iteration refinement policy (default `"last"`, which pins + all established frequencies) to the bootstrap's replicate fits, so their scatter + collapsed. Replicates now always sweep every frequency, boxed by the same + per-frequency bounds as the fit they characterise. + ## [1.1.0] - 2026-07-08 ### Performance @@ -191,5 +517,6 @@ First public release. parity, on 72 real ASAS-SN light curves across six variability classes and on confirmed Kepler transits. +[1.2.0]: https://github.com/tjayasinghe/cuPeriod/compare/v1.1.0...v1.2.0 [1.1.0]: https://github.com/tjayasinghe/cuPeriod/compare/v1.0.0...v1.1.0 [1.0.0]: https://github.com/tjayasinghe/cuPeriod/releases/tag/v1.0.0 diff --git a/CITATION.cff b/CITATION.cff index f2442be..da990e8 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -2,21 +2,23 @@ cff-version: 1.2.0 message: "If you use cuPeriod in your research, please cite it as below." title: cuPeriod abstract: >- - Optimized, GPU-accelerated periodograms for astronomy: seven period-search methods - (GLS, BLS, PDM, CE, String-Length, MHAOV, TLS) with fast CPU and CUDA backends, scaling - from a single light curve to millions. A portable PyTorch backend extends GPU + Optimized, GPU-accelerated periodograms for astronomy: eight period-search methods (GLS, + BLS, PDM, CE, String-Length, MHAOV, TLS, SuperSmoother) with fast CPU and CUDA backends, + scaling from a single light curve to millions. A portable PyTorch backend extends GPU acceleration beyond NVIDIA to AMD (ROCm), Intel (XPU), and Apple (MPS) hardware, and a multi-threaded numba CPU tier gives every method a fast backend even without a GPU. An optional PySide6 desktop GUI provides an interactive periodogram explorer over the same - API. + API. For classical pulsators it also performs automated, uncertainty-aware + pre-whitening: iterative sinusoid extraction with principled stopping criteria, error + propagation, combination-frequency identification, and g-mode period-spacing tools. type: software authors: - given-names: Tharindu family-names: Jayasinghe # Add your ORCID here to make the citation unambiguous, e.g.: # orcid: "https://orcid.org/0000-0000-0000-0000" -version: 1.1.0 -date-released: "2026-07-08" +version: 1.2.0 +date-released: "2026-08-14" license: GPL-3.0-or-later repository-code: "https://github.com/tjayasinghe/cuPeriod" url: "https://cuperiod.readthedocs.io" diff --git a/README.md b/README.md index c1ca722..30d3294 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ fast CPU backends and GPU-accelerated paths that scale from a single light curve millions. The NVIDIA CUDA fast paths are joined by a portable **PyTorch** backend that also runs on AMD, Intel, and Apple GPUs (and a CPU-only path), so the accelerated code is no longer NVIDIA-only. One API, one CLI, and an optional desktop GUI cover every method, with -frictionless column handling, multi-band support, raw-spectrum output, and an -N-best-periods utility. +frictionless column handling, joint multi-band search, alias diagnostics, raw-spectrum +output, and an N-best-periods utility. 📖 **Documentation:** — a [5-minute quickstart](https://cuperiod.readthedocs.io/en/latest/quickstart.html), a full user guide, @@ -31,26 +31,50 @@ Every implementation is validated against the standard reference (astropy - **Validated, not just fast.** GLS and BLS match astropy to floating-point round-off, and every other method is checked against an independent reference implementation - (PyAstronomy, or a direct implementation of the published algorithm) on identical - grids. CPU, CUDA, and the portable PyTorch backend agree to round-off and pick the + (PyAstronomy, the `supersmoother` package and gatspy, or a direct implementation of the + published algorithm) on identical grids. Across the seven benchmark-suite methods, CPU, + CUDA, and the portable PyTorch backend agree to round-off and pick the identical best period on 126 real ASAS-SN light curves across six variability classes plus 12 confirmed *Kepler* transits — 88–96% harmonic-aware period recovery on this deliberately heterogeneous sample (a synthetic injection–recovery sweep further characterizes sensitivity vs. signal-to-noise) — see the [full benchmark report](benchmarks/REPORT.md) and the - [benchmarks docs page](https://cuperiod.readthedocs.io/en/latest/benchmarks.html). + [benchmarks docs page](https://cuperiod.readthedocs.io/en/latest/benchmarks.html). The + multi-band methods are further validated blind on 100 real SDSS Stripe 82 RR Lyrae with + literature periods — the pooled fold statistics recover up to 93% of periods strictly + (97% harmonic-aware) on real five-band data. - **A fast CPU tier, no GPU required.** The `[fast]` extra's multicore `numba` kernels - make `backend="cpu"` 18x faster than astropy's `BoxLeastSquares` and 2106x faster than + make `backend="cpu"` 20x faster than astropy's `BoxLeastSquares` and 2177x faster than PyAstronomy's PDM on a representative light curve, while recovering the same periods. - **GPU acceleration beyond NVIDIA.** The portable PyTorch backend runs every method on AMD (ROCm), Intel (XPU), and Apple (MPS) GPUs, in addition to the NVIDIA CUDA fast paths — so the accelerated code isn't locked to one vendor. -- **Built for catalogue scale.** `batch_periodograms` sustains up to 587 light curves/s +- **Built for catalogue scale.** `batch_periodograms` sustains up to 574 light curves/s (>2 million/hour) on a single GPU, with a resumable batch sink for runs spanning millions of curves. -- **Seven methods, one API.** GLS, BLS, PDM, CE, String-Length, MHAOV, and TLS share one - entry point, one CLI, and an optional desktop GUI, with frictionless column handling and - multi-band support. +- **Eight methods, one API.** GLS, BLS, PDM, CE, String-Length, MHAOV, TLS, and + SuperSmoother share one entry point, one CLI, and an optional desktop GUI, with + frictionless column handling. +- **Multi-band search that earns its keep.** Seven of the eight methods fit several filters + of one star jointly. The native multi-band GLS offers three models — shared-phase + offsets (the default), independent per-band sinusoids, and a regularized per-band + harmonic model — runs on every backend (a six-band star over 200k frequencies: 55 s + through astropy, **0.13 s** native), and comes with **bootstrap false-alarm + probabilities**, which astropy's `LombScargleMultiband` does not provide at all. On a + simulated Rubin-like cadence with 30 epochs spread over six bands, single-band GLS + recovers 0% of faint RRab proxies and the shared-phase model recovers **82%**. +- **Survey catalogues, in place.** `cuperiod.interop` runs a search directly over LINCC + nested-pandas / lsdb light curves — one row per object, epochs in a nested column — with + no flattening or `groupby`. A partition tier reuses **one GPU engine** across every + object in a dask partition, with verified column presets for ZTF and Rubin DP1. +- **Alias-checked periods.** `alias_diagnostics` measures the sampling's spectral window, + predicts the alias family it implies, scores each competitor against the peak you got, + and says plainly when the period is ambiguous. +- **Pulsators get a frequency solution, not just a period.** `prewhiten` automates the + whole Period04-style loop — GPU/NUFFT amplitude spectrum, iterative sinusoid extraction, + simultaneous re-fitting, principled stopping criteria, propagated uncertainties, + combination-frequency identification, and g-mode period-spacing tools — for one star or + a million. ## Status @@ -62,11 +86,12 @@ Implemented now, each with optimized CPU and GPU backends: | **BLS** | eclipses / box-like transits | yes | yes | | **MHAOV** | sharply non-sinusoidal signals (multiharmonic AOV) | yes | yes | | **TLS** | limb-darkened transit matched filter | yes | — | -| **PDM** | non-sinusoidal folds (Stellingwerf) | yes | — | -| **CE** | sparse survey data (conditional entropy) | yes | — | -| **String-Length** | eclipsing / eccentric shapes | yes | — | +| **PDM** | non-sinusoidal folds (Stellingwerf) | yes | yes | +| **CE** | sparse survey data (conditional entropy) | yes | yes | +| **String-Length** | eclipsing / eccentric shapes | yes | yes | +| **SuperSmoother** | any repeating shape, non-parametric (Friedman) | yes | yes | -All seven methods have CPU and GPU backends, plus the full single/batch/CLI machinery. +All eight methods have CPU and GPU backends, plus the full single/batch/CLI machinery. ## Install @@ -74,9 +99,11 @@ All seven methods have CPU and GPU backends, plus the full single/batch/CLI mach pip install cuperiod # CPU (numpy, scipy, astropy, finufft) pip install "cuperiod[gpu]" # + CUDA 12 GPU backends (cupy, cufinufft) pip install "cuperiod[torch]" # + portable PyTorch backend (AMD/Intel/Apple GPUs + CPU) -pip install "cuperiod[fast]" # + numba multicore CPU kernels (all 7 methods, 20-300x) +pip install "cuperiod[fast]" # + numba multicore CPU kernels (7 methods, no GLS, 20-300x) pip install "cuperiod[gui]" # + interactive desktop GUI (cuperiod-gui) pip install "cuperiod[pandas]" # + pandas DataFrame ingestion +pip install "cuperiod[nested]" # + nested-pandas light curves (cuperiod.interop) +pip install "cuperiod[lsdb]" # + lsdb HATS catalogs (lazy, dask-partitioned) ``` The `[gpu]` extra needs an NVIDIA GPU with the CUDA 12 runtime; it pulls in `cupy-cuda12x`, @@ -85,9 +112,9 @@ backend that reaches AMD (ROCm), Intel (XPU), and Apple-Silicon (MPS) GPUs — a everywhere — so the accelerated code runs beyond NVIDIA (install the wheel matching your accelerator from [pytorch.org](https://pytorch.org/get-started/locally/); the default is CPU-only). The `[fast]` extra adds multicore `numba` CPU kernels that become the default -`"cpu"`/`"auto"` backend for **every** method — BLS, PDM, CE, String-Length, MHAOV, and -TLS — one to two orders of magnitude faster than the fallback CPU paths and matching them -to floating point. +`"cpu"`/`"auto"` backend for **every method but GLS** — BLS, PDM, CE, String-Length, +MHAOV, TLS, and SuperSmoother — one to two orders of magnitude faster than the fallback +CPU paths and matching them to floating point. Not sure what will run where? `cuperiod doctor` reports every installed backend, the torch devices it sees and the precision each uses, and what `backend="auto"` resolves to. @@ -125,13 +152,63 @@ Method names are case-insensitive (`"gls"` == `"GLS"`). ### Multi-band (one star, several filters) -GLS, BLS, and MHAOV jointly model two or more bands of the same star: +GLS, BLS, MHAOV, PDM, CE, String-Length, and SuperSmoother jointly model two or more bands +of the same star — one period, but each band keeps its own mean, amplitude, and +normalization: ```python mb = cup.MultiBandLightCurve.from_light_curves({"g": lc_g, "r": lc_r}) pg = cup.periodogram(mb, "GLS") # VanderPlas & Ivezić shared-phase model + +# ...or straight from a long-format file / the CLI / batch: +mb = cup.MultiBandLightCurve.from_file("star_ugrizy.parquet", band_column="band") + +# One of three joint models (offsets / perband / flex): +settings = cup.GLSSettings(mb_model="flex") +pg = cup.periodogram(mb, "GLS", settings=settings) + +# Honest false-alarm probabilities, from a within-band bootstrap: +calib = cup.multiband_fap(mb, settings, n_bootstrap=1000) +print(calib.fap(pg.best_periods(1)[0].power), calib.level(0.01)) ``` +`mb_model` is `"offsets"` (shared phase + per-band offsets, the default), `"perband"` +(independent per-band sinusoids, `chi2_0`-weighted), or `"flex"` (regularized per-band +harmonics, matching astropy to ~2e-10). All three run natively on finufft, cufinufft, and +torch — astropy is kept only as the reference they're tested against. + +Period recovery on a simulated Rubin-like six-band cadence +(`benchmarks/multiband_recovery.py`; faint RRab proxies, 0.20 mag per-point noise, 300 +stars per cell, top period within 1% and no harmonic credit), by *total* epochs across all +six bands: + +| strategy | 30 epochs | 60 epochs | 120 epochs | +| --- | --- | --- | --- | +| best single band (r) | 0.0% | 37.3% | 97.3% | +| any single band | 0.0% | 49.3% | 99.0% | +| multi-band `offsets` (1,0) | **81.7%** | **99.7%** | 100.0% | + +`perband` and `flex` land in between (17.7% / 20.0% at 30 epochs, 97.0% at 60): sharing +the phase is what buys sparse-cadence recovery, which is why `"offsets"` is the default. +These are simulations on a deliberately simplified cadence (random nights, no rolling +cadence) — read the ordering, not the absolute numbers. See the +[multi-band guide](https://cuperiod.readthedocs.io/en/latest/guide/multiband.html). + +### Survey catalogs (LINCC: nested-pandas / lsdb) + +```python +from cuperiod.interop import nested_periodogram, partition_periodogram + +out = nested_periodogram(frame, "lc", preset="ztf_dr22") # row-wise +res = partition_periodogram(cat, preset="rubin_dp1_object", # one GPU engine + method="GLS", backend="gpu") # per partition +``` + +Runs on the nested layout directly — no flattening, no `groupby`. Column presets for ZTF +DR22, ZTF alerts, and Rubin DP1 object/DIA photometry; a failed object yields NaN rather +than aborting the run. See the +[interop guide](https://cuperiod.readthedocs.io/en/latest/guide/interop.html). + ### Backends `backend="auto"` (default) uses the GPU when available and falls back to CPU. Force a path @@ -141,6 +218,25 @@ device: `backend="torch"` (best device present) or `"torch:cpu"` / `"torch:cuda" `"torch:mps"` / `"torch:xpu"`. On Apple MPS (no float64) it uses float32; `precision="auto"` keeps float64 everywhere else. +## Pre-whitening a pulsator + +```python +solution = cup.prewhiten((time, mag, mag_err)) +print(solution.summary()) # ranked frequencies with 1-sigma uncertainties and S/N + +for c in solution.components: + print(c.label, c.frequency, c.frequency_error, c.snr, c.combination) + +series = cup.find_period_spacing( # gamma Dor / SPB g-mode pattern + [c.period for c in solution.independent()], + [c.amplitude for c in solution.independent()], +) +``` + +Every judgement call an interactive session leaves to the operator is an explicit setting, +and the result records **why the extraction stopped**. See the +[pre-whitening guide](https://cuperiod.readthedocs.io/en/latest/guide/prewhitening.html). + ## Batch processing (millions of light curves) ```python @@ -162,29 +258,37 @@ written. `suggest_gpu_workers` sizes the GPU pool from probed device memory. ```bash cuperiod run star.csv --method GLS,BLS --n-best 10 cuperiod batch "lcs/*.csv" --method GLS --device gpu --out results/ +cuperiod prewhiten star.csv --snr 4.6 -n 30 --spacing +cuperiod batch-prewhiten "lcs/*.csv" --out modes.parquet cuperiod methods # list methods and backends cuperiod gpu-info # device + suggested worker counts cuperiod doctor # backends, torch devices, precision, auto-resolution cuperiod grid-info star.fits -m GLS ``` -`run` accepts `--time/--value/--error/--band` overrides and `--domain magnitude|flux`, and -can write JSON (`--out`) and the raw spectrum (`--save-periodogram`). +`run` accepts `--time/--value/--error` column overrides and `--domain magnitude|flux`, and +can write JSON (`--out`) and the raw spectrum (`--save-periodogram`). `--band` splits a +long-format file on its filter column and runs a **joint** multi-band fit; the Python API's +`batch_periodograms(..., band_column=...)` takes the same (the `batch` command has no band +option yet). ## Desktop GUI -An interactive periodogram explorer ships with the `[gui]` extra — run any method with all -of its options, explore the full-resolution spectrum, and watch the phased light curve -update live as you drag across peaks. Single curves or a whole folder in batch mode, -multi-band overlays, and a dark/light theme remembered across launches. +An interactive explorer ships with the `[gui]` extra — run any method with all of its +options, explore the full-resolution spectrum, and watch the phased light curve update +live as you drag across peaks. Single curves or a whole folder in batch mode, multi-band +overlays, and a dark/light theme remembered across launches. An **Analysis** picker +switches the same window to pre-whitening: the amplitude spectrum with the residual +overlaid, a frequency table with uncertainties, and a g-mode period-spacing explorer. ```bash pip install "cuperiod[gui]" # add [gpu] or [torch] for accelerated backends cuperiod-gui # or: python -m cuperiod.gui ``` -It opens with bundled demo light curves (a *Kepler* transit, six ASAS-SN variables, a -synthetic multi-band curve), so there's something to explore on first launch. +The toolbar's **Load demo** menu always offers a synthetic multi-band curve, so there's +something to explore on first launch. In a source checkout (or with `CUPERIOD_EXAMPLE_DATA` +pointed at `examples/data`) it also lists a *Kepler* transit and six ASAS-SN variables. ## Light-curve inputs @@ -201,8 +305,8 @@ for the machine-readable record (also picked up by GitHub's "Cite this repositor @software{jayasinghe_cuperiod, author = {Jayasinghe, Tharindu}, title = {cuPeriod}, - version = {1.1.0}, - date = {2026-07-08}, + version = {1.2.0}, + date = {2026-08-14}, url = {https://github.com/tjayasinghe/cuPeriod} } ``` diff --git a/benchmarks/README.md b/benchmarks/README.md index 7cffee6..7e8d177 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -1,11 +1,16 @@ # cuPeriod validation & benchmark suite -Reproducible validation and performance benchmarks for every cuPeriod method on -**real survey data**, comparing the CPU and GPU backends against each other and -against established third-party implementations. +Reproducible validation and performance benchmarks for cuPeriod's period-search +methods on **real survey data**, comparing the CPU and GPU backends against each +other and against established third-party implementations. The rendered results are in **[REPORT.md](REPORT.md)** with figures in `figures/`. +The single-band *validation* sections cover seven methods; the performance sweep +covers all eight. SuperSmoother, added in v1.2, is pinned against the reference +`supersmoother` package and `gatspy` in the unit tests (`tests/test_supersmoother.py`), +and is exercised on real data in the multi-band validation below. + ## What it checks | | Methods | Reference | Question | @@ -16,11 +21,13 @@ The rendered results are in **[REPORT.md](REPORT.md)** with figures in `figures/ | | CE, String-Length, MHAOV | independent textbook impl. | match the original paper? | | | TLS | `transitleastsquares` | recover known Kepler periods? | | Period recovery | all 7 | VSX literature period | find the real period? | -| Performance | all 7 | astropy / PyAstronomy | how much faster, and how does it scale? | +| Performance | all 8 | astropy / PyAstronomy | how much faster, and how does it scale? | +| Multi-band recovery (simulated) | GLS | single-band GLS | does a joint fit beat per-band searching? | +| Multi-band recovery (real) | all 7 multi-band methods + 3 GLS models | Sesar 2010 literature periods | recover known periods on real ugriz data? | The performance benchmark also times the **portable `torch` backend** (`backend="torch"`; -the resolved device is shown in the `torch_backend` column) for the ported methods — GLS -and BLS — alongside the CPU and CUDA paths, so the cross-vendor path (AMD/Intel/Mac/CPU) is +the resolved device is shown in the `torch_backend` column) for every method — all eight +now have one — alongside the CPU and CUDA paths, so the cross-vendor path (AMD/Intel/Mac/CPU) is tracked. A backend absent on the host (no CUDA GPU, or no torch) is recorded blank rather than failing the sweep. @@ -37,12 +44,111 @@ than failing the sweep. (`dataset/download_extension.py`, re-runnable) that deliberately adds harder, less-curated classes (spot-evolving rotators, wandering semiregular/Mira periods) for a more realistic recovery-rate estimate; see REPORT.md §3 for - the core-vs-extension breakdown. This file is self-contained — §1, §2 and §4 + the core-vs-extension breakdown. This file is self-contained — §1, §2 and §5 of the report need no external data or network access. +* **`dataset/s82_rrlyrae.parquet`** — 100 real SDSS Stripe 82 RR Lyrae *ugriz* + light curves (80 RRab, 20 RRc; ~55 epochs per band over a ~3200 d baseline) + with the literature periods of Sesar et al. 2010 (ApJ 708, 717), the canonical + real multi-band validation set — VanderPlas & Ivezić (2015) developed the + multiband periodogram on these stars. One row per star and band: + `sesar_id, rrl_type, p_sesar, band, n_det, baseline, mjd[], mag[], mag_err[]`. + Built by `dataset/download_s82_rrlyrae.py` (re-runnable) from the astroML-data + GitHub mirror of the paper's tables — the original MPIA host is dead — keeping + the first 100 stars by ascending Sesar ID, a deterministic cut with no quality + selection. At ~390 KB it is committed, so §4 of the report runs offline. * **Kepler** confirmed KOIs for TLS, from the Mendeley *Dataset_Machine_Learning_Exoplanets_2024* (`wctcv34962`); raw PDCSAP flux is fetched from MAST with `lightkurve` into `data/` at run time. +## Multi-band recovery (`multiband_recovery.py`) + +Single-band vs. joint multi-band period recovery under a Rubin/LSST-like cadence. This +one is **simulated**, not real data: RRab proxies (fundamental plus a phase-locked 0.35 +second harmonic, P ~ U(0.35, 0.9) d) observed over a 3-year span, epochs landing on random +nights with the WFD per-band share (u 6%, g 9%, r 26%, i 26%, z 17%, y 16%) and 0.20 mag +per-point noise — about an *r* ≈ 23 halo RR Lyrae in single visits. The *total* number of +epochs across all six bands is swept. Recovery means the periodogram's top period is +within 1% of the truth, with no harmonic credit. + +```bash +python multiband_recovery.py --n-stars 300 # -> results/multiband_recovery.parquet +``` + +Recovery fraction, 300 stars per cell: + +| strategy | 30 epochs | 60 epochs | 120 epochs | +|---|---|---|---| +| best single band (r) | 0.0% | 37.3% | 97.3% | +| any single band | 0.0% | 49.3% | 99.0% | +| multiband perband (0,1) | 17.7% | 97.0% | 100.0% | +| multiband flex (1,1) | 20.0% | 97.0% | 100.0% | +| multiband offsets (1,0) | 81.7% | 99.7% | 100.0% | + +*any single band* counts a star as recovered if **any** of the six per-band searches lands +on the right period — an optimistic upper bound, since in practice you don't know which +band was right. The cadence is deliberately simple (random nights, no rolling cadence, no +lunation weighting), so the result to read is the ordering rather than the absolute rates: +sharing the phase across bands is what buys sparse-cadence recovery, consistent with +Rubin's own alert-production study and VanderPlas & Ivezić (2015). That is why `offsets` +is cuPeriod's default multi-band model. + +Options: `--n-stars`, `--noise` (mag per point), `--backend`. It needs no external data or +network access. + +## Real multi-band validation (`multiband_real.py`) + +The same question as above, asked of **real** photometry with known answers. Every star in +`dataset/s82_rrlyrae.parquet` gets one identical blind search — periods 0.15–1.2 d on a +uniform grid at 5 samples per Rayleigh width of its ~3200 d baseline (~97,000 trial +frequencies), every method at its default settings (BLS builds its native duration grid +inside the same window). Scoring follows the suite: **strict** = the top period is within 1% +of Sesar's, with no harmonic credit; **harmonic-aware** = it matches up to a small-integer +harmonic ratio within 2%. + +```bash +python multiband_real.py # -> results/multiband_real.parquet +``` + +100 stars, CPU pass (numba/finufft tiers): + +| model | strict | harmonic-aware | median CPU s/star | +|---|---|---|---| +| GLS `offsets` (1,0) | 76% | 80% | 0.070 | +| GLS `perband` (0,1) | 78% | 81% | 0.112 | +| GLS `flex` (1,1) | 78% | 81% | 0.367 | +| PDM | **93%** | 94% | 0.011 | +| CE | 85% | 90% | 0.023 | +| String-Length | **93%** | **97%** | 0.036 | +| MHAOV | 83% | 84% | 0.538 | +| SuperSmoother | 85% | 96% | 0.296 | +| BLS | 22% | 34% | 3.024 | + +Single-band GLS on one filter at a time is the baseline the joint methods have to beat: 72–78% +strict per band (*z* worst, *r* best), and 92% if you count a star as recovered when **any** of +the five bands lands on the right period — the same optimistic upper bound as above, since in +practice you don't know which band was right. The median fractional period error over strict +hits is ~1e-05 for every model, so a hit is a hit at the grid's resolution. + +The read: on curves this well sampled (~280 points across five bands) the pooled fold +statistics lead. PDM and String-Length reach 93% strict, String-Length 97% harmonic-aware — +a dense fold exploits the full non-sinusoidal RRab shape, while the single-harmonic GLS models +stay alias-limited. Those three GLS models are indistinguishable here (76–78%) and no better +than the best single band (78%), which is the *opposite* regime from the simulated sparse +cadence above, where `offsets` recovers 82% at 30 total epochs and the flexible models ≤20%: +dense per-band data reward shape, sparse data reward parsimony. (The fold methods were not run +at sparse cadence, so this says nothing about how they would do there.) SuperSmoother's +strict-vs-harmonic gap, 85% → 96%, is exactly the documented integer-multiples family — of 21 +fold-family harmonic-but-not-strict picks, 11 sit at exactly 2P and 5 at 3P — and it shows up +by subtype: 55% strict on the near-sinusoidal RRc against 92.5% on RRab, since a fold at 2P +stays coherent. The documented recipe applies: take the shortest member of a near-tied family, +or let `cuperiod.alias_diagnostics` arbitrate. Of the 163 non-harmonic misses across all +models, 54% sit on the ±1 or ±2 cycle/day loci — the ground-based window function, not noise. +BLS's 22% is expected: it is transit-shaped by design, included for completeness rather than +recommended for RR Lyrae. + +A GPU pass runs alongside the scored CPU pass to record agreement and timing. The step needs +no network access — the light curves are committed. + ## Environments Two venvs, because `transitleastsquares` pins an old numba: @@ -55,6 +161,8 @@ Two venvs, because `transitleastsquares` pins an old numba: ```bash python validate_periodograms.py # -> results/validation_metrics.parquet (GPU venv) python injection_recovery.py # -> results/injection_recovery.parquet (GPU venv) +python multiband_recovery.py --n-stars 300 # -> results/multiband_recovery.parquet (GPU venv) +python multiband_real.py # -> results/multiband_real.parquet (GPU venv) python bls_numba_parity.py # -> results/bls_numba_parity.parquet (GPU venv) python benchmark.py # -> results/bench_*.parquet (GPU venv) ../.venv-ref/Scripts/python tls_download_ref.py # -> data/, tls_reference_results.csv @@ -62,5 +170,6 @@ python tls_cuperiod.py # -> results/tls_results.parquet python make_report.py # -> figures/*.png, REPORT.md ``` -`dataset/light_curves.parquet` is committed, so the validation and benchmark -steps reproduce out of the box; only the TLS section downloads Kepler data. +`dataset/light_curves.parquet` and `dataset/s82_rrlyrae.parquet` are committed, +so the validation, multi-band and benchmark steps reproduce out of the box; only +the TLS section downloads Kepler data. diff --git a/benchmarks/REPORT.md b/benchmarks/REPORT.md index 51124b7..c8ee998 100644 --- a/benchmarks/REPORT.md +++ b/benchmarks/REPORT.md @@ -1,6 +1,6 @@ # cuPeriod — Validation & Benchmark Report -**Summary.** All 7 period-search methods in cuPeriod 1.1.0 were validated on 126 real ASAS-SN light curves with literature periods, plus 12 confirmed Kepler KOIs for the transit methods. CPU and GPU backends agree to round-off (worst-case relative difference 1e-05, dominated by the two single-precision GPU paths) and select the identical best period on 100% of targets; every method with an established external reference implementation reproduces it on an identical grid. Harmonic-aware period recovery is ≥88% for all methods. Peak measured throughput is 587 light curves/s (GLS) on one GPU. Practical guidance on backend selection is given in §7; limitations in §8. +**Summary.** cuPeriod 1.2.0's 7 single-band-benchmarked period-search methods were validated on 126 real ASAS-SN light curves with literature periods, plus 12 confirmed Kepler KOIs for the transit methods. CPU and GPU backends agree to round-off (worst-case relative difference 1e-05, dominated by the two single-precision GPU paths) and select the identical best period on 100% of targets; every method with an established external reference implementation reproduces it on an identical grid. Harmonic-aware period recovery is ≥88% for all of them. Peak measured throughput is 574 light curves/s (GLS) on one GPU. Every multi-band method was additionally validated on 100 real SDSS Stripe 82 RR Lyrae with literature periods (best joint model: 93% strict top-period recovery; §4). Practical guidance on backend selection is given in §8; limitations in §9. ## 1 — Test environment and methodology @@ -11,10 +11,10 @@ | GPU | NVIDIA GeForce RTX 5070 Ti, 16 GB (compute capability 12.0, sm_120) | | CPU | AMD Ryzen 9 9950X3D, 16 cores / 32 threads | | Memory | 32 GB | -| Software | cuPeriod 1.1.0, Python 3.12, CuPy (CUDA 12), PyTorch cu128 (torch:cuda), numba, finufft | +| Software | cuPeriod 1.2.0, Python 3.12, CuPy (CUDA 12), PyTorch cu128 (torch:cuda), numba, finufft | | torch device (validated) | torch:cuda | | Reference tools | astropy (`LombScargle`, `BoxLeastSquares`), PyAstronomy (`pyPDM`), `transitleastsquares`; CE/String-Length/MHAOV vs direct NumPy implementations of the published algorithms | -| Validation data | 126 ASAS-SN g-band light curves (6 variability classes: Eclipsing 28, Rr Lyrae 22, Cepheid 16, Delta Scuti 16, Long Period 22, Rotational 22) with VSX literature periods, bundled in `dataset/light_curves.parquet` (core sample plus an extension selected/downloaded via `dataset/download_extension.py` from ASAS-SN Sky Patrol — clean single VSX types, n_det≥300, baseline≥1000 d); 12 confirmed Kepler KOIs (Mendeley *Dataset_Machine_Learning_Exoplanets_2024*; flux via MAST/lightkurve) | +| Validation data | 126 ASAS-SN g-band light curves (6 variability classes: Eclipsing 28, Rr Lyrae 22, Cepheid 16, Delta Scuti 16, Long Period 22, Rotational 22) with VSX literature periods, bundled in `dataset/light_curves.parquet` (core sample plus an extension selected/downloaded via `dataset/download_extension.py` from ASAS-SN Sky Patrol — clean single VSX types, n_det≥300, baseline≥1000 d); 12 confirmed Kepler KOIs (Mendeley *Dataset_Machine_Learning_Exoplanets_2024*; flux via MAST/lightkurve); 100 SDSS Stripe 82 RR Lyrae with ugriz photometry and literature periods (Sesar et al. 2010, `dataset/s82_rrlyrae.parquet`) for the multi-band methods | ### 1.2 Timing methodology @@ -41,7 +41,7 @@ Every method runs on an identical grid through cuPeriod's CPU and GPU backends a | MHAOV | 126 | 1.1e-05 | 100% | Sch.-Czerny | 1.4e-04 | | TLS | 28 | 9.3e-10 | 100% | — | — | -**Table 1.** Numerical validation per method (metrics defined in §1.3). The GLS and MHAOV GPU kernels are single precision, bounding their parity at ≈1e-6/1e-7; all other GPU paths — String-Length included, via a stable phase sort on every backend — are double precision. String-Length's worst-case reference difference is an isolated outlier on 1–2 heavily phase-tied stars, where the textbook reference breaks ties with an unstable sort (correlation ≈1, median \|Δ\| ≈ 6e-12, recovered period unaffected). +**Table 1.** Numerical validation per method (metrics defined in §1.3). The GLS and MHAOV GPU kernels are single precision, bounding their parity at ≈1e-6 (GLS) / ≈1e-5 (MHAOV); all other GPU paths — String-Length included, via a stable phase sort on every backend — are double precision. String-Length's worst-case reference difference is an isolated outlier on 1–2 heavily phase-tied stars, where the textbook reference breaks ties with an unstable sort (correlation ≈1, median \|Δ\| ≈ 6e-12, recovered period unaffected). ![parity](figures/fig1_parity_reference.png) @@ -110,9 +110,43 @@ Every method runs on an identical grid through cuPeriod's CPU and GPU backends a - *alias/harmonic*: recovered period sits near a harmonic/alias ratio just outside the accepted set — a photometric-alias selection, not a recovery failure. -## 4 — Injection–recovery sensitivity +## 4 — Multi-band period recovery: real Stripe 82 RR Lyrae -§2–3 validate against real, bright, well-established stars — a favourable regime. This section complements that with a controlled sweep: a known synthetic signal of tunable amplitude, drawn onto *real* ASAS-SN observation cadences (so the irregular sampling and seasonal gaps of ground-based photometry are represented realistically), scored with the same harmonic-aware 2% tolerance as §3. Three signal models, each run through the methods it is diagnostic for: a **sinusoid** (+ mild 2nd harmonic) for GLS/MHAOV/PDM/CE/String-Length; an **eclipse** fold (two unequal narrow Gaussian dips per cycle) for PDM/CE/String-Length/BLS; and a **box transit** for BLS/TLS. SNR is defined as injected amplitude / photometric σ, with σ = 0.02 mag (typical ASAS-SN g-band precision); periods and phases are drawn per trial (seed 42, 40 trials per method × signal × SNR cell), all on cuPeriod's CPU (numba) backend. +§3 validates the single-band methods on real data; this section does the same for every **multi-band** method, on the canonical real multi-band test set: the SDSS Stripe 82 RR Lyrae of Sesar et al. 2010 (ApJ 708, 717) — the dataset VanderPlas & Ivezić 2015 developed the shared-phase multiband periodogram on, the model that ships as cuPeriod's default `offsets` GLS. 100 stars (80 RRab, 20 RRc; the first 100 of 483 by Sesar ID, no quality selection), each with real ugriz photometry (~55 epochs per band, ~280 points total) over a ~3200-day baseline, and a literature period from the discovery paper. Ground-based cadence at its most adversarial: strong ±1 cycle/day aliasing. Blind search, identical for every star: periods 0.15–1.2 d at 5 samples per Rayleigh width (~97 000 trial frequencies), every method at default settings (BLS builds its native duration grid inside the same window). **strict** = top period within 1% of the literature value, no harmonic credit; **harmonic-aware** = §1.3's 2% harmonic tolerance. Bundle: `dataset/s82_rrlyrae.parquet` via `dataset/download_s82_rrlyrae.py`. + +| model | N | strict (1%) | harmonic-aware (2%) | median \|ΔP\|/P | t_CPU [s/★] | t_GPU [s/★] | +| --- | --- | --- | --- | --- | --- | --- | +| single-band GLS, u | 100 | 75.0% [65.7–82.5%] | 77.0% [67.8–84.2%] | — | — | — | +| single-band GLS, g | 100 | 77.0% [67.8–84.2%] | 81.0% [72.2–87.5%] | — | — | — | +| single-band GLS, r | 100 | 78.0% [68.9–85.0%] | 79.0% [70.0–85.8%] | — | — | — | +| single-band GLS, i | 100 | 75.0% [65.7–82.5%] | 79.0% [70.0–85.8%] | — | — | — | +| single-band GLS, z | 100 | 72.0% [62.5–79.9%] | 77.0% [67.8–84.2%] | — | — | — | +| single-band GLS, any band | 100 | 92.0% [85.0–95.9%] | — | — | — | — | +| **GLS offsets (1,0)** | 100 | 76.0% [66.8–83.3%] | 80.0% [71.1–86.7%] | 1.0e-05 | 0.07 | 0.13 | +| **GLS perband (0,1)** | 100 | 78.0% [68.9–85.0%] | 81.0% [72.2–87.5%] | 9.6e-06 | 0.11 | 0.21 | +| **GLS flex (1,1)** | 100 | 78.0% [68.9–85.0%] | 81.0% [72.2–87.5%] | 9.6e-06 | 0.37 | 0.27 | +| **PDM** | 100 | 93.0% [86.3–96.6%] | 94.0% [87.5–97.2%] | 9.0e-06 | 0.01 | 0.07 | +| **CE** | 100 | 85.0% [76.7–90.7%] | 90.0% [82.6–94.5%] | 9.8e-06 | 0.02 | 0.05 | +| **String-Len** | 100 | 93.0% [86.3–96.6%] | 97.0% [91.5–99.0%] | 8.1e-06 | 0.04 | 0.03 | +| **MHAOV** | 100 | 83.0% [74.5–89.1%] | 84.0% [75.6–89.9%] | 8.4e-06 | 0.54 | 0.48 | +| **SuperSmoother** | 100 | 85.0% [76.7–90.7%] | 96.0% [90.2–98.4%] | 8.0e-06 | 0.30 | 0.87 | +| **BLS** | 100 | 22.0% [15.0–31.1%] | 34.0% [25.5–43.7%] | 1.4e-03 | 3.02 | 3.66 | + +**Table 3.** Multi-band period recovery on real Stripe 82 RR Lyrae, Wilson 95% CIs. *median \|ΔP\|/P* is over strict hits (grid resolution is ~3e-5 of the period at these frequencies). Timings are median wall time per star on the shared ~97k-frequency grid, warm JIT, single shot — the batch runner amortises further via engine reuse. BLS is transit-shaped by design and is included for completeness, not as a recommended RR Lyrae tool. + +**Reading the result.** The pooled fold statistics lead on these well-sampled curves: PDM reaches 93% strict vs 78% for the best GLS model. With ~280 points a fold uses the full non-sinusoidal light-curve shape, while the single-harmonic GLS models stay alias-limited — dense data reward shape, sparse data reward parsimony (see the model-choice note below). Of the 163 non-harmonic misses across all models, 54% sit on the ±1 or ±2 cycle/day window aliases (Figure 7b) — the failure mode is the ground-based window function, not noise. For the fold-family statistics (PDM/CE/String-Length/SuperSmoother), 21 harmonic-aware hits are not strict hits; 52% of those sit at exactly 2P — the documented integer-multiple degeneracy of phase-folding statistics (a fold at 2P, 3P… of a true period stays coherent). The practical recipe stands: treat the *shortest* member of a near-tied family as the period, or arbitrate with `cuperiod.alias_diagnostics`. + +**Model choice depends on sampling density.** On these well-sampled curves (~280 points) the three GLS models perform comparably (offsets 76%, perband 78%, flex 78% strict). The **simulated sparse-cadence benchmark** (`multiband_recovery.py`) probes the opposite regime: at 30 total epochs the shared-phase `offsets` model recovers 82% vs ≤20% for the flexible models — fewer parameters win when epochs are few. Both regimes are real; `offsets` stays the default because the sparse regime (early Rubin) is the one that needs a joint method most, and the flexible models are one `mb_model=` switch away. + +**Backends.** The GPU pass picks the same top period as the scored cpu pass in 100.0% of model×star runs. Per-star GPU timings in Table 3 are single-shot periodogram calls; no model gains ≥1.5× from the GPU at this single-shot size. PDM (7× slower) is dominated by fixed per-call dispatch and transfer overhead that a single-shot call cannot amortise — for one-off searches of this method use the CPU tier, and at catalogue scale use the batch runner, which amortises launches and reuses engines across stars. + +![multiband real](figures/fig7_multiband_real.png) + +**Figure 7.** (a) Strict and harmonic-aware recovery per model; the single-band GLS baseline (left of the dotted line) is what a per-band search achieves on the same grid. (b) Recovered/literature period ratio for every model×star pair: misses (red) concentrate on the ±1 cycle/day alias loci (dotted) and the integer-multiple harmonics (dashed). + +## 5 — Injection–recovery sensitivity + +§2–4 validate against real, bright, well-established stars — a favourable regime. This section complements that with a controlled sweep: a known synthetic signal of tunable amplitude, drawn onto *real* ASAS-SN observation cadences (so the irregular sampling and seasonal gaps of ground-based photometry are represented realistically), scored with the same harmonic-aware 2% tolerance as §3. Three signal models, each run through the methods it is diagnostic for: a **sinusoid** (+ mild 2nd harmonic) for GLS/MHAOV/PDM/CE/String-Length; an **eclipse** fold (two unequal narrow Gaussian dips per cycle) for PDM/CE/String-Length/BLS; and a **box transit** for BLS/TLS. SNR is defined as injected amplitude / photometric σ, with σ = 0.02 mag (typical ASAS-SN g-band precision); periods and phases are drawn per trial (seed 42, 40 trials per method × signal × SNR cell), all on cuPeriod's CPU (numba) backend. | signal | method | SNR=0.5 | SNR=1 | SNR=1.5 | SNR=2.5 | SNR=4 | SNR=6 | SNR=10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | @@ -128,7 +162,7 @@ Every method runs on an identical grid through cuPeriod's CPU and GPU backends a | Transit | BLS | 18% | 92% | 100% | 100% | 100% | 100% | 100% | | Transit | TLS | 20% | 90% | 100% | 100% | 100% | 100% | 100% | -**Table 3.** Recovery fraction (%) per method × signal × SNR, n=40 trials/cell. Wilson intervals per cell are wide at this trial count (omitted here for readability; §3's Table 2 shows the CI convention on the larger real-star sample). +**Table 4.** Recovery fraction (%) per method × signal × SNR, n=40 trials/cell. Wilson intervals per cell are wide at this trial count (omitted here for readability; §3's Table 2 shows the CI convention on the larger real-star sample). ![injection](figures/fig6_injection.png) @@ -136,7 +170,7 @@ Every method runs on an identical grid through cuPeriod's CPU and GPU backends a **Where methods plateau below 100%.** String-Len on eclipse plateaus at 78% even at the highest tested SNR (10). These are method–signal mismatches, not implementation bugs (isolated cells in the low-to-mid 90s are consistent with one or two alias near-misses at n=40 trials and are not flagged) — e.g. String-Length's rank-based statistic is comparatively insensitive to the narrow, low duty-cycle dips of the eclipse model used here, so it under-recovers that signal shape even at high SNR; a box-fitting method (BLS) is the appropriate tool for narrow eclipses/transits. -## 5 — TLS on Kepler transits +## 6 — TLS on Kepler transits 12 confirmed KOIs, blind search 0.5–12 d. cuPeriod (GPU) recovers the known period (or a 1/2 or 2× harmonic) within 2% for **83%** of them, and agrees with `transitleastsquares` on **83%**. On the 5-KOI CPU-timed subset, CPU↔GPU max\|Δpower\| ≤ 2.1e-14 and the GPU is a median **2×** faster. @@ -155,85 +189,89 @@ Every method runs on an identical grid through cuPeriod's CPU and GPU backends a | 8051946 | 1.4952 | 11.4480 | 1.4952 | 2.8e+00 | — | — | | 9907129 | 9.7057 | 9.7068 | 9.7054 | 1.1e-04 | — | — | -**Table 3.** Blind TLS period recovery on confirmed Kepler KOIs. cuPeriod recovers 10/12; the `transitleastsquares` reference recovers 11/12. Both miss only the shallowest transits, where a blind 0.5–12 d search aliases — a failure mode shared with the reference implementation, not a backend defect. +**Table 5.** Blind TLS period recovery on confirmed Kepler KOIs. cuPeriod recovers 10/12; the `transitleastsquares` reference recovers 11/12. Both miss only the shallowest transits, where a blind 0.5–12 d search aliases — a failure mode shared with the reference implementation, not a backend defect. ![tls](figures/fig5_tls.png) **Figure 4.** (a) Recovered vs known KOI period for cuPeriod (GPU and CPU) and `transitleastsquares`; (b) GPU speedup on the CPU-timed subset. -## 6 — Performance +## 7 — Performance -**cuPeriod's CPU box search beats astropy.** The default CPU BLS backend is a multicore `numba` port of the CUDA kernel — **18× faster than astropy's compiled `BoxLeastSquares`** (188 ms vs 3.5 s on this light curve), matching it to floating-point — verified on all 126 validation light curves: max\|Δpower\| ≤ 0.0e+00, identical best period on 126/126. The GPU then adds another 2× (38× over astropy). +**cuPeriod's CPU box search beats astropy.** The default CPU BLS backend is a multicore `numba` port of the CUDA kernel — **20× faster than astropy's compiled `BoxLeastSquares`** (171 ms vs 3.5 s on this light curve), matching it to floating-point — verified on all 126 validation light curves: max\|Δpower\| ≤ 0.0e+00, identical best period on 126/126. The GPU then adds another 2× (37× over astropy). | method | CPU backend | t_CPU [s] | t_GPU [s] | t_torch [s] | torch device | reference tool | t_ref [s] | CPU vs ref | GPU vs CPU | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | -| GLS | finufft | 0.015 | 0.0051 | 0.008 | torch:cuda | astropy | 0.03 | 2× | 2.9× | -| BLS | numba | 0.188 | 0.0920 | 0.392 | torch:cuda | astropy | 3.46 | 18× | 2.0× | -| PDM | numba | 0.003 | 0.0051 | 0.011 | torch:cuda | PyAstronomy | 6.25 | 2106× | 0.6× | -| CE | numba | 0.003 | 0.0039 | 0.009 | torch:cuda | — | — | — | 0.8× | -| String-Len | numba | 0.043 | 0.0117 | 0.009 | torch:cuda | — | — | — | 3.7× | -| MHAOV | numba | 0.025 | 0.1348 | 0.114 | torch:cuda | — | — | — | 0.2× | -| TLS | numba | 0.150 | 0.0427 | 2.110 | torch:cuda | — | — | — | 3.5× | +| GLS | finufft | 0.013 | 0.0054 | 0.009 | torch:cuda | astropy | 0.04 | 3× | 2.3× | +| BLS | numba | 0.171 | 0.0932 | 0.396 | torch:cuda | astropy | 3.47 | 20× | 1.8× | +| PDM | numba | 0.003 | 0.0051 | 0.009 | torch:cuda | PyAstronomy | 6.17 | 2177× | 0.6× | +| CE | numba | 0.003 | 0.0044 | 0.021 | torch:cuda | — | — | — | 0.7× | +| String-Len | numba | 0.043 | 0.0119 | 0.009 | torch:cuda | — | — | — | 3.7× | +| MHAOV | numba | 0.026 | 0.0381 | 0.032 | torch:cuda | — | — | — | 0.7× | +| SuperSmoother | numba | 0.099 | 0.2843 | 0.222 | torch:cuda | — | — | — | 0.3× | +| TLS | numba | 0.132 | 0.0723 | 2.205 | torch:cuda | — | — | — | 1.8× | -**Table 4.** Single-curve wall time per method (methodology in §1.2). *CPU backend* = what `backend="cpu"` resolves to — the fast default a user gets: finufft (GLS), the multicore numba box search (BLS), numba for the rest (with the `[fast]` extra) or numpy otherwise. *CPU vs ref* = cuPeriod-CPU speedup over the established external tool; *GPU vs CPU* = CUDA backend over cuPeriod's own CPU backend. *t_torch* = the portable PyTorch backend (device in *torch device*: cpu/cuda/mps/xpu) — the cross-vendor path that also runs on AMD/Intel/Mac GPUs. +**Table 6.** Single-curve wall time per method (methodology in §1.2). *CPU backend* = what `backend="cpu"` resolves to — the fast default a user gets: finufft (GLS), the multicore numba box search (BLS), numba for the rest (with the `[fast]` extra) or numpy otherwise. *CPU vs ref* = cuPeriod-CPU speedup over the established external tool; *GPU vs CPU* = CUDA backend over cuPeriod's own CPU backend. *t_torch* = the portable PyTorch backend (device in *torch device*: cpu/cuda/mps/xpu) — the cross-vendor path that also runs on AMD/Intel/Mac GPUs. -cuPeriod's CPU path already outperforms every external reference tool it has (GLS, PDM, BLS). **With the multicore numba tier, the GPU's single-curve margin over the CPU is modest almost everywhere** on this 16-core machine — 2–4× for BLS/String-Length/TLS, essentially a wash for PDM/CE, and the GPU is slower than the warm CPU kernel for MHAOV at this size. GLS is the one consistent exception (~3×): its CPU path is finufft, not a numba kernel. The scaling sweep (up to 30 000 points / a 100 000-frequency grid; Figure 5b) shows the same pattern across that whole range for PDM and MHAOV — the GPU's fixed per-call overhead (kernel launch, host↔device transfer) does not amortise at these problem sizes on a CPU this wide. The GPU's case is catalogue throughput and non-NVIDIA hardware (the portable torch backend), not single-curve latency on the CPU-tier methods; see §7. +cuPeriod's CPU path already outperforms every external reference tool it has (GLS, PDM, BLS). **With the multicore numba tier, the GPU's single-curve margin over the CPU is modest almost everywhere** on this 16-core machine: a ≥2× win for GLS (2.3×), String-Len (3.7×); a wash (0.8–2×) for BLS (1.8×), TLS (1.8×); slower than the warm CPU kernel for PDM (0.6×), CE (0.7×), MHAOV (0.7×), SuperSmoother (0.3×) at this size — fixed per-call dispatch and transfer overhead does not amortise once the CPU kernel itself runs in milliseconds. GLS's edge reflects its CPU path being finufft rather than a numba kernel. The scaling sweep (up to 30 000 points / a 100 000-frequency grid; Figure 5b) shows where that balance shifts with problem size. The GPU's case is catalogue throughput and non-NVIDIA hardware (the portable torch backend), not single-curve latency on the CPU-tier methods; see §8. -> The pure-`numpy` BLS backend shares one array-module-generic source with the CUDA kernel (so they validate to floating-point), but it is a *parity reference*, not the product path — 17.7 s here, slower than numba and astropy because its GPU-shaped layout trades memory traffic for the parallelism that makes the GPU fast. +> The pure-`numpy` BLS backend shares one array-module-generic source with the CUDA kernel (so they validate to floating-point), but it is a *parity reference*, not the product path — 18.0 s here, slower than numba and astropy because its GPU-shaped layout trades memory traffic for the parallelism that makes the GPU fast. ![benchmark](figures/fig4_benchmark.png) **Figure 5.** (a) Single-curve GPU speedup over cuPeriod's CPU backend (green boxes: cuPeriod-CPU speedup over the external reference tool); (b) wall time vs search-grid size (solid = GPU, dashed = CPU); (c) batch throughput, GPU vs CPU process pool. -Batch throughput on one GPU peaks at **587 light curves/s** (GLS, n=4096) — **>2.1 million light curves/hour**. This is a *single-batch* rate that includes the one-off worker-pool spin-up (process spawn + per-worker CUDA context); a warmed pool sustains a higher rate (≈490 lc/s here) over many chunks. On this 32-thread machine the CPU process pool keeps pace with the GPU for the numba-tier methods — GLS n=256 1.3×; GLS n=1024 1.4×; PDM n=256 1.0×; PDM n=1024 1.0× — with GLS the one method that shows a consistent GPU edge at batch scale too. Expect a wider GPU margin on a narrower CPU, or at batch sizes beyond what's swept here. +Batch throughput on one GPU peaks at **574 light curves/s** (GLS, n=4096) — **>2.1 million light curves/hour**. This is a *single-batch* rate that includes the one-off worker-pool spin-up (process spawn + per-worker CUDA context); a warmed pool sustains a higher rate over many chunks. On this 32-thread machine the CPU process pool keeps pace with the GPU for the numba-tier methods — GLS n=256 1.3×; GLS n=1024 1.4×; PDM n=256 1.0×; PDM n=1024 1.0× — with GLS the one method that shows a consistent GPU edge at batch scale too. Expect a wider GPU margin on a narrower CPU, or at batch sizes beyond what's swept here. -## 7 — Backend recommendations +## 8 — Backend recommendations | method | fastest measured | best time | GPU vs CPU | single-curve recommendation | | --- | --- | --- | --- | --- | -| GLS | gpu (CUDA) | 5.1 ms | 2.9× | `gpu` if available, else `cpu` | -| BLS | gpu (CUDA) | 92.0 ms | 2.0× | `gpu` if available, else `cpu` | -| PDM | cpu (numba) | 3.0 ms | 0.6× | `cpu` (GPU slower here) | -| CE | cpu (numba) | 3.1 ms | 0.8× | `cpu` (GPU slower here) | -| String-Len | torch (torch:cuda) | 8.9 ms | 3.7× | `gpu` if available, else `cpu` | -| MHAOV | cpu (numba) | 24.7 ms | 0.2× | `cpu` (GPU slower here) | -| TLS | gpu (CUDA) | 42.7 ms | 3.5× | `gpu` if available, else `cpu` | +| GLS | gpu (CUDA) | 5.4 ms | 2.3× | `gpu` if available, else `cpu` | +| BLS | gpu (CUDA) | 93.2 ms | 1.8× | `cpu` (GPU comparable) | +| PDM | cpu (numba) | 2.8 ms | 0.6× | `cpu` (GPU slower here) | +| CE | cpu (numba) | 3.0 ms | 0.7× | `cpu` (GPU slower here) | +| String-Len | torch (torch:cuda) | 9.1 ms | 3.7× | `gpu` if available, else `cpu` | +| MHAOV | cpu (numba) | 25.8 ms | 0.7× | `cpu` (GPU slower here) | +| SuperSmoother | cpu (numba) | 98.9 ms | 0.3× | `cpu` (GPU slower here) | +| TLS | gpu (CUDA) | 72.3 ms | 1.8× | `cpu` (GPU comparable) | -**Table 5.** Fastest measured backend per method on this machine (single curve, ~900 points; grids as in Table 4). +**Table 7.** Fastest measured backend per method on this machine (single curve, ~900 points; grids as in Table 6). Guidance by use case, from the measurements above: -1. **Interactive, single-curve analysis (default).** Use `backend="cpu"` with the `[fast]` extra installed. On a modern multi-core CPU it is within a small factor of the GPU on every method, faster than the GPU for PDM/CE/MHAOV at typical light-curve sizes, and already 2–2000× faster than the established external tools. No GPU is required for competitive single-curve performance. -2. **GLS-dominated pipelines on NVIDIA hardware.** Use `backend="gpu"`: GLS is the one method with a consistent GPU advantage (~3× single-curve, ~1.4× at batch scale), because its CPU path is finufft rather than a numba kernel. -3. **Catalogue-scale processing (10³–10⁶ curves).** Use `batch_periodograms(..., device="gpu")` on NVIDIA hardware — peak measured throughput 587 curves/s (>2 million curves/hour) on one GPU. On this 32-thread CPU the process pool keeps pace for the numba-tier methods, so on wide CPU nodes `device="cpu"` is a legitimate alternative; expect the GPU margin to widen on narrower CPUs and larger batches. -4. **AMD, Intel or Apple GPUs.** Use `backend="torch"` — the portable path validated to the same parity standard. On NVIDIA hardware it is slower than the native CUDA backend (Table 4), so treat it as the portability path, not the speed path. -5. **Strict double-precision requirements.** The GLS and MHAOV CUDA kernels are single precision (parity ≈1e-6/1e-7; Table 1). The selected best period was unaffected on all 126 validation stars, but if statistic values matter beyond ~6 significant digits (e.g. FAP tail comparisons), use the CPU backend, which is double precision throughout. -6. **Minimal installations (no numba).** `backend="cpu"` falls back to numpy — numerically identical but much slower for the box methods (the pure-numpy BLS parity reference takes ~18 s vs 0.19 s with numba). Install the `[fast]` extra, or use `backend="astropy"` for BLS. +1. **Interactive, single-curve analysis (default).** Use `backend="cpu"` with the `[fast]` extra installed. On a modern multi-core CPU it is within a small factor of the GPU on every method, faster than the GPU for PDM/CE/MHAOV/SuperSmoother at typical light-curve sizes, and already 2–2000× faster than the established external tools. No GPU is required for competitive single-curve performance. +2. **GLS-dominated pipelines on NVIDIA hardware.** Use `backend="gpu"`: GLS/String-Len show a consistent single-curve GPU advantage (Table 6 — GLS holds 3.9–4.7× across the grid-size sweep; GLS keeps ~1.4× at batch scale too, because its CPU path is finufft rather than a numba kernel). +3. **Catalogue-scale processing (10³–10⁶ curves).** Use `batch_periodograms(..., device="gpu")` on NVIDIA hardware — peak measured throughput 574 curves/s (>2 million curves/hour) on one GPU. On this 32-thread CPU the process pool keeps pace for the numba-tier methods, so on wide CPU nodes `device="cpu"` is a legitimate alternative; expect the GPU margin to widen on narrower CPUs and larger batches. +4. **AMD, Intel or Apple GPUs.** Use `backend="torch"` — the portable path validated to the same parity standard. On NVIDIA hardware the native CUDA backend is usually at least as fast (Table 6), so treat torch as the portability path, not the speed path. +5. **Strict double-precision requirements.** The GLS and MHAOV CUDA kernels are single precision (parity ≈1e-6 / ≈1e-5; Table 1). The selected best period was unaffected on all 126 validation stars, but if statistic values matter beyond ~6 significant digits (e.g. FAP tail comparisons), use the CPU backend, which is double precision throughout. +6. **Minimal installations (no numba).** `backend="cpu"` falls back to numpy — numerically identical but much slower for the box methods (the pure-numpy BLS parity reference takes ~18 s vs 0.17 s with numba). Install the `[fast]` extra, or use `backend="astropy"` for BLS. -## 8 — Limitations +## 9 — Limitations - All timings are from a single machine (Table in §1.1); CPU↔GPU ratios depend strongly on core count. The 16-core/32-thread CPU used here is near the top of the desktop range, so the reported GPU margins are conservative for typical hardware. - Batch throughput was swept only to 4096 curves per batch and is a single-shot rate including worker-pool start-up; sustained throughput and larger batches favour the GPU further. -- The GLS and MHAOV GPU statistics are single precision (§7, item 5). +- The GLS and MHAOV GPU statistics are single precision (§8, item 5). - The torch backend was timed on a CUDA device only; Apple (mps) and Intel (xpu) devices are supported but not benchmarked here. -- The TLS blind search uses a fixed 0.5–12 d window; the unrecovered KOIs are the shallowest transits, which alias within that window (the reference implementation misses one of the same targets; §5). The recovery rate therefore reflects the search configuration as much as the implementation. +- The TLS blind search uses a fixed 0.5–12 d window; the unrecovered KOIs are the shallowest transits, which alias within that window (the reference implementation misses one of the same targets; §6). The recovery rate therefore reflects the search configuration as much as the implementation. +- The real multi-band validation (§4) covers one variable class (RR Lyrae) on well-sampled ~280-point curves; the sparse-cadence regime is covered by the simulated `multiband_recovery.py` benchmark, not by real data. BLS is included there for completeness but is transit-shaped by design. - Recovery rates are measured on light curves with well-established literature periods and moderate noise; they are upper bounds relative to survey-quality data with weaker signals. -## 9 — References +## 10 — References -Method papers: GLS — Zechmeister & Kürster 2009, A&A 496, 577; Lomb–Scargle practicalities — VanderPlas 2018, ApJS 236, 16. BLS — Kovács, Zucker & Mazeh 2002, A&A 391, 369. PDM — Stellingwerf 1978, ApJ 224, 953. Conditional Entropy — Graham et al. 2013, MNRAS 434, 2629. String Length — Dworetsky 1983, MNRAS 203, 917. MHAOV — Schwarzenberg-Czerny 1996, ApJ 460, L107. TLS — Hippke & Heller 2019, A&A 623, A39. +Method papers: GLS — Zechmeister & Kürster 2009, A&A 496, 577; Lomb–Scargle practicalities — VanderPlas 2018, ApJS 236, 16; multiband GLS — VanderPlas & Ivezić 2015, ApJ 812, 18. BLS — Kovács, Zucker & Mazeh 2002, A&A 391, 369. PDM — Stellingwerf 1978, ApJ 224, 953. Conditional Entropy — Graham et al. 2013, MNRAS 434, 2629. String Length — Dworetsky 1983, MNRAS 203, 917. MHAOV — Schwarzenberg-Czerny 1996, ApJ 460, L107. TLS — Hippke & Heller 2019, A&A 623, A39. SuperSmoother — Friedman 1984; Reimann 1994. Reference software: Astropy Collaboration 2022, ApJ 935, 167; PyAstronomy — Czesla et al. 2019, ascl:1906.010; `transitleastsquares` — Hippke & Heller 2019. -Data: ASAS-SN — Shappee et al. 2014, ApJ 788, 48; Kochanek et al. 2017, PASP 129, 104502. VSX — Watson, Henden & Price 2006, SASS 25, 47. Kepler KOI light curves via MAST/lightkurve. +Data: ASAS-SN — Shappee et al. 2014, ApJ 788, 48; Kochanek et al. 2017, PASP 129, 104502. VSX — Watson, Henden & Price 2006, SASS 25, 47. SDSS Stripe 82 RR Lyrae — Sesar et al. 2010, ApJ 708, 717 (files via the astroML-data mirror). Kepler KOI light curves via MAST/lightkurve. -## 10 — Reproducibility -The validation light curves and their literature periods ship in `dataset/light_curves.parquet`; §2, §3, §4 and §6 need no network access or external catalogue. The Kepler/TLS comparison (§5) downloads flux from MAST and runs `transitleastsquares` in a separate pinned environment. +## 11 — Reproducibility +The validation light curves and their literature periods ship in `dataset/light_curves.parquet` and `dataset/s82_rrlyrae.parquet`; §2, §3, §4, §5 and §7 need no network access or external catalogue. The Kepler/TLS comparison (§6) downloads flux from MAST and runs `transitleastsquares` in a separate pinned environment. ``` python benchmarks/validate_periodograms.py # 1-1 validation (main GPU venv) -python benchmarks/injection_recovery.py # synthetic sensitivity sweep (§4) +python benchmarks/multiband_real.py # real S82 multi-band recovery (§4) +python benchmarks/injection_recovery.py # synthetic sensitivity sweep (§5) python benchmarks/benchmark.py # performance .venv-ref/.../python benchmarks/tls_download_ref.py # Kepler + transitleastsquares python benchmarks/tls_cuperiod.py # cuPeriod TLS diff --git a/benchmarks/benchmark.py b/benchmarks/benchmark.py index 5b20c85..5403cb7 100644 --- a/benchmarks/benchmark.py +++ b/benchmarks/benchmark.py @@ -16,6 +16,7 @@ from __future__ import annotations +import argparse import time import warnings @@ -95,8 +96,14 @@ def freq_grid(n): "CE": lambda: cup.CESettings(), "STRINGLENGTH": lambda: cup.StringLengthSettings(), "MHAOV": lambda: cup.MHAOVSettings(), + "SUPERSMOOTHER": lambda: cup.SuperSmootherSettings(), } +#: Methods swept in the scaling sections (2 and 3). SuperSmoother joins GLS/PDM/MHAOV +#: as the costliest fold method; no external reference tool is timed for it (gatspy's +#: pure-python smoother would dominate the sweep; accuracy parity is pinned in tests). +SCALING_METHODS = ["GLS", "PDM", "MHAOV", "SUPERSMOOTHER"] + # -------------------------------------------------------------------------- def bench_single(t, y, e): @@ -117,7 +124,15 @@ def bench_single(t, y, e): if has_torch else np.nan) tbe = (cup.periodogram((t, y, e), m, backend="torch", grid=grid, settings=st()).backend if has_torch and np.isfinite(tt) else "—") - tr = best_time(reftime[m], repeat=1) if m in reftime else np.nan + # Reference tools are ad-hoc installs (`uv sync` prunes them) — a missing + # one blanks its cell rather than killing the whole section. + tr = np.nan + if m in reftime: + try: + tr = best_time(reftime[m], repeat=1) + except ImportError as exc: + print(f" {m}: reference tool unavailable ({exc}); skipping ref timing", + flush=True) rows.append(dict(method=m, n_grid=grid.size, cpu_backend=be, cpu_s=tc, gpu_s=tg, torch_s=tt, torch_backend=tbe, ref_s=tr, ref=refname.get(m, "—"), @@ -175,7 +190,7 @@ def bench_scaling_npoints(t, y, e): rows = [] for n in [100, 300, 1000, 3000, 10000, 30000]: tt, yy, ee = resample(t, y, e, n) - for m in ["GLS", "PDM", "MHAOV"]: + for m in SCALING_METHODS: st = FREQ_SETTINGS[m] tc = best_time(lambda: cup.periodogram((tt, yy, ee), m, backend="cpu", grid=grid, settings=st()), repeat=1) tg = safe_best_time(lambda: cup.periodogram((tt, yy, ee), m, backend="gpu", grid=grid, settings=st()), repeat=1) @@ -194,7 +209,7 @@ def bench_scaling_grid(t, y, e): rows = [] for n in [1000, 3000, 10000, 30000, 100000]: grid = freq_grid(n) - for m in ["GLS", "PDM", "MHAOV"]: + for m in SCALING_METHODS: st = FREQ_SETTINGS[m] tc = best_time(lambda: cup.periodogram((t, y, e), m, backend="cpu", grid=grid, settings=st()), repeat=1) tg = safe_best_time(lambda: cup.periodogram((t, y, e), m, backend="gpu", grid=grid, settings=st()), repeat=1) @@ -214,8 +229,9 @@ def bench_batch(t, y, e): rng = np.random.default_rng(1) rows = [] cpu_cap = 1024 - # warm up the GPU worker pool + CUDA context so the timed runs measure - # steady-state throughput, not one-off device initialisation. + # warm up the parent process (imports, JIT/kernel compilation). The pool itself is + # rebuilt per call, so each timed run still pays its own spawn + CUDA-context cost — + # see the single-shot note below. warm = [(f"w{i}", cup.LightCurve.from_arrays(t, y, e)) for i in range(64)] for method in ["GLS", "PDM"]: cup.batch_periodograms(warm, method, device="gpu", grid=grid, @@ -251,20 +267,42 @@ def bench_batch(t, y, e): def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + "--sections", default=None, + help="comma-separated subset of single,npoints,grid,batch. Default runs " + "all four, skipping 'single' when results/bench_single.parquet " + "already exists (resume behaviour); naming sections runs exactly " + "those, re-measuring even if a parquet exists.") + args = parser.parse_args() + known = ("single", "npoints", "grid", "batch") + chosen = None + if args.sections is not None: + chosen = [s.strip() for s in args.sections.split(",") if s.strip()] + bad = sorted(set(chosen) - set(known)) + if bad: + parser.error(f"unknown sections {bad}; choose from {known}") + + def want(name: str, default: bool = True) -> bool: + return name in chosen if chosen is not None else default + t, y, e, P = representative_lc() print(f"representative LC: N={t.size}, baseline={t.max()-t.min():.0f} d, P={P:.4f}", flush=True) - if (RESULTS / "bench_single.parquet").exists(): - print("\n[1/4] single-LC: already done, skipping", flush=True) - else: + if want("single", default=not (RESULTS / "bench_single.parquet").exists()): print("\n[1/4] single-LC per-method timing...", flush=True) bench_single(t, y, e) - print("\n[2/4] scaling vs N points...", flush=True) - bench_scaling_npoints(t, y, e) - print("\n[3/4] scaling vs grid size...", flush=True) - bench_scaling_grid(t, y, e) - print("\n[4/4] batch throughput...", flush=True) - bench_batch(t, y, e) - print("\ndone — wrote results/bench_*.parquet", flush=True) + else: + print("\n[1/4] single-LC: skipped", flush=True) + if want("npoints"): + print("\n[2/4] scaling vs N points...", flush=True) + bench_scaling_npoints(t, y, e) + if want("grid"): + print("\n[3/4] scaling vs grid size...", flush=True) + bench_scaling_grid(t, y, e) + if want("batch"): + print("\n[4/4] batch throughput...", flush=True) + bench_batch(t, y, e) + print("\nBENCHMARK_DONE — wrote results/bench_*.parquet", flush=True) if __name__ == "__main__": diff --git a/benchmarks/dataset/download_s82_rrlyrae.py b/benchmarks/dataset/download_s82_rrlyrae.py new file mode 100644 index 0000000..76df530 --- /dev/null +++ b/benchmarks/dataset/download_s82_rrlyrae.py @@ -0,0 +1,209 @@ +"""Download the SDSS Stripe 82 RR Lyrae (Sesar et al. 2010) multi-band light curves +and bundle a deterministic subset into benchmarks/dataset/s82_rrlyrae.parquet. + +Why this dataset +---------------- +Sesar et al. 2010 (ApJ 708, 717) published ugriz light curves for 483 RR Lyrae +in SDSS Stripe 82, each with a precise literature period from a ~10-year +baseline. It is the canonical real multi-band validation set: VanderPlas & +Ivezic 2015 -- whose shared-phase model is cuPeriod's default ``offsets`` +multi-band GLS -- developed and demonstrated their method on exactly these +stars, as does the reference ``gatspy`` package. Five real bands, real SDSS +cadence (including the 1-day alias structure of ground-based data), and known +answers make it the right target for validating every multi-band method. + +Provenance +---------- +The original data host (B. Sesar's MPIA page, ``www.mpia.de/~bsesar/S82_RRLyr``, +the URL hardcoded in released gatspy 0.3) is dead. The maintained mirror is the +astroML organization's data repository, which gatspy's development branch now +points at: + + https://github.com/astroML/astroML-data/tree/main/datasets/S82_RRLyr + +Files used (downloaded into benchmarks/data/s82/, gitignored): + +* ``table1.tar.gz`` (~1.2 MB) -- one whitespace file per star, + ``table1/.dat``: columns ``RA DEC`` then ``(MJD mag err)`` for each of + u, g, r, i, z (17 columns). Missing observations carry the sentinel + ``-99.99`` in all three fields of that band. +* ``table2.dat.gz`` (~64 KB) -- per-star fit parameters; columns used here are + ``id``, ``type`` (``ab``/``c``) and ``P`` (period, days). + +Cite Sesar et al. 2010, ApJ 708, 717 when using these data. + +Subset +------ +The committed bundle keeps the first ``--n-stars`` (default 100) stars by +ascending Sesar ID -- a deterministic, selection-bias-free cut (no filtering on +photometric quality or on how well any method performs). ``--all`` bundles all +483. Schema (one row per star and band): + + sesar_id, rrl_type, p_sesar, band, n_det, baseline, mjd[], mag[], mag_err[] + +Run (main .venv; needs network on first run only) +------------------------------------------------- + .venv/Scripts/python.exe benchmarks/dataset/download_s82_rrlyrae.py +""" + +from __future__ import annotations + +import argparse +import gzip +import sys +import tarfile +import urllib.request +from pathlib import Path + +import numpy as np +import pandas as pd + +DATASET_DIR = Path(__file__).resolve().parent +CACHE_DIR = DATASET_DIR.parent / "data" / "s82" +OUTPUT_PARQUET = DATASET_DIR / "s82_rrlyrae.parquet" + +BASE_URL = "https://github.com/astroML/astroML-data/raw/main/datasets/S82_RRLyr/" +FILES = ("table1.tar.gz", "table2.dat.gz") + +BANDS = ("u", "g", "r", "i", "z") +SENTINEL = -99.99 +N_STARS_DEFAULT = 100 + +# Sanity anchors from gatspy's doctests (gatspy.datasets.rrlyrae): the total +# star count, a handful of ids that must be present (gatspy lists them in tar +# order, so only membership is checked), and the first-epoch photometry of one +# star, which catches column-layout mistakes. +EXPECTED_N_STARS = 483 +EXPECTED_IDS_PRESENT = [1013184, 1019544, 1027882, 1052471, 1056152] +EXPECTED_FIRST_STAR = { # band -> (mjd[0], mag[0]) for star 1013184 + "u": (51081.347856, 18.702), + "g": (51081.349522, 17.553), + "r": (51081.346189, 17.236), + "i": (51081.347022, 17.124), +} + + +def download(force: bool = False) -> None: + CACHE_DIR.mkdir(parents=True, exist_ok=True) + for name in FILES: + target = CACHE_DIR / name + if target.exists() and not force: + print(f"cached: {target}") + continue + url = BASE_URL + name + print(f"downloading {url} ...") + with urllib.request.urlopen(url) as resp: + target.write_bytes(resp.read()) + print(f" -> {target} ({target.stat().st_size:,} bytes)") + + +def load_periods() -> pd.DataFrame: + """Table 2: Sesar ID, RRL subtype (ab/c) and period in days.""" + with gzip.open(CACHE_DIR / "table2.dat.gz", "rt") as fh: + raw = np.loadtxt( + fh, + dtype={"names": ("id", "type", "P"), "formats": ("i8", "U2", "f8")}, + usecols=(0, 1, 2), + ) + return pd.DataFrame({ + "sesar_id": raw["id"], "rrl_type": raw["type"], "p_sesar": raw["P"], + }) + + +def load_light_curves() -> dict[int, dict[str, np.ndarray]]: + """Table 1: per-star (17-column) files -> {id: {band: (n, 3) [mjd, mag, err]}}.""" + stars: dict[int, dict[str, np.ndarray]] = {} + with tarfile.open(CACHE_DIR / "table1.tar.gz") as tar: + for member in tar.getmembers(): + parts = member.name.split("/") + if len(parts) != 2 or not parts[1].endswith(".dat"): + continue + sesar_id = int(parts[1].removesuffix(".dat")) + fh = tar.extractfile(member) + assert fh is not None + data = np.loadtxt(fh, dtype=np.float64) + data = np.atleast_2d(data) + per_band: dict[str, np.ndarray] = {} + for k, band in enumerate(BANDS): + block = data[:, 2 + 3 * k : 5 + 3 * k] # mjd, mag, err + good = ( + np.all(block != SENTINEL, axis=1) + & np.all(np.isfinite(block), axis=1) + & (block[:, 2] > 0) + ) + per_band[band] = block[good][np.argsort(block[good][:, 0])] + stars[sesar_id] = per_band + return stars + + +def sanity_check(stars: dict[int, dict[str, np.ndarray]]) -> None: + ids = sorted(stars) + print(f"parsed {len(ids)} stars; first five ids: {ids[:5]}") + if len(ids) != EXPECTED_N_STARS: + sys.exit(f"FATAL: expected {EXPECTED_N_STARS} stars, parsed {len(ids)}") + if not set(EXPECTED_IDS_PRESENT) <= set(ids): + sys.exit("FATAL: known Sesar ids are missing from the archive") + first = stars[EXPECTED_IDS_PRESENT[0]] + for band, (mjd0, mag0) in EXPECTED_FIRST_STAR.items(): + got = first[band][0] + if abs(got[0] - mjd0) > 1e-6 or abs(got[1] - mag0) > 1e-3: + sys.exit( + f"FATAL: star {EXPECTED_IDS_PRESENT[0]} band {band} first epoch " + f"is ({got[0]}, {got[1]}), expected ({mjd0}, {mag0}) -- " + "column layout mismatch" + ) + print("column-layout sanity check against gatspy doctest values: OK") + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--n-stars", type=int, default=N_STARS_DEFAULT, + help="bundle the first N stars by ascending Sesar ID") + parser.add_argument("--all", action="store_true", + help="bundle all 483 stars (overrides --n-stars)") + parser.add_argument("--force-download", action="store_true") + args = parser.parse_args() + + download(force=args.force_download) + periods = load_periods() + stars = load_light_curves() + sanity_check(stars) + + with_period = sorted(set(stars) & set(periods["sesar_id"])) + missing = sorted(set(stars) - set(periods["sesar_id"])) + if missing: + print(f"note: {len(missing)} stars lack a table2 period and are skipped: " + f"{missing}") + n_keep = len(with_period) if args.all else min(args.n_stars, len(with_period)) + keep = with_period[:n_keep] + + period_of = periods.set_index("sesar_id") + rows = [] + for sesar_id in keep: + for band in BANDS: + block = stars[sesar_id][band] + rows.append({ + "sesar_id": sesar_id, + "rrl_type": str(period_of.loc[sesar_id, "rrl_type"]), + "p_sesar": float(period_of.loc[sesar_id, "p_sesar"]), + "band": band, + "n_det": int(len(block)), + "baseline": float(block[-1, 0] - block[0, 0]) if len(block) else 0.0, + "mjd": block[:, 0].tolist(), + "mag": block[:, 1].tolist(), + "mag_err": block[:, 2].tolist(), + }) + out = pd.DataFrame(rows) + out.to_parquet(OUTPUT_PARQUET, index=False) + + meta = out.drop_duplicates("sesar_id") + print(f"\nwrote {OUTPUT_PARQUET}: {len(meta)} stars x {len(BANDS)} bands") + print(f" types: {meta['rrl_type'].value_counts().to_dict()}") + print(f" periods: {meta['p_sesar'].min():.4f} - {meta['p_sesar'].max():.4f} d") + per_band = out.groupby("band")["n_det"].median().astype(int).to_dict() + print(f" median epochs per band: {per_band}") + print(f" file size: {OUTPUT_PARQUET.stat().st_size:,} bytes") + + +if __name__ == "__main__": + main() diff --git a/benchmarks/dataset/s82_rrlyrae.parquet b/benchmarks/dataset/s82_rrlyrae.parquet new file mode 100644 index 0000000..90d206b Binary files /dev/null and b/benchmarks/dataset/s82_rrlyrae.parquet differ diff --git a/benchmarks/figures/fig4_benchmark.png b/benchmarks/figures/fig4_benchmark.png index 1a29d56..235070f 100644 Binary files a/benchmarks/figures/fig4_benchmark.png and b/benchmarks/figures/fig4_benchmark.png differ diff --git a/benchmarks/figures/fig7_multiband_real.png b/benchmarks/figures/fig7_multiband_real.png new file mode 100644 index 0000000..07bf459 Binary files /dev/null and b/benchmarks/figures/fig7_multiband_real.png differ diff --git a/benchmarks/make_report.py b/benchmarks/make_report.py index f9ffc8e..9765416 100644 --- a/benchmarks/make_report.py +++ b/benchmarks/make_report.py @@ -24,8 +24,8 @@ "grid.alpha": 0.25, "axes.axisbelow": True, "savefig.bbox": "tight", }) -METHOD_ORDER = ["GLS", "BLS", "PDM", "CE", "STRINGLENGTH", "MHAOV", "TLS"] -MLABEL = {"STRINGLENGTH": "String-Len"} +METHOD_ORDER = ["GLS", "BLS", "PDM", "CE", "STRINGLENGTH", "MHAOV", "SUPERSMOOTHER", "TLS"] +MLABEL = {"STRINGLENGTH": "String-Len", "SUPERSMOOTHER": "SuperSmoother"} CLASS_ORDER = ["ECLIPSING", "RR_LYRAE", "CEPHEID", "DELTA_SCUTI", "LONG_PERIOD", "ROTATIONAL"] CCOLOR = dict(zip(CLASS_ORDER, plt.cm.tab10(np.linspace(0, 1, 10)))) @@ -196,6 +196,81 @@ def fig_recovery(val): plt.close(fig) +MBR_ORDER = [ + ("gls_offsets", "GLS offsets (1,0)"), ("gls_perband", "GLS perband (0,1)"), + ("gls_flex", "GLS flex (1,1)"), ("pdm", "PDM"), ("ce", "CE"), + ("stringlength", "String-Len"), ("mhaov", "MHAOV"), + ("supersmoother", "SuperSmoother"), ("bls", "BLS"), +] + + +def _mbr_scored(mbr): + """The scored (first-listed backend) pass of the multiband-real results.""" + scored_backend = str(mbr["backend"].iloc[0]) + return mbr[mbr["backend"] == scored_backend], scored_backend + + +def fig_multiband_real(mbr): + scored, _ = _mbr_scored(mbr) + mb = scored[~scored.model.str.startswith("single_")] + single = scored[scored.model.str.startswith("single_")] + + fig, axes = plt.subplots(1, 2, figsize=(11, 4.2)) + # (a) strict + harmonic-aware recovery per model, single-band baselines first + ax = axes[0] + band_rate = single.groupby("model")["strict"].mean() + best_band = band_rate.idxmax().removeprefix("single_") + any_rate = single.groupby("sesar_id")["strict"].any().mean() + labels = [f"best band ({best_band})", "any band"] + strict = [band_rate.max() * 100, any_rate * 100] + harm = [np.nan, np.nan] + for key, label in MBR_ORDER: + g = mb[mb.model == key] + labels.append(label) + strict.append(g["strict"].mean() * 100) + harm.append(g["harmonic_ok"].mean() * 100) + x = np.arange(len(labels)) + ax.bar(x - 0.2, np.nan_to_num(harm), 0.4, + label="incl. harmonic (P, P/2, 2P…)", color="#4c72b0") + ax.bar(x + 0.2, strict, 0.4, label="strict (=P within 1%)", color="#dd8452") + ax.axvline(1.5, color="gray", lw=0.8, ls=":") + ax.set_xticks(x) + ax.set_xticklabels(labels, rotation=35, ha="right", fontsize=7) + ax.set_ylabel("recovery rate [%]") + ax.set_ylim(0, 105) + ax.set_title("(a) Recovery on 100 real S82 RR Lyrae\n" + "left of dots: single-band GLS baseline", fontsize=8) + ax.legend(fontsize=7, loc="lower right") + + # (b) where the misses go: ratio vs true period, harmonic + 1-day alias loci + ax = axes[1] + ratio = mb.p_top / mb.p_true + hit = mb["harmonic_ok"].to_numpy() + ax.scatter(mb.p_true[hit], ratio[hit], s=8, alpha=.3, color="#4c72b0", + edgecolor="none", label="harmonic-aware hit") + ax.scatter(mb.p_true[~hit], ratio[~hit], s=14, alpha=.8, color="crimson", + edgecolor="none", label="miss") + pp = np.linspace(mb.p_true.min() * 0.95, mb.p_true.max() * 1.05, 200) + for r in (0.5, 1.0, 2.0): + ax.axhline(r, color="gray", lw=0.7, ls="--", alpha=.6) + for s, lab in ((1, "+1 d$^{-1}$ alias"), (-1, "−1 d$^{-1}$ alias")): + with np.errstate(divide="ignore"): + loc = 1.0 / (1.0 + s * pp) + ok = (loc > 0) & (loc < 10) + ax.plot(pp[ok], loc[ok], lw=0.9, ls=":", color="#2ca02c", alpha=.9) + if ok.any(): + ax.text(pp[ok][-1], loc[ok][-1], lab, fontsize=6, color="#2ca02c") + ax.set_yscale("log") + ax.set_xlabel("Sesar 2010 literature period [d]") + ax.set_ylabel("recovered / literature period") + ax.set_title("(b) All multi-band model–star pairs\n" + "dashed: harmonics · dotted: ±1 cycle/day aliases", fontsize=8) + ax.legend(fontsize=7, loc="upper left", framealpha=0.9) + fig.tight_layout() + fig.savefig(FIGURES / "fig7_multiband_real.png") + plt.close(fig) + + INJ_SIGNAL_ORDER = ["sinusoid", "eclipse", "transit"] INJ_MCOLOR = {"GLS": "#1f77b4", "MHAOV": "#ff7f0e", "PDM": "#2ca02c", "CE": "#9467bd", "STRINGLENGTH": "#8c564b", "BLS": "#d62728", "TLS": "#17becf"} @@ -236,7 +311,8 @@ def fig_benchmark(single, npts, grid, batch): ax.bar(x, s["gpu_speedup"], 0.6, color="#4c72b0") top = float(s["gpu_speedup"].max()) for i, (m, row) in enumerate(s.iterrows()): - ax.text(i, row["gpu_speedup"], f"{row['gpu_speedup']:.0f}x", + v = row["gpu_speedup"] + ax.text(i, v, f"{v:.0f}x" if v >= 2 else f"{v:.1f}x", ha="center", va="bottom", fontsize=7) cvr = row.get("cpu_vs_ref", np.nan) if "cpu_vs_ref" in s.columns else np.nan if np.isfinite(cvr): @@ -249,9 +325,11 @@ def fig_benchmark(single, npts, grid, batch): "green = cuPeriod CPU speedup over the reference tool", fontsize=7.5) # (b) scaling vs grid size — one colour per method, solid=GPU, dashed=CPU ax = axes[1] - mcol = {"GLS": "#1f77b4", "PDM": "#2ca02c", "MHAOV": "#ff7f0e"} + mcol = {"GLS": "#1f77b4", "PDM": "#2ca02c", "MHAOV": "#ff7f0e", + "SUPERSMOOTHER": "#9467bd"} if grid is not None: - for m, mk in [("GLS", "o"), ("PDM", "s"), ("MHAOV", "^")]: + for m, mk in [("GLS", "o"), ("PDM", "s"), ("MHAOV", "^"), + ("SUPERSMOOTHER", "D")]: g = grid[grid.method == m].sort_values("n") if g.empty: continue @@ -370,6 +448,7 @@ def main(): batch = load("bench_batch.parquet") tls = load("tls_results.parquet") inj = load("injection_recovery.parquet") + mbr = load("multiband_real.parquet") spectra = sorted(glob.glob(str(RESULTS / "spectra" / "*.npz"))) made = [] @@ -385,6 +464,8 @@ def main(): fig_tls(tls); made.append("fig5") if inj is not None: fig_injection(inj); made.append("fig6") + if mbr is not None: + fig_multiband_real(mbr); made.append("fig7") print("figures:", made) # ---- assemble REPORT.md ---------------------------------------------- @@ -408,20 +489,30 @@ def main(): same_pct = val.cpu_gpu_same.mean() * 100 harm_lo = val.groupby("method").recover_harmonic.mean().min() * 100 summary = ( - f"**Summary.** All {val.method.nunique()} period-search methods in cuPeriod " - f"{cup.__version__} were validated on {len(meta)} real ASAS-SN light curves with " + f"**Summary.** cuPeriod {cup.__version__}'s {val.method.nunique()} " + f"single-band-benchmarked period-search methods were validated on {len(meta)} " + "real ASAS-SN light curves with " "literature periods, plus 12 confirmed Kepler KOIs for the transit methods. " f"CPU and GPU backends agree to round-off (worst-case relative difference " f"{worst_par:.0e}, dominated by the two single-precision GPU paths) and select " f"the identical best period on {same_pct:.0f}% of targets; every method with an " "established external reference implementation reproduces it on an identical " - f"grid. Harmonic-aware period recovery is ≥{harm_lo:.0f}% for all methods. ") + f"grid. Harmonic-aware period recovery is ≥{harm_lo:.0f}% for all of them. ") if batch is not None: gpk = batch.loc[batch.gpu_lc_per_s.idxmax()] summary += (f"Peak measured throughput is {gpk.gpu_lc_per_s:,.0f} light curves/s " f"({ml(gpk.method)}) on one GPU. ") + if mbr is not None: + mb_scored, _ = _mbr_scored(mbr) + mb_only = mb_scored[~mb_scored.model.str.startswith("single_")] + best_strict = mb_only.groupby("model")["strict"].mean().max() * 100 + summary += ( + f"Every multi-band method was additionally validated on " + f"{mb_scored.sesar_id.nunique()} real SDSS Stripe 82 RR Lyrae " + f"with literature periods (best joint model: {best_strict:.0f}% " + "strict top-period recovery; §4). ") summary += ("Practical guidance on backend selection is given in " - "§7; limitations in §8.") + "§8; limitations in §9.") L.append(summary + "\n") # ---- 1. environment & methodology -------------------------------------- @@ -446,7 +537,9 @@ def main(): "an extension selected/downloaded via `dataset/download_extension.py` from " "ASAS-SN Sky Patrol — clean single VSX types, n_det≥300, baseline≥1000 d); 12 " "confirmed Kepler KOIs (Mendeley *Dataset_Machine_Learning_Exoplanets_2024*; " - "flux via MAST/lightkurve) |\n") + "flux via MAST/lightkurve); 100 SDSS Stripe 82 RR Lyrae with ugriz " + "photometry and literature periods (Sesar et al. 2010, " + "`dataset/s82_rrlyrae.parquet`) for the multi-band methods |\n") L.append("### 1.2 Timing methodology\n") L.append("Wall-clock times use `time.perf_counter()`. Every timed configuration is run " "once untimed first — so JIT compilation (numba), CUDA kernel/plan caching and " @@ -500,8 +593,9 @@ def main(): L.append(md_table(tbl, list(tbl.columns))) L.append("\n**Table 1.** Numerical validation per method (metrics defined in §1.3). " "The GLS and MHAOV GPU kernels are single precision, bounding their parity " - "at ≈1e-6/1e-7; all other GPU paths — String-Length included, via a stable " - "phase sort on every backend — are double precision. String-Length's " + "at ≈1e-6 (GLS) / ≈1e-5 (MHAOV); all other GPU paths — String-Length " + "included, via a stable phase sort on every backend — are double " + "precision. String-Length's " "worst-case reference difference is an isolated outlier on 1–2 heavily " "phase-tied stars, where the textbook reference breaks ties with an " "unstable sort (correlation ≈1, median \\|Δ\\| ≈ 6e-12, recovered period " @@ -654,10 +748,209 @@ def _classify(ratio): L.append(f"\n- *{cat}*: {EXPL[cat]}.") L.append("\n") + if mbr is not None: + scored, scored_backend = _mbr_scored(mbr) + mb = scored[~scored.model.str.startswith("single_")].copy() + sb = scored[scored.model.str.startswith("single_")] + n_stars = int(scored.sesar_id.nunique()) + types = scored.drop_duplicates("sesar_id").rrl_type.value_counts() + gpu = mbr[mbr.backend != scored_backend] + + L.append("## 4 — Multi-band period recovery: real Stripe 82 RR Lyrae\n") + L.append( + f"§3 validates the single-band methods on real data; this section does " + f"the same for every **multi-band** method, on the canonical real " + f"multi-band test set: the SDSS Stripe 82 RR Lyrae of Sesar et al. " + f"2010 (ApJ 708, 717) — the dataset VanderPlas & Ivezić 2015 " + f"developed the shared-phase multiband periodogram on, the model that " + f"ships as cuPeriod's default `offsets` GLS. {n_stars} stars " + f"({int(types.get('ab', 0))} RRab, {int(types.get('c', 0))} RRc; the " + f"first {n_stars} of 483 by Sesar ID, no quality selection), each with " + f"real ugriz photometry (~55 epochs per band, ~280 points total) over " + f"a ~3200-day baseline, and a literature period from the discovery " + f"paper. Ground-based cadence at its most adversarial: strong ±1 " + f"cycle/day aliasing. Blind search, identical for every star: periods " + f"0.15–1.2 d at 5 samples per Rayleigh width (~97 000 trial " + f"frequencies), every method at default settings (BLS builds its " + f"native duration grid inside the same window). **strict** = top " + f"period within 1% of the literature value, no harmonic credit; " + f"**harmonic-aware** = §1.3's 2% harmonic tolerance. Bundle: " + f"`dataset/s82_rrlyrae.parquet` via " + f"`dataset/download_s82_rrlyrae.py`.\n") + + rows = [] + for band in ("u", "g", "r", "i", "z"): + s = sb[sb.model == f"single_{band}"] + if s.empty: + continue + rows.append(dict( + model=f"single-band GLS, {band}", n=len(s), + strict=fmt_pct_ci(int(s.strict.sum()), len(s)), + harmonic=fmt_pct_ci(int(s.harmonic_ok.sum()), len(s)), + dpp="—", tcpu="—", tgpu="—")) + any_hits = sb.groupby("sesar_id")["strict"].any() + rows.append(dict( + model="single-band GLS, any band", n=len(any_hits), + strict=fmt_pct_ci(int(any_hits.sum()), len(any_hits)), + harmonic="—", dpp="—", tcpu="—", tgpu="—")) + for key, label in MBR_ORDER: + g = mb[mb.model == key] + if g.empty: + continue + hits = g[g.strict] + dpp = (f"{np.median(np.abs(hits.p_top / hits.p_true - 1.0)):.1e}" + if len(hits) else "—") + gg = gpu[gpu.model == key] + tgpu = f"{gg.seconds.median():.2f}" if len(gg) else "—" + rows.append(dict( + model=f"**{label}**", n=len(g), + strict=fmt_pct_ci(int(g.strict.sum()), len(g)), + harmonic=fmt_pct_ci(int(g.harmonic_ok.sum()), len(g)), + dpp=dpp, tcpu=f"{g.seconds.median():.2f}", tgpu=tgpu)) + mtbl = pd.DataFrame(rows).rename(columns={ + "model": "model", "n": "N", "strict": "strict (1%)", + "harmonic": "harmonic-aware (2%)", "dpp": "median \\|ΔP\\|/P", + "tcpu": "t_CPU [s/★]", "tgpu": "t_GPU [s/★]"}) + L.append(md_table(mtbl, list(mtbl.columns), {"N": str})) + L.append( + "\n**Table 3.** Multi-band period recovery on real Stripe 82 RR " + "Lyrae, Wilson 95% CIs. *median \\|ΔP\\|/P* is over strict hits " + "(grid resolution is ~3e-5 of the period at these frequencies). " + "Timings are median wall time per star on the shared ~97k-frequency " + "grid, warm JIT, single shot — the batch runner amortises further " + "via engine reuse. BLS is transit-shaped by design and is included " + "for completeness, not as a recommended RR Lyrae tool.\n") + + # -- data-driven reading of the results --------------------------- + notes = [] + # which family leads on this (dense) data? + by_model = mb.groupby("model")["strict"].mean() + fold_keys = ["pdm", "ce", "stringlength", "supersmoother"] + gls_keys = ["gls_offsets", "gls_perband", "gls_flex"] + fold_best = by_model.reindex(fold_keys).max() + gls_best = by_model.reindex(gls_keys).max() + if fold_best - gls_best >= 0.05: + lblmap = dict(MBR_ORDER) + fold_name = lblmap[by_model.reindex(fold_keys).idxmax()] + notes.append( + f"The pooled fold statistics lead on these well-sampled " + f"curves: {fold_name} reaches {fold_best*100:.0f}% strict vs " + f"{gls_best*100:.0f}% for the best GLS model. With ~280 points " + "a fold uses the full non-sinusoidal light-curve shape, while " + "the single-harmonic GLS models stay alias-limited — dense " + "data reward shape, sparse data reward parsimony (see the " + "model-choice note below).") + # 1-day aliasing among non-harmonic misses + miss = mb[~mb.harmonic_ok & np.isfinite(mb.p_top)] + if len(miss): + df_alias = np.abs(1.0 / miss.p_top - 1.0 / miss.p_true) + on_alias = ((np.abs(df_alias - 1.0) < 0.05) + | (np.abs(df_alias - 2.0) < 0.05)).mean() + notes.append( + f"Of the {len(miss)} non-harmonic misses across all models, " + f"{on_alias*100:.0f}% sit on the ±1 or ±2 cycle/day window " + "aliases (Figure 7b) — the failure mode is the ground-based " + "window function, not noise.") + # fold-family: strict-vs-harmonic gap = integer-multiple picks + fold = mb[mb.model.isin(["pdm", "ce", "stringlength", "supersmoother"])] + gap = fold[fold.harmonic_ok & ~fold.strict] + if len(gap): + frac2 = (gap.ratio == 2.0).mean() + notes.append( + f"For the fold-family statistics (PDM/CE/String-Length/" + f"SuperSmoother), {len(gap)} harmonic-aware hits are not strict " + f"hits; {frac2*100:.0f}% of those sit at exactly 2P — the " + "documented integer-multiple degeneracy of phase-folding " + "statistics (a fold at 2P, 3P… of a true period stays coherent). " + "The practical recipe stands: treat the *shortest* member of a " + "near-tied family as the period, or arbitrate with " + "`cuperiod.alias_diagnostics`.") + if notes: + L.append("**Reading the result.** " + " ".join(notes) + "\n") + + # offsets vs flexible models, tied to the simulated-cadence benchmark + r_off = mb[mb.model == "gls_offsets"].strict.mean() + r_flex = mb[mb.model == "gls_flex"].strict.mean() + r_per = mb[mb.model == "gls_perband"].strict.mean() + gls_rates = (f"offsets {r_off*100:.0f}%, perband {r_per*100:.0f}%, " + f"flex {r_flex*100:.0f}% strict") + if max(r_flex, r_per) - r_off >= 0.05: + reading = ( + f"On these well-sampled curves (~280 points) the flexible GLS " + f"models beat the rigid shared-phase model ({gls_rates}): real " + f"RR Lyrae amplitudes vary strongly with wavelength (u ≈ 2× z), " + f"which `offsets` (common amplitude and phase, per-band offsets " + f"only) cannot express, and the model mismatch leaks power " + f"toward the 1-day alias.") + elif r_off - max(r_flex, r_per) >= 0.05: + reading = ( + f"Even on these well-sampled curves the shared-phase model " + f"leads ({gls_rates}).") + else: + reading = ( + f"On these well-sampled curves (~280 points) the three GLS " + f"models perform comparably ({gls_rates}).") + L.append( + f"**Model choice depends on sampling density.** {reading} " + f"The **simulated sparse-cadence benchmark** " + f"(`multiband_recovery.py`) probes the opposite regime: at 30 total " + f"epochs the shared-phase `offsets` model recovers 82% vs ≤20% for " + f"the flexible models — fewer parameters win when epochs are few. " + f"Both regimes are real; `offsets` stays the default because the " + f"sparse regime (early Rubin) is the one that needs a joint method " + f"most, and the flexible models are one `mb_model=` switch away.\n") + + gagree = np.nan + if len(gpu): + merged = gpu.merge( + mb[["sesar_id", "model", "p_top"]], + on=["sesar_id", "model"], suffixes=("", "_ref")) + gagree = (np.abs(merged.p_top / merged.p_top_ref - 1.0) + <= 1e-4).mean() + t_cpu = mb.groupby("model").seconds.median() + t_gpu = gpu.groupby("model").seconds.median() + speedup = (t_cpu / t_gpu).dropna() + gainers = speedup[speedup >= 1.5].sort_values(ascending=False) + lbl = dict(MBR_ORDER) + gain_txt = ( + "; GPU speedups ≥1.5× at this grid size: " + + ", ".join(f"{lbl.get(m, m)} {v:.1f}×" + for m, v in gainers.items()) + if len(gainers) else + "; no model gains ≥1.5× from the GPU at this single-shot size") + laggards = speedup[speedup <= 0.2].sort_values() + lag_txt = "" + if len(laggards): + verb = "is" if len(laggards) == 1 else "are" + these = "this method" if len(laggards) == 1 else "these methods" + lag_txt = ( + " " + + " and ".join(f"{lbl.get(m, m)} ({1.0/v:.0f}× slower)" + for m, v in laggards.items()) + + f" {verb} dominated by fixed per-call dispatch and " + f"transfer overhead that a single-shot call cannot " + f"amortise — for one-off searches of {these} use the " + f"CPU tier, and at catalogue scale use the batch " + f"runner, which amortises launches and reuses engines " + f"across stars.") + L.append( + f"**Backends.** The GPU pass picks the same top period as the " + f"scored {scored_backend} pass in {gagree*100:.1f}% of " + f"model×star runs. Per-star GPU timings in Table 3 are " + f"single-shot periodogram calls{gain_txt}.{lag_txt}\n") + L.append("![multiband real](figures/fig7_multiband_real.png)\n") + L.append( + "**Figure 7.** (a) Strict and harmonic-aware recovery per model; " + "the single-band GLS baseline (left of the dotted line) is what a " + "per-band search achieves on the same grid. (b) Recovered/literature " + "period ratio for every model×star pair: misses (red) concentrate " + "on the ±1 cycle/day alias loci (dotted) and the integer-multiple " + "harmonics (dashed).\n") + if inj is not None: - L.append("## 4 — Injection–recovery sensitivity\n") + L.append("## 5 — Injection–recovery sensitivity\n") n_trials = int(inj.groupby(["method", "signal_type", "snr"]).size().max()) - L.append("§2–3 validate against real, bright, well-established stars — a favourable " + L.append("§2–4 validate against real, bright, well-established stars — a favourable " "regime. This section complements that with a controlled sweep: a known " "synthetic signal of tunable amplitude, drawn onto *real* ASAS-SN " "observation cadences (so the irregular sampling and seasonal gaps of " @@ -686,7 +979,7 @@ def _classify(ratio): itbl = itbl.rename(columns=hdr) fmtd = {v: (lambda x: f"{x:.0f}%") for v in hdr.values()} L.append(md_table(itbl, ["signal", "method"] + list(hdr.values()), fmtd)) - L.append(f"\n**Table 3.** Recovery fraction (%) per method × signal × SNR, " + L.append(f"\n**Table 4.** Recovery fraction (%) per method × signal × SNR, " f"n={n_trials} trials/cell. Wilson intervals per cell are wide at this " "trial count (omitted here for readability; §3's Table 2 shows the CI " "convention on the larger real-star sample).\n") @@ -714,7 +1007,7 @@ def _classify(ratio): "method (BLS) is the appropriate tool for narrow eclipses/transits.\n") if tls is not None: - L.append("## 5 — TLS on Kepler transits\n") + L.append("## 6 — TLS on Kepler transits\n") good = (tls.cup_gpu_relerr < 0.02).mean() * 100 par = tls.cpu_gpu_parity.dropna() spd = tls.gpu_speedup.dropna() @@ -751,7 +1044,7 @@ def _classify(ratio): if "tls_ref_rel_err" in tls: refnote = (f"the `transitleastsquares` reference recovers " f"{int((tls.tls_ref_rel_err < 0.02).sum())}/{len(tls)}. ") - L.append(f"\n**Table 3.** Blind TLS period recovery on confirmed Kepler KOIs. " + L.append(f"\n**Table 5.** Blind TLS period recovery on confirmed Kepler KOIs. " f"cuPeriod recovers {n_cup}/{len(tls)}; {refnote}Both miss only the " "shallowest transits, where a blind 0.5–12 d search aliases — a failure " "mode shared with the reference implementation, not a backend defect.\n") @@ -760,7 +1053,7 @@ def _classify(ratio): "and `transitleastsquares`; (b) GPU speedup on the CPU-timed subset.\n") if single is not None: - L.append("## 6 — Performance\n") + L.append("## 7 — Performance\n") s = single.copy() s = s.set_index("method").reindex([m for m in METHOD_ORDER if m in set(single.method)]).reset_index() bls = s[s.method == "BLS"] @@ -796,7 +1089,7 @@ def _classify(ratio): "CPU vs ref": nan_dash(lambda v: f"{v:.0f}×"), "t_ref [s]": nan_dash(lambda v: f"{v:.2f}"), "method": ml})) - L.append("\n**Table 4.** Single-curve wall time per method (methodology in §1.2). " + L.append("\n**Table 6.** Single-curve wall time per method (methodology in §1.2). " "*CPU backend* = what `backend=\"cpu\"` resolves to — the fast default a " "user gets: finufft (GLS), the multicore numba box search (BLS), numba for " "the rest (with the `[fast]` extra) or numpy otherwise. *CPU vs ref* = " @@ -804,19 +1097,26 @@ def _classify(ratio): "CUDA backend over cuPeriod's own CPU backend. *t_torch* = the portable " "PyTorch backend (device in *torch device*: cpu/cuda/mps/xpu) — the " "cross-vendor path that also runs on AMD/Intel/Mac GPUs.\n") - L.append("cuPeriod's CPU path already outperforms every external reference tool it " - "has (GLS, PDM, BLS). **With the multicore numba tier, the GPU's " - "single-curve margin over the CPU is modest almost everywhere** on this " - "16-core machine — 2–4× for BLS/String-Length/TLS, essentially a wash for " - "PDM/CE, and the GPU is slower than the warm CPU kernel for MHAOV at this " - "size. GLS is the one consistent exception (~3×): its CPU path is finufft, " - "not a numba kernel. The scaling sweep (up to 30 000 points / a " - "100 000-frequency grid; Figure 5b) shows the same pattern across that whole " - "range for PDM and MHAOV — the GPU's fixed per-call overhead (kernel launch, " - "host↔device transfer) does not amortise at these problem sizes on a CPU " - "this wide. The GPU's case is catalogue throughput and non-NVIDIA hardware " - "(the portable torch backend), not single-curve latency on the CPU-tier " - "methods; see §7.\n") + gsp = s.dropna(subset=["gpu_speedup"]).set_index("method").gpu_speedup + fast = [(m, v) for m, v in gsp.items() if v >= 2.0] + wash = [(m, v) for m, v in gsp.items() if 0.8 <= v < 2.0] + slow = [(m, v) for m, v in gsp.items() if v < 0.8] + _fmt = lambda pairs: (", ".join(f"{ml(m)} ({v:.1f}×)" for m, v in pairs) + if pairs else "none") + gls_note = (" GLS's edge reflects its CPU path being finufft rather than a " + "numba kernel." if any(m == "GLS" for m, _ in fast) else "") + L.append("cuPeriod's CPU path already outperforms every external reference tool " + "it has (GLS, PDM, BLS). **With the multicore numba tier, the GPU's " + "single-curve margin over the CPU is modest almost everywhere** on " + f"this 16-core machine: a ≥2× win for {_fmt(fast)}; a wash (0.8–2×) " + f"for {_fmt(wash)}; slower than the warm CPU kernel for {_fmt(slow)} " + "at this size — fixed per-call dispatch and transfer overhead does " + f"not amortise once the CPU kernel itself runs in milliseconds." + f"{gls_note} The scaling sweep (up to 30 000 points / a " + "100 000-frequency grid; Figure 5b) shows where that balance shifts " + "with problem size. The GPU's case is catalogue throughput and " + "non-NVIDIA hardware (the portable torch backend), not single-curve " + "latency on the CPU-tier methods; see §8.\n") if len(bls) and "cpu_port_s" in bls and np.isfinite(bls.cpu_port_s.iloc[0]): b = bls.iloc[0] L.append(f"\n> The pure-`numpy` BLS backend shares one array-module-generic source " @@ -837,7 +1137,7 @@ def _classify(ratio): f"**>{gpeak.gpu_lc_per_s*3600/1e6:.1f} million light curves/hour**. " f"This is a *single-batch* rate that includes the one-off worker-pool " f"spin-up (process spawn + per-worker CUDA context); a warmed pool " - f"sustains a higher rate (≈490 lc/s here) over many chunks.") + f"sustains a higher rate over many chunks.") if len(cmp): rows_txt = "; ".join( f"{ml(r.method)} n={int(r.n_lc)} {r.speedup:.1f}×" @@ -850,7 +1150,7 @@ def _classify(ratio): L.append(msg + "\n") if single is not None: - L.append("## 7 — Backend recommendations\n") + L.append("## 8 — Backend recommendations\n") rec = backend_recommendations( single.set_index("method") .reindex([m for m in METHOD_ORDER if m in set(single.method)]) @@ -859,41 +1159,58 @@ def _classify(ratio): "fastest": "fastest measured", "t_best": "best time", "gpu_over_cpu": "GPU vs CPU", "recommendation": "single-curve recommendation"}) L.append(md_table(rec, list(rec.columns))) - L.append("\n**Table 5.** Fastest measured backend per method on this machine " - "(single curve, ~900 points; grids as in Table 4).\n") + L.append("\n**Table 7.** Fastest measured backend per method on this machine " + "(single curve, ~900 points; grids as in Table 6).\n") + slow_names = "/".join(ml(m) for m, _ in slow) if slow else "none" + fast_names = "/".join(ml(m) for m, _ in fast) if fast else "none" + gls_grid_txt = "" + if grid is not None and (grid.method == "GLS").any(): + gg = grid[grid.method == "GLS"].speedup.dropna() + if len(gg): + gls_grid_txt = (f" — GLS holds {gg.min():.1f}–{gg.max():.1f}× across " + f"the grid-size sweep") + peak_txt = "hundreds of curves/s" + if batch is not None and len(batch): + pk = batch.gpu_lc_per_s.max() + peak_txt = f"{pk:,.0f} curves/s (>{pk*3600/1e6:.0f} million curves/hour)" + numba_txt = "much slower" + nb = single[single.method == "BLS"] + if len(nb) and "cpu_port_s" in nb and np.isfinite(nb.cpu_port_s.iloc[0]): + numba_txt = (f"~{nb.cpu_port_s.iloc[0]:.0f} s vs " + f"{nb.cpu_s.iloc[0]:.2f} s with numba") L.append("Guidance by use case, from the measurements above:\n") L.append("1. **Interactive, single-curve analysis (default).** Use " "`backend=\"cpu\"` with the `[fast]` extra installed. On a modern " "multi-core CPU it is within a small factor of the GPU on every method, " - "faster than the GPU for PDM/CE/MHAOV at typical light-curve sizes, and " + f"faster than the GPU for {slow_names} at typical light-curve sizes, and " "already 2–2000× faster than the established external tools. No GPU is " "required for competitive single-curve performance.\n" "2. **GLS-dominated pipelines on NVIDIA hardware.** Use `backend=\"gpu\"`: " - "GLS is the one method with a consistent GPU advantage (~3× single-curve, " - "~1.4× at batch scale), because its CPU path is finufft rather than a " - "numba kernel.\n" + f"{fast_names} show a consistent single-curve GPU advantage " + f"(Table 6{gls_grid_txt}; GLS keeps ~1.4× at batch scale too, because " + "its CPU path is finufft rather than a numba kernel).\n" "3. **Catalogue-scale processing (10³–10⁶ curves).** Use " "`batch_periodograms(..., device=\"gpu\")` on NVIDIA hardware — peak " - "measured throughput 587 curves/s (>2 million curves/hour) on one GPU. On " + f"measured throughput {peak_txt} on one GPU. On " "this 32-thread CPU the process pool keeps pace for the numba-tier " "methods, so on wide CPU nodes `device=\"cpu\"` is a legitimate " "alternative; expect the GPU margin to widen on narrower CPUs and larger " "batches.\n" "4. **AMD, Intel or Apple GPUs.** Use `backend=\"torch\"` — the portable " - "path validated to the same parity standard. On NVIDIA hardware it is " - "slower than the native CUDA backend (Table 4), so treat it as the " - "portability path, not the speed path.\n" + "path validated to the same parity standard. On NVIDIA hardware the " + "native CUDA backend is usually at least as fast (Table 6), so treat " + "torch as the portability path, not the speed path.\n" "5. **Strict double-precision requirements.** The GLS and MHAOV CUDA " - "kernels are single precision (parity ≈1e-6/1e-7; Table 1). The selected " + "kernels are single precision (parity ≈1e-6 / ≈1e-5; Table 1). The selected " f"best period was unaffected on all {len(meta)} validation stars, but if statistic " "values matter beyond ~6 significant digits (e.g. FAP tail comparisons), " "use the CPU backend, which is double precision throughout.\n" "6. **Minimal installations (no numba).** `backend=\"cpu\"` falls back to " "numpy — numerically identical but much slower for the box methods (the " - "pure-numpy BLS parity reference takes ~18 s vs 0.19 s with numba). " + f"pure-numpy BLS parity reference takes {numba_txt}). " "Install the `[fast]` extra, or use `backend=\"astropy\"` for BLS.\n") - L.append("## 8 — Limitations\n") + L.append("## 9 — Limitations\n") L.append("- All timings are from a single machine (Table in §1.1); CPU↔GPU ratios " "depend strongly on core count. The 16-core/32-thread CPU used here is near " "the top of the desktop range, so the reported GPU margins are conservative " @@ -901,41 +1218,50 @@ def _classify(ratio): "- Batch throughput was swept only to 4096 curves per batch and is a " "single-shot rate including worker-pool start-up; sustained throughput and " "larger batches favour the GPU further.\n" - "- The GLS and MHAOV GPU statistics are single precision (§7, item 5).\n" + "- The GLS and MHAOV GPU statistics are single precision (§8, item 5).\n" "- The torch backend was timed on a CUDA device only; Apple (mps) and Intel " "(xpu) devices are supported but not benchmarked here.\n" "- The TLS blind search uses a fixed 0.5–12 d window; the unrecovered KOIs " "are the shallowest transits, which alias within that window (the reference " - "implementation misses one of the same targets; §5). The recovery rate " + "implementation misses one of the same targets; §6). The recovery rate " "therefore reflects the search configuration as much as the implementation.\n" + "- The real multi-band validation (§4) covers one variable class (RR Lyrae) " + "on well-sampled ~280-point curves; the sparse-cadence regime is covered by " + "the simulated `multiband_recovery.py` benchmark, not by real data. BLS is " + "included there for completeness but is transit-shaped by design.\n" "- Recovery rates are measured on light curves with well-established " "literature periods and moderate noise; they are upper bounds relative to " "survey-quality data with weaker signals.\n") - L.append("## 9 — References\n") + L.append("## 10 — References\n") L.append("Method papers: " "GLS — Zechmeister & Kürster 2009, A&A 496, 577; " - "Lomb–Scargle practicalities — VanderPlas 2018, ApJS 236, 16. " + "Lomb–Scargle practicalities — VanderPlas 2018, ApJS 236, 16; " + "multiband GLS — VanderPlas & Ivezić 2015, ApJ 812, 18. " "BLS — Kovács, Zucker & Mazeh 2002, A&A 391, 369. " "PDM — Stellingwerf 1978, ApJ 224, 953. " "Conditional Entropy — Graham et al. 2013, MNRAS 434, 2629. " "String Length — Dworetsky 1983, MNRAS 203, 917. " "MHAOV — Schwarzenberg-Czerny 1996, ApJ 460, L107. " - "TLS — Hippke & Heller 2019, A&A 623, A39.\n") + "TLS — Hippke & Heller 2019, A&A 623, A39. " + "SuperSmoother — Friedman 1984; Reimann 1994.\n") L.append("Reference software: Astropy Collaboration 2022, ApJ 935, 167; " "PyAstronomy — Czesla et al. 2019, ascl:1906.010; " "`transitleastsquares` — Hippke & Heller 2019.\n") L.append("Data: ASAS-SN — Shappee et al. 2014, ApJ 788, 48; Kochanek et al. 2017, " "PASP 129, 104502. VSX — Watson, Henden & Price 2006, SASS 25, 47. " - "Kepler KOI light curves via MAST/lightkurve.\n") + "SDSS Stripe 82 RR Lyrae — Sesar et al. 2010, ApJ 708, 717 (files via the " + "astroML-data mirror). Kepler KOI light curves via MAST/lightkurve.\n") - L.append("## 10 — Reproducibility\n" + L.append("## 11 — Reproducibility\n" "The validation light curves and their literature periods ship in " - "`dataset/light_curves.parquet`; §2, §3, §4 and §6 need no network access or " - "external catalogue. The Kepler/TLS comparison (§5) downloads flux from MAST " - "and runs `transitleastsquares` in a separate pinned environment.\n```\n" + "`dataset/light_curves.parquet` and `dataset/s82_rrlyrae.parquet`; §2, §3, " + "§4, §5 and §7 need no network access or external catalogue. The Kepler/TLS " + "comparison (§6) downloads flux from MAST and runs `transitleastsquares` in " + "a separate pinned environment.\n```\n" "python benchmarks/validate_periodograms.py # 1-1 validation (main GPU venv)\n" - "python benchmarks/injection_recovery.py # synthetic sensitivity sweep (§4)\n" + "python benchmarks/multiband_real.py # real S82 multi-band recovery (§4)\n" + "python benchmarks/injection_recovery.py # synthetic sensitivity sweep (§5)\n" "python benchmarks/benchmark.py # performance\n" ".venv-ref/.../python benchmarks/tls_download_ref.py # Kepler + transitleastsquares\n" "python benchmarks/tls_cuperiod.py # cuPeriod TLS\n" diff --git a/benchmarks/multiband_real.py b/benchmarks/multiband_real.py new file mode 100644 index 0000000..8e4cfed --- /dev/null +++ b/benchmarks/multiband_real.py @@ -0,0 +1,277 @@ +"""Validate every multi-band method on real SDSS Stripe 82 RR Lyrae. + +The companion to ``multiband_recovery.py`` (which is simulated): the same +question -- do the joint multi-band searches find the right period? -- asked of +**real survey photometry with literature answers**. The data are the Sesar et +al. 2010 (ApJ 708, 717) Stripe 82 RR Lyrae: real SDSS ugriz cadence over ~10 +years, including the 1-day alias structure of ground-based sampling, with +periods known from the discovery paper. This is the dataset VanderPlas & +Ivezic 2015 built the shared-phase multiband model on -- the model that ships +as cuPeriod's default ``offsets`` GLS -- so it doubles as an end-to-end check +against that paper's headline result. Bundle: ``dataset/s82_rrlyrae.parquet`` +(first 100 stars by Sesar ID, no quality selection; see +``dataset/download_s82_rrlyrae.py``). + +Setup +----- +* Blind search, identical for every star: periods 0.15-1.2 d (brackets the + RR Lyrae instability strip; the bundle spans 0.26-0.91 d), uniform frequency + grid at 5 samples per Rayleigh width of each star's ~3200 d baseline + (~96k trial frequencies). BLS builds its native duration/period grid inside + the same period window, as elsewhere in the suite. +* Every multi-band method at default settings: GLS in all three models + (``offsets``, ``perband``, ``flex``), PDM, conditional entropy, + string-length, MHAOV, SuperSmoother, and BLS (transit-shaped by design; it + is included for completeness and read with that caveat). +* Single-band GLS on each of u,g,r,i,z as the baseline the joint methods must + beat; a band with too few points counts as a non-recovery. +* Scoring follows the suite: **strict** = top period within 1% of Sesar's, no + harmonic credit (as in ``multiband_recovery.py``); **harmonic-aware** = the + top period matches up to a small-integer harmonic ratio within 2% + (``_common.period_match``). Fold-family statistics (PDM/CE/SL and + SuperSmoother) are genuinely periodic at integer multiples of the true + period, so for them the strict column mostly measures multiple/submultiple + picks rather than wrong periods -- report both, judge with both. + +Backends: the ``cpu`` pass (numba/finufft tiers) is the scored reference; a +``gpu`` pass records its own top periods and timings so agreement and speed +are reported from the same run. Per-call timing includes any per-call GPU +plan/kernel setup (a warm-up pass absorbs one-time JIT/compile); the batch +runner amortizes more via engine reuse. + +Writes results/multiband_real.parquet and prints the summary tables. + +Run (main .venv, GPU optional): + + .venv/Scripts/python.exe benchmarks/multiband_real.py +""" + +from __future__ import annotations + +import argparse +import time +import warnings +from pathlib import Path + +import numpy as np +import pandas as pd + +warnings.filterwarnings("ignore") +from _common import DATASET, RESULTS, period_match # noqa: E402 + +import cuperiod as cup # noqa: E402 + +S82_PARQUET = DATASET / "s82_rrlyrae.parquet" +P_MIN_DAYS, P_MAX_DAYS = 0.15, 1.2 +SAMPLES_PER_PEAK = 5 +REL_TOL_STRICT = 0.01 +BANDS = ("u", "g", "r", "i", "z") + +_GLS_BASE = {"fap_method": "none"} +MB_MODELS: dict[str, tuple[str, object]] = { + "gls_offsets": ("GLS", cup.GLSSettings(**_GLS_BASE)), + "gls_perband": ("GLS", cup.GLSSettings(mb_model="perband", **_GLS_BASE)), + "gls_flex": ("GLS", cup.GLSSettings(mb_model="flex", **_GLS_BASE)), + "pdm": ("PDM", cup.PDMSettings()), + "ce": ("CE", cup.CESettings()), + "stringlength": ("STRINGLENGTH", cup.StringLengthSettings()), + "mhaov": ("MHAOV", cup.MHAOVSettings()), + "supersmoother": ("SUPERSMOOTHER", cup.SuperSmootherSettings()), + "bls": ("BLS", cup.BLSSettings( + min_period_days=P_MIN_DAYS, max_period_days=P_MAX_DAYS, + )), +} +# BLS owns its period/duration grid; everything else shares the star's grid. +NATIVE_GRID_MODELS = frozenset({"bls"}) + + +def load_stars() -> list[tuple[int, str, float, cup.MultiBandLightCurve]]: + df = pd.read_parquet(S82_PARQUET) + stars = [] + for sesar_id, group in df.groupby("sesar_id", sort=True): + bands = { + str(r.band): cup.LightCurve.from_arrays( + np.asarray(r.mjd, dtype=np.float64), + np.asarray(r.mag, dtype=np.float64), + np.asarray(r.mag_err, dtype=np.float64), + ) + for r in group.itertuples() + if len(r.mjd) > 0 + } + first = group.iloc[0] + stars.append(( + int(sesar_id), str(first.rrl_type), float(first.p_sesar), + cup.MultiBandLightCurve.from_light_curves(bands), + )) + return stars + + +def star_grid(mblc: cup.MultiBandLightCurve) -> cup.GridSpec: + time_all = mblc.finite().stacked()[0] + baseline = float(time_all.max() - time_all.min()) + df = 1.0 / (SAMPLES_PER_PEAK * baseline) + values = np.arange(1.0 / P_MAX_DAYS, 1.0 / P_MIN_DAYS, df) + return cup.GridSpec(kind="frequency", values=values, uniform=True) + + +def top_period(pg: cup.Periodogram) -> float: + power = np.asarray(pg.power, dtype=np.float64) + idx = int( + np.argmin(power) if pg.objective_sense == "min" else np.argmax(power) + ) + return float(1.0 / pg.frequency[idx]) + + +def run_star( + model: str, + mblc: cup.MultiBandLightCurve, + grid: cup.GridSpec, + backend: str, +) -> tuple[float, float]: + """Return (top period, wall seconds) for one model on one star.""" + method, settings = MB_MODELS[model] + t0 = time.perf_counter() + pg = cup.periodogram( + mblc, method, backend=backend, + grid=None if model in NATIVE_GRID_MODELS else grid, + settings=settings, + ) + seconds = time.perf_counter() - t0 + assert isinstance(pg, cup.Periodogram) + return top_period(pg), seconds + + +def run(backends: list[str], limit: int | None, out_path: Path) -> pd.DataFrame: + stars = load_stars() + if limit is not None: + stars = stars[:limit] + grids = {sid: star_grid(mblc) for sid, _, _, mblc in stars} + n_freq = int(np.median([g.frequency.size for g in grids.values()])) + print(f"{len(stars)} stars, blind {P_MIN_DAYS}-{P_MAX_DAYS} d " + f"(~{n_freq} trial frequencies), backends {backends}") + + # Absorb one-time JIT/kernel-compile cost so per-star timings are steady + # state. The first star is then re-run inside the timed loop. + sid0, _, _, mblc0 = stars[0] + for backend in backends: + for model in MB_MODELS: + run_star(model, mblc0, grids[sid0], backend) + + rows: list[dict[str, object]] = [] + t_start = time.perf_counter() + for backend in backends: + for k, (sesar_id, rrl_type, p_true, mblc) in enumerate(stars, 1): + for model in MB_MODELS: + p_top, seconds = run_star(model, mblc, grids[sesar_id], backend) + ok, ratio = period_match(p_top, p_true) + rows.append({ + "sesar_id": sesar_id, "rrl_type": rrl_type, + "p_true": p_true, "model": model, "backend": backend, + "p_top": p_top, "seconds": seconds, + "strict": abs(p_top / p_true - 1.0) <= REL_TOL_STRICT, + "harmonic_ok": ok, "ratio": ratio, + }) + if backend == backends[0]: + # Single-band GLS baseline (scored pass only). + for band in BANDS: + lc = mblc.bands.get(band) + p_top = np.nan + if lc is not None: + try: + pg = cup.periodogram( + lc, "GLS", backend=backend, + grid=grids[sesar_id], + settings=MB_MODELS["gls_offsets"][1], + ) + assert isinstance(pg, cup.Periodogram) + p_top = top_period(pg) + except cup.InsufficientDataError: + pass + ok, ratio = period_match(p_top, p_true) + rows.append({ + "sesar_id": sesar_id, "rrl_type": rrl_type, + "p_true": p_true, "model": f"single_{band}", + "backend": backend, "p_top": p_top, "seconds": np.nan, + "strict": bool( + np.isfinite(p_top) + and abs(p_top / p_true - 1.0) <= REL_TOL_STRICT + ), + "harmonic_ok": ok, "ratio": ratio, + }) + if k % 20 == 0: + print(f" {backend}: {k}/{len(stars)} stars, " + f"{time.perf_counter() - t_start:.0f}s", flush=True) + # Checkpoint after each backend pass so a crash or kill in a later + # pass cannot lose the scored results. + pd.DataFrame(rows).to_parquet(out_path, index=False) + print(f" checkpoint: {backend} pass written " + f"({len(rows)} rows)", flush=True) + return pd.DataFrame(rows) + + +def summarize(df: pd.DataFrame, scored_backend: str) -> None: + scored = df[df["backend"] == scored_backend] + n_stars = scored["sesar_id"].nunique() + + single = scored[scored["model"].str.startswith("single_")] + any_band = single.groupby("sesar_id")["strict"].any() + print(f"\nSingle-band GLS baseline ({n_stars} stars, strict within 1%):") + for band in BANDS: + frac = single[single["model"] == f"single_{band}"]["strict"].mean() + print(f" {band}: {frac:.1%}") + print(f" any band: {any_band.mean():.1%}") + + mb = scored[~scored["model"].str.startswith("single_")] + print(f"\nMulti-band methods ({n_stars} stars):") + print("| model | strict (1%) | harmonic-aware (2%) | median |dP|/P " + "| median s/star |") + print("|---|---|---|---|---|") + for model in MB_MODELS: + g = mb[mb["model"] == model] + hits = g[g["strict"]] + frac_err = np.median(np.abs(hits["p_top"] / hits["p_true"] - 1.0)) + print(f"| {model} | {g['strict'].mean():.1%} " + f"| {g['harmonic_ok'].mean():.1%} " + f"| {frac_err:.1e} | {g['seconds'].median():.3f} |") + + other = [b for b in df["backend"].unique() if b != scored_backend] + for backend in other: + alt = df[(df["backend"] == backend) + & ~df["model"].str.startswith("single_")] + merged = alt.merge( + mb[["sesar_id", "model", "p_top"]], on=["sesar_id", "model"], + suffixes=("", "_ref"), + ) + agree = (np.abs(merged["p_top"] / merged["p_top_ref"] - 1.0) + <= 1e-4).mean() + print(f"\n{backend} backend: top period agrees with {scored_backend} " + f"for {agree:.1%} of runs; median s/star by model:") + for model in MB_MODELS: + sec = alt[alt["model"] == model]["seconds"].median() + ref = mb[mb["model"] == model]["seconds"].median() + print(f" {model}: {sec:.3f}s (vs {ref:.3f}s {scored_backend})") + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--backends", default="cpu,gpu", + help="comma-separated; first one is the scored pass") + parser.add_argument("--limit", type=int, default=None, + help="run only the first N stars (smoke test)") + parser.add_argument("--out", type=Path, + default=RESULTS / "multiband_real.parquet", + help="output parquet (point a smoke run elsewhere so it " + "cannot clobber the committed results)") + args = parser.parse_args() + backends = [b.strip() for b in args.backends.split(",") if b.strip()] + + df = run(backends, args.limit, args.out) + out = args.out + df.to_parquet(out, index=False) + print(f"\nwrote {out}", flush=True) + summarize(df, backends[0]) + print("\nMULTIBAND_REAL_DONE", flush=True) + + +if __name__ == "__main__": + main() diff --git a/benchmarks/multiband_recovery.py b/benchmarks/multiband_recovery.py new file mode 100644 index 0000000..3b0878b --- /dev/null +++ b/benchmarks/multiband_recovery.py @@ -0,0 +1,174 @@ +"""Multi-band vs single-band period recovery under Rubin/LSST-like cadence. + +The motivating result for the multi-band methods: Rubin's alert-production study +found single-band Lomb-Scargle recovers periods poorly at LSST cadence while the +joint multi-band periodogram recovers most RR Lyrae. This benchmark reproduces +that comparison end-to-end with cuPeriod's native models on simulated RRab-like +stars observed with a sparse six-band cadence. + +Setup (deliberately simple, stated so the numbers can be judged): + +* 3-year campaign; per-band epochs land on random nights with a random + within-night time (no rolling cadence, no lunation weighting). +* The per-band epoch share follows the WFD flavor (r/i deepest: + u 6%, g 9%, r 26%, i 26%, z 17%, y 16%); the *total* number of epochs across + all six bands is swept (30 / 60 / 120) to span the first survey years. +* RRab proxy: fundamental sine plus a phase-locked 0.35-amplitude second + harmonic; period ~ U(0.35, 0.9) d; g amplitude ~ U(0.5, 1.0) mag scaled by + band (u 1.05, g 1.0, r 0.72, i 0.57, z 0.53, y 0.48); photometric noise + 0.20 mag per point by default (--noise) — an r ~ 23 halo RR Lyrae in + single Rubin visits, the population the multiband methods exist for. +* Recovery = the periodogram's top period within 1% of the truth, no harmonic + credit. + +Strategies compared per star, all on the same frequency grid: + + r-band GLS single-band on the best-sampled band + any-band GLS recovered if ANY band's top period matches (optimistic + upper bound for per-band searching) + multiband offsets shared-phase (1, 0) model (cuPeriod default) + multiband perband chi2_0-weighted per-band combination (0, 1) + multiband flex regularized (1, 1) model + +Writes results/multiband_recovery.parquet and prints the recovery table. +""" + +from __future__ import annotations + +import argparse +import time +import warnings + +import numpy as np +import pandas as pd + +warnings.filterwarnings("ignore") +import cuperiod as cup # noqa: E402 + +from _common import RESULTS # noqa: E402 + +SEED = 42 +SPAN_DAYS = 3.0 * 365.25 +BANDS = ("u", "g", "r", "i", "z", "y") +BAND_SHARE = {"u": 0.06, "g": 0.09, "r": 0.26, "i": 0.26, "z": 0.17, "y": 0.16} +AMP_SCALE = {"u": 1.05, "g": 1.00, "r": 0.72, "i": 0.57, "z": 0.53, "y": 0.48} +MEAN_MAG = {"u": 23.4, "g": 22.8, "r": 22.5, "i": 22.4, "z": 22.4, "y": 22.3} +NOISE_MAG = 0.20 +HARMONIC_FRACTION = 0.35 +EPOCH_BUDGETS = (30, 60, 120) +REL_TOL = 0.01 + + +def simulate_star( + rng: np.random.Generator, total_epochs: int, noise: float +) -> tuple[cup.MultiBandLightCurve, float]: + """One RRab-like star on a sparse six-band cadence; returns (bands, period).""" + period = float(rng.uniform(0.35, 0.9)) + amp_g = float(rng.uniform(0.5, 1.0)) + phase = float(rng.uniform(0.0, 2.0 * np.pi)) + bands: dict[str, cup.LightCurve] = {} + for band in BANDS: + n = max(3, int(round(total_epochs * BAND_SHARE[band]))) + nights = rng.integers(0, int(SPAN_DAYS), size=n) + t = np.sort(nights + rng.uniform(0.05, 0.45, size=n)) + amp = amp_g * AMP_SCALE[band] + signal = amp * np.sin(2 * np.pi * t / period + phase) + signal += HARMONIC_FRACTION * amp * np.sin( + 2 * (2 * np.pi * t / period + phase) + ) + err = np.full(n, noise) + mag = MEAN_MAG[band] + signal + rng.normal(0.0, noise, size=n) + bands[band] = cup.LightCurve.from_arrays(t, mag, err) + return cup.MultiBandLightCurve.from_light_curves(bands), period + + +def top_period(power: np.ndarray, frequency: np.ndarray) -> float: + return float(1.0 / frequency[int(np.argmax(power))]) + + +def recovered(p_found: float, p_true: float) -> bool: + return abs(p_found / p_true - 1.0) <= REL_TOL + + +def run(n_stars: int, backend: str, noise: float) -> pd.DataFrame: + from cuperiod.multiband.gls_mb import gls_multiband_power + + grid = cup.GridSpec( + kind="frequency", + values=np.arange(0.05, 3.5, 1.0 / (5.0 * SPAN_DAYS)), + uniform=True, + ) + frequency = grid.frequency + settings = { + "offsets": cup.GLSSettings(fap_method="none"), + "perband": cup.GLSSettings(mb_model="perband", fap_method="none"), + "flex": cup.GLSSettings(mb_model="flex", fap_method="none"), + } + rows: list[dict[str, object]] = [] + rng = np.random.default_rng(SEED) + t0 = time.perf_counter() + for budget in EPOCH_BUDGETS: + for star in range(n_stars): + mblc, p_true = simulate_star(rng, budget, noise) + row: dict[str, object] = { + "star": star, "epochs": budget, "p_true": p_true, + } + band_hits = {} + for band, lc in mblc.bands.items(): + # A band too sparse to fit alone counts as a non-recovery for + # the single-band strategies -- that sparsity is the point. + try: + pg = cup.periodogram( + lc, "GLS", backend=backend, grid=grid, + settings=settings["offsets"], + ) + assert isinstance(pg, cup.Periodogram) + band_hits[band] = recovered( + top_period(pg.power, frequency), p_true + ) + except cup.InsufficientDataError: + band_hits[band] = False + row["r_band"] = band_hits["r"] + row["any_band"] = any(band_hits.values()) + for model, s in settings.items(): + pg_mb = gls_multiband_power(grid, mblc, s, backend) + row[f"mb_{model}"] = recovered( + top_period(pg_mb.power, frequency), p_true + ) + rows.append(row) + done = len(rows) + print(f" budget {budget}: {done} rows, {time.perf_counter() - t0:.0f}s") + return pd.DataFrame(rows) + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("--n-stars", type=int, default=250) + parser.add_argument("--backend", default="finufft") + parser.add_argument("--noise", type=float, default=NOISE_MAG, + help="per-point photometric noise (mag)") + args = parser.parse_args() + + print(f"multiband recovery: {args.n_stars} stars x {EPOCH_BUDGETS} epochs, " + f"noise {args.noise} mag, backend {args.backend}") + df = run(args.n_stars, args.backend, args.noise) + out = RESULTS / "multiband_recovery.parquet" + df.to_parquet(out) + print(f"wrote {out}") + + strategies = ["r_band", "any_band", "mb_perband", "mb_flex", "mb_offsets"] + summary = df.groupby("epochs")[strategies].mean().T + summary.index.name = "strategy" + print("\nRecovery fraction (top period within 1%, no harmonic credit):\n") + header = "| strategy | " + " | ".join( + f"{e} epochs" for e in summary.columns + ) + " |" + print(header) + print("|" + "---|" * (len(summary.columns) + 1)) + for name, vals in summary.iterrows(): + cells = " | ".join(f"{v:.1%}" for v in vals) + print(f"| {name} | {cells} |") + + +if __name__ == "__main__": + main() diff --git a/benchmarks/results/bench_batch.parquet b/benchmarks/results/bench_batch.parquet index 3aba2a4..be3662b 100644 Binary files a/benchmarks/results/bench_batch.parquet and b/benchmarks/results/bench_batch.parquet differ diff --git a/benchmarks/results/bench_grid.parquet b/benchmarks/results/bench_grid.parquet index 76447f2..d02ba36 100644 Binary files a/benchmarks/results/bench_grid.parquet and b/benchmarks/results/bench_grid.parquet differ diff --git a/benchmarks/results/bench_npoints.parquet b/benchmarks/results/bench_npoints.parquet index a2c7fe0..d0f3d4b 100644 Binary files a/benchmarks/results/bench_npoints.parquet and b/benchmarks/results/bench_npoints.parquet differ diff --git a/benchmarks/results/bench_single.parquet b/benchmarks/results/bench_single.parquet index d2f203a..ba6b4d6 100644 Binary files a/benchmarks/results/bench_single.parquet and b/benchmarks/results/bench_single.parquet differ diff --git a/benchmarks/results/multiband_real.parquet b/benchmarks/results/multiband_real.parquet new file mode 100644 index 0000000..81d2f1f Binary files /dev/null and b/benchmarks/results/multiband_real.parquet differ diff --git a/benchmarks/results/multiband_recovery.parquet b/benchmarks/results/multiband_recovery.parquet new file mode 100644 index 0000000..cd7954d Binary files /dev/null and b/benchmarks/results/multiband_recovery.parquet differ diff --git a/docs/api/index.md b/docs/api/index.md index 9f306d8..f241a7c 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -27,6 +27,67 @@ The two functions most users need, plus their helpers. to_input ``` +## Pre-whitening + +Automated frequency extraction for pulsators, and the g-mode period-spacing tools that +follow it (see {doc}`../guide/prewhitening`). + +```{eval-rst} +.. autosummary:: + :toctree: generated + :nosignatures: + + prewhiten + batch_prewhiten + PreWhitenResult + Sinusoid + Combination + identify_combinations + fit_multisine + MultiSineFit + amplitude_spectrum + spectral_window + baluev_fap + AmplitudeSpectrum + SpectrumEngine + find_period_spacing + PeriodSpacingSeries + spacing_spectrum + SpacingSpectrum + echelle + buoyancy_radius +``` + +## Multi-band + +Joint multi-band false-alarm calibration (see {doc}`../guide/multiband`). The multi-band +models themselves are selected through {class}`GLSSettings` and run through +{func}`periodogram`. + +```{eval-rst} +.. autosummary:: + :toctree: generated + :nosignatures: + + multiband_fap + MultibandFAP +``` + +## Diagnostics + +Is the best peak the true frequency, or a sidelobe of the sampling's spectral window? + +```{eval-rst} +.. autosummary:: + :toctree: generated + :nosignatures: + + alias_diagnostics + AliasReport + AliasCandidate + WindowPeak +``` + ## Light curves & inputs Containers for the data, and the column/domain mapping that ingests heterogeneous tables. @@ -71,7 +132,10 @@ Per-method tuning models (see {doc}`../guide/tuning`). CESettings MHAOVSettings StringLengthSettings + SuperSmootherSettings TLSSettings + PreWhitenSettings + SpacingSettings BatchSettings ``` @@ -131,6 +195,27 @@ The batch run summary (see {doc}`../guide/batch`). BatchSummary ``` +## LINCC interoperability + +Adapters for nested-pandas / lsdb catalogs (see {doc}`../guide/interop`). These live in +the optional `cuperiod.interop` subpackage — `pip install "cuperiod[nested]"` — and are +imported from there, not from the top level. + +```{eval-rst} +.. autosummary:: + :toctree: generated + :nosignatures: + + interop.nested_periodogram + interop.partition_periodogram + interop.resolve_nested_columns + interop.NestedColumns + interop.COLUMN_PRESETS +``` + +The survey column layouts {data}`~cuperiod.interop.COLUMN_PRESETS` accepts as +`preset=` are tabulated in {doc}`../guide/interop`. + ## Exceptions All cuPeriod errors derive from {class}`CuPeriodError`, so a single `except` catches the diff --git a/docs/benchmarks.md b/docs/benchmarks.md index b6b123d..14b21d5 100644 --- a/docs/benchmarks.md +++ b/docs/benchmarks.md @@ -13,6 +13,11 @@ broaden coverage of harder classes. TLS is validated on 12 confirmed Kepler KOIs curves and their literature periods ship with the suite, so §1–2 and §4 are fully reproducible offline. +§1, §2, §4 and §5 below cover the seven methods that go through the single-band validation +suite. SuperSmoother, new in this release, is pinned in the unit tests against the reference +`supersmoother` package and `gatspy` ({doc}`guide/methods`), joins the performance sweep +in §3, and is validated on real data alongside every other multi-band method in §7. + ## 1. Numerical validation Every method runs the **same grid** through cuPeriod's CPU and GPU backends and through an @@ -74,7 +79,7 @@ agree to round-off) and cuPeriod↔**reference** (must match an established impl ``` *parity* is the worst-case relative difference between the CPU and GPU statistic over all -stars (GLS/MHAOV GPU paths are single precision, hence ~1e-6/1e-7; the rest — String-Length +stars (GLS/MHAOV GPU paths are single precision, hence ~1e-6 and ~1e-5; the rest — String-Length now included, via a stable phase sort on every backend — are double). † String-Length's *reference* agreement shows one isolated outlier: a heavily phase-tied star where the textbook reference breaks ties with an unstable sort. Its correlation stays ≈ 1 (median @@ -121,8 +126,8 @@ own CPU backend on the same grid, on an NVIDIA device (`torch:cuda`): - 100% ``` -All seven methods pick the identical best period as the CPU backend on every validated -star. The same torch code path also runs on Apple (`mps`) and Intel (`xpu`) devices, but +All seven methods in the validation suite pick the identical best period as the CPU backend +on every validated star. The same torch code path also runs on Apple (`mps`) and Intel (`xpu`) devices, but those were not exercised in this report (see {doc}`guide/backends`). ## 2. Period recovery on real light curves @@ -189,32 +194,32 @@ on a 32-thread machine: - GPU speed-up * - GLS - finufft - - 0.015 s + - 0.013 s - 0.005 s - - 0.008 s - - 2× astropy - - ~3× + - 0.009 s + - 3× astropy + - ~2× * - BLS - numba - - 0.188 s - - 0.092 s - - 0.392 s - - **18× astropy** + - 0.171 s + - 0.093 s + - 0.396 s + - **20× astropy** - ~2× * - PDM - numba - 0.003 s - 0.005 s - - 0.011 s + - 0.009 s - **>2,000× PyAstronomy** - ~0.6× (GPU slower) * - CE - numba - 0.003 s - 0.004 s - - 0.009 s + - 0.021 s - — - - ~0.8× (GPU slower) + - ~0.7× (GPU slower) * - String-Length - numba - 0.043 s @@ -224,44 +229,55 @@ on a 32-thread machine: - ~4× * - MHAOV - numba - - 0.025 s - - 0.135 s - - 0.114 s + - 0.026 s + - 0.038 s + - 0.032 s - — - - ~0.2× (GPU slower) + - ~0.7× (GPU slower) +* - SuperSmoother + - numba + - 0.099 s + - 0.284 s + - 0.222 s + - — + - ~0.3× (GPU slower) * - TLS - numba - - 0.150 s - - 0.043 s - - 2.110 s + - 0.132 s + - 0.072 s + - 2.205 s - — - - ~4× + - ~2× ``` Two takeaways: - cuPeriod's **CPU** path already beats every reference tool it was checked against — most dramatically PDM (a multicore `numba` port over PyAstronomy's pure-Python `pyPDM`) and - BLS, where the multicore `numba` box search is **18× faster than astropy's compiled + BLS, where the multicore `numba` box search is **20× faster than astropy's compiled `BoxLeastSquares`** while matching it to floating point. - **The multicore numba CPU tier changes the GPU calculus for a single curve.** Now that - PDM, CE, String-Length, MHAOV, and TLS all default to numba kernels rather than plain - numpy, the GPU's single-curve margin is modest (BLS/String-Length/TLS, ~2-4×), a wash - (CE), or the GPU is actually a touch *slower* than the CPU (PDM, MHAOV) — kernel-launch - and host↔device transfer overhead no longer amortizes once the CPU kernel itself runs in - low single-digit milliseconds. That holds across the benchmark's scaling sweep too (up to - 30k points, a 100k-frequency grid — see the full report). GLS is the exception, with a - consistent ~3× GPU edge since its CPU path is finufft, not numba. The GPU's clear, - reproducible win is now **catalog throughput**, not single-curve latency. + PDM, CE, String-Length, MHAOV, SuperSmoother, and TLS all default to numba kernels rather + than plain numpy, the GPU's single-curve margin is a modest win (String-Length ~4×, + GLS ~2×), a near-wash (BLS and TLS, ~1.8×), or the GPU is actually a touch *slower* than + the CPU (PDM/CE/MHAOV ~0.6-0.7×, SuperSmoother ~0.3×) — fixed dispatch and host↔device + transfer overhead no longer amortizes once the CPU kernel itself runs in low single-digit + milliseconds. The scaling sweep (up to 30k points, a 100k-frequency grid — see the full + report) adds two nuances: GLS holds a ~4-5× GPU edge at every grid size since its CPU + path is finufft, not numba, and v1.2's auto-sized batching lifted MHAOV's GPU from ~5× + slower to a near-wash across the whole range, while SuperSmoother's GPU only approaches + parity once curves reach several thousand points. The GPU's clear, reproducible win is + now **catalog throughput**, not single-curve latency. :::{note} -The **`torch:cuda`** column is the portable PyTorch backend on the *same* RTX 5070 Ti — now -validated on NVIDIA hardware, where all seven methods match the CPU reference to round-off. -It is competitive with the cupy fast paths on PDM/CE/String-Length/MHAOV and slower on -BLS/TLS, whose cupy `RawKernel`s are hand-tuned. Its real value is reaching **AMD, Intel, -and Apple** GPUs the CUDA paths can't (those share the same code and are CPU-validated; see -{doc}`guide/backends`). On the CPU it is correct but not the speed champion — finufft (GLS) -and the numba kernels win there. +The **`torch:cuda`** column is the portable PyTorch backend on the *same* RTX 5070 Ti — +validated on NVIDIA hardware, where every method above matches the CPU reference to +round-off. It is competitive with the cupy fast paths on the frequency methods — here it +even edges them out on String-Length, MHAOV, and SuperSmoother — while staying well behind +on BLS/TLS, whose cupy `RawKernel`s are hand-tuned. Its real value is reaching **AMD, +Intel, and Apple** GPUs the CUDA paths can't (those share the same code and are +CPU-validated; see {doc}`guide/backends`). On the CPU it is correct but not the speed +champion — finufft (GLS) and the numba kernels win there. ::: ## 4. Injection–recovery sensitivity @@ -286,7 +302,7 @@ seasonal gaps are realistic) and scores recovery with the same harmonic-aware 2% - 98–100% * - Sinusoid - CE / String-Length - - 42–98% + - 98–100% - 100% * - Eclipse - BLS @@ -309,13 +325,13 @@ tested SNR is String-Length on the narrow eclipse model (~78%) — a method–si not a bug: its rank-based statistic is comparatively insensitive to narrow, low duty-cycle dips, and a box-fitting method (BLS) is the appropriate tool for narrow eclipses/transits. Full per-SNR grid and figure in the -[full report](https://github.com/tjayasinghe/cuPeriod/blob/main/benchmarks/REPORT.md#4--injection–recovery-sensitivity). +[full report](https://github.com/tjayasinghe/cuPeriod/blob/main/benchmarks/REPORT.md#5--injection–recovery-sensitivity). ## 5. Batch throughput & transits -- **Batch:** up to 587 light curves/second on one GPU for GLS on short survey curves - (>2.1 million/hour) — a *single-batch* rate that includes one-off worker-pool spin-up - (process spawn + per-worker CUDA context); a warmed pool sustains ~490 lc/s over many +- **Batch:** up to 574 light curves/second on one GPU for GLS on short survey curves + (>2 million/hour) — a *single-batch* rate that includes one-off worker-pool spin-up + (process spawn + per-worker CUDA context); a warmed pool sustains a higher rate over many chunks. On the same 32-thread machine, the CPU process pool keeps pace with the GPU for the numba-tier methods at the batch sizes tested (PDM: ~1.0× at n=256 and n=1024); GLS is the one method with a consistent GPU edge at batch scale too (~1.3-1.4× up to n=1024). @@ -327,6 +343,115 @@ Full per-SNR grid and figure in the **~2×** faster at CPU↔GPU agreement ≤ 2.1e-14 (the numba CPU tier narrowed what used to be a much larger single-curve gap). +## 6. Multi-band recovery at survey cadence + +`benchmarks/multiband_recovery.py` (fully synthetic, offline) measures what joint +multi-band fitting buys at sparse survey cadence: 300 faint RRab-like stars per cell +(0.2 mag noise), six bands with WFD-like epoch shares over a 3-year window, recovery = +top period within 1% of truth with no harmonic credit. + +| strategy | 30 epochs | 60 epochs | 120 epochs | +|---|---|---|---| +| best single band (*r*) | 0.0% | 37.3% | 97.3% | +| any single band | 0.0% | 49.3% | 99.0% | +| multi-band `perband` (0,1) | 17.7% | 97.0% | 100.0% | +| multi-band `flex` (1,1) | 20.0% | 97.0% | 100.0% | +| multi-band `offsets` (1,0) | **81.7%** | **99.7%** | 100.0% | + +At 30 total epochs — roughly Rubin's first year for one band's worth of visits spread +over six filters — single-band search recovers nothing and the shared-phase `offsets` +model recovers 82%. The models that grant each band its own phase (`perband`, `flex`) +sit far below it at this sparsity: pooling phase information is what buys the +recovery, which is why `offsets` is the default. Model definitions and guidance live +in {doc}`guide/multiband`; the native `offsets` path is also ~400× faster than +astropy's `LombScargleMultiband` on a 6-band, 200k-frequency search (55 s → 0.13 s, +CPU). + +## 7. Multi-band validation on real data + +§6 is simulated; this is the same question asked of **real** photometry with known answers. +`benchmarks/multiband_real.py` runs every multi-band method over 100 SDSS Stripe 82 RR Lyrae +from Sesar et al. (2010) — 80 RRab and 20 RRc, real SDSS *ugriz* cadence with ~55 epochs per +band over a ~3200 d baseline, each with a literature period from that paper's ~10-year +solution. These are the stars VanderPlas & Ivezić (2015) built the multiband periodogram on, +so the shared-phase model that ships as cuPeriod's default `offsets` is being checked on its +home ground. Every star gets one identical blind search: periods 0.15–1.2 d at 5 samples per +Rayleigh width (~97,000 trial frequencies), all methods at default settings. *Strict* means +the top period is within 1% of the literature value with no harmonic credit; *harmonic-aware* +accepts a small-integer harmonic within 2%. + +```{list-table} +:header-rows: 1 +:widths: 30 16 22 22 + +* - Multi-band model + - strict + - harmonic-aware + - median CPU s/star +* - GLS `offsets` (1,0) + - 76% + - 80% + - 0.070 +* - GLS `perband` (0,1) + - 78% + - 81% + - 0.112 +* - GLS `flex` (1,1) + - 78% + - 81% + - 0.367 +* - PDM + - **93%** + - 94% + - 0.011 +* - CE + - 85% + - 90% + - 0.023 +* - String-Length + - **93%** + - **97%** + - 0.036 +* - MHAOV + - 83% + - 84% + - 0.538 +* - SuperSmoother + - 85% + - 96% + - 0.296 +* - BLS + - 22% + - 34% + - 3.024 +``` + +Single-band GLS, one filter at a time, is the baseline: 72–78% strict per band (*z* worst, +*r* best) and 92% for *any* single band — the optimistic bound that counts a star as recovered +if any of the five searches lands on the right period, which in practice you cannot know. + +Two regimes, one conclusion. On curves this well sampled (~280 points across five bands) the +pooled fold statistics lead: PDM and String-Length reach 93% strict and String-Length 97% +harmonic-aware, because a dense fold exploits the whole non-sinusoidal RRab shape while the +single-harmonic GLS models stay alias-limited. The three GLS models are indistinguishable here +(76–78%) and no better than the best single band, the *opposite* of §6's sparse cadence where +`offsets` recovers 82% against ≤20% for the flexible models. Dense per-band data reward shape; +sparse data reward parsimony — the fold methods were not run at sparse cadence, so §6 remains +the guidance for a survey-cadence search. SuperSmoother's 85% → 96% gap is the documented +integer-multiples family: of 21 fold-family picks that are harmonic but not strict, 11 sit at +exactly 2P and 5 at 3P, and its strict rate is 55% on the near-sinusoidal RRc against 92.5% on +RRab, since a fold at twice the period stays coherent. Read the shortest member of a near-tied +family, or let {func}`~cuperiod.alias_diagnostics` arbitrate. Of the 163 non-harmonic misses +across all models, 54% fall on the ±1 or ±2 cycle/day loci — the ground-based window function, +not noise. BLS's 22% is expected and not a defect: it fits transit shapes, and is reported for +completeness rather than recommended for RR Lyrae. Model definitions and guidance live in +{doc}`guide/multiband`. + +To reproduce: `benchmarks/dataset/download_s82_rrlyrae.py` builds the bundle from the +astroML-data mirror (needs network, one time only), then `benchmarks/multiband_real.py` runs +offline — the ~390 KB bundle is committed with the suite. + See the [full report](https://github.com/tjayasinghe/cuPeriod/blob/main/benchmarks/REPORT.md) -for the figures, per-KOI detail, and reproduction commands. +for the figures, per-band and per-subtype breakdowns, per-KOI detail, and reproduction +commands. diff --git a/docs/conf.py b/docs/conf.py index 560fa8c..ba62b46 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ try: release = importlib.metadata.version("cuperiod") except importlib.metadata.PackageNotFoundError: # not installed (rare) - release = "1.1.0" + release = "1.2.0" version = ".".join(release.split(".")[:2]) # -- General configuration ---------------------------------------------------- diff --git a/docs/guide/backends.md b/docs/guide/backends.md index a082280..b19e0d0 100644 --- a/docs/guide/backends.md +++ b/docs/guide/backends.md @@ -58,6 +58,10 @@ The selectors: - `numba` *(with `[fast]`)*, `numpy` - `cupy` - `numba` if installed, else `numpy` +* - SuperSmoother + - `numba` *(with `[fast]`)*, `numpy` + - `cupy` + - `numba` if installed, else `numpy` ``` † BLS's `numpy` backend is a GPU-parity *reference*, not the product path — it shares one @@ -88,7 +92,7 @@ Two orthogonal settings tune it (both environment-overridable, e.g. `CUPERIOD_GL - **`device`** — `"auto"` (default; the best present), `"cpu"`, `"cuda"`, `"mps"`, `"xpu"`. A `"torch:"` backend string overrides it. - **`precision`** — `"auto"` (default) is float64 everywhere it is supported and float32 - only where the device forces it (Apple MPS; some Intel GPUs). `"float64"` and `"float32"` + only where the device forces it (Apple MPS). `"float64"` and `"float32"` force it; `precision="float64"` on MPS raises rather than silently downgrading. Results are always returned as float64 numpy arrays regardless of the device precision. @@ -124,28 +128,28 @@ vs. the `[fast]`-extra CPU backends, on a 32-thread machine): - GPU speed-up * - GLS - finufft - - 0.015 s + - 0.013 s - 0.005 s - - 0.008 s - - ~3× + - 0.009 s + - ~2× * - BLS - numba - - 0.188 s - - 0.092 s - - 0.392 s + - 0.171 s + - 0.093 s + - 0.396 s - ~2× * - PDM - numba - 0.003 s - 0.005 s - - 0.011 s + - 0.009 s - ~0.6× (GPU slower) * - CE - numba - 0.003 s - 0.004 s - - 0.009 s - - ~0.8× (GPU slower) + - 0.021 s + - ~0.7× (GPU slower) * - String-Length - numba - 0.043 s @@ -154,42 +158,52 @@ vs. the `[fast]`-extra CPU backends, on a 32-thread machine): - ~4× * - MHAOV - numba - - 0.025 s - - 0.135 s - - 0.114 s - - ~0.2× (GPU slower) + - 0.026 s + - 0.038 s + - 0.032 s + - ~0.7× (GPU slower) * - TLS - numba - - 0.150 s - - 0.043 s - - 2.110 s - - ~4× + - 0.132 s + - 0.072 s + - 2.205 s + - ~2× +* - SuperSmoother + - numba + - 0.099 s + - 0.284 s + - 0.222 s + - ~0.3× (GPU slower) ``` How to read this: -- **The CPU backend for every method is now the multicore `numba` kernel** (with the +- **The CPU backend for every method but GLS is now the multicore `numba` kernel** (with the `[fast]` extra installed — one to two orders of magnitude faster than the vectorized numpy fallback, see {doc}`../installation`). On this 32-thread machine, that CPU tier is - now fast enough that a single-curve GPU run is only a modest win for BLS/String-Length/TLS - (~2-4×), a wash for CE, and the GPU is actually a touch *slower* than the CPU for PDM and - MHAOV at this curve size — kernel-launch and host↔device transfer overhead no longer - amortizes when the CPU kernel itself takes low single-digit milliseconds. GLS is the one - consistent exception (~3×), because its CPU path is finufft, not a numba kernel. -- This holds up in the benchmark's scaling sweep too, up to 30k points and a 100k-frequency - grid — the GPU doesn't pull ahead of the numba CPU tier for PDM/MHAOV anywhere in that - range on this machine. Expect a wider GPU margin on a narrower CPU. The GPU's clear, + now fast enough that a single-curve GPU run is only a modest win for GLS/String-Length + (~2-4×), a near-wash for BLS/TLS (~1.8×), and the GPU is actually a touch *slower* than + the CPU for PDM/CE/MHAOV (~0.6-0.7×) and SuperSmoother (~0.3×) at this curve size — + fixed dispatch and host↔device transfer overhead no longer amortizes when the CPU + kernel itself takes low single-digit milliseconds. GLS keeps its edge because its CPU + path is finufft, not a numba kernel. +- The scaling sweep (up to 30k points and a 100k-frequency grid) tells the same story + with two nuances: GLS holds a ~4-5× GPU edge at every grid size, and v1.2's auto-sized + batching lifted MHAOV's GPU from ~5× slower to a near-wash (~0.5-0.7×) across the whole + range, while SuperSmoother's GPU only approaches CPU parity once curves reach several + thousand points. Expect a wider GPU margin on a narrower CPU. The GPU's clear, reproducible win is **catalog throughput** — many curves in flight at once — and reaching non-NVIDIA hardware via the portable torch backend, not single-curve latency on the CPU-tier methods ({doc}`batch`). -- Without the `[fast]` extra, PDM/CE/String-Length/MHAOV/TLS fall back to the **vectorized - numpy paths** on the CPU — one to two orders of magnitude slower than the numba column - above (e.g. PDM ~300×, CE ~135×, MHAOV ~57× on a 3k-point curve). +- Without the `[fast]` extra, PDM/CE/String-Length/MHAOV/TLS/SuperSmoother fall back to the + **vectorized numpy paths** on the CPU — one to two orders of magnitude slower than the + numba column above (e.g. PDM ~300×, CE ~135×, MHAOV ~57× on a 3k-point curve, and + SuperSmoother ~130× on a separate 600-point curve over a 20 000-frequency grid). - On **consumer NVIDIA cards** (GeForce), whose float64 throughput is 1/64 of float32, the opt-in `precision="float32"` runs the BLS/TLS CUDA kernels ~8-9× faster at detection-grade accuracy; float64 stays the default. - cuPeriod's **CPU** path already beats the established reference tools it was checked - against — GLS ~2× astropy, BLS ~18× astropy's `BoxLeastSquares`, and PDM's numba kernel + against — GLS ~3× astropy, BLS ~20× astropy's `BoxLeastSquares`, and PDM's numba kernel over 2,000× PyAstronomy's pure-Python `pyPDM` (the numpy PDM path alone is already ~4×). :::{tip} diff --git a/docs/guide/batch.md b/docs/guide/batch.md index 1062ce3..cd64481 100644 --- a/docs/guide/batch.md +++ b/docs/guide/batch.md @@ -93,7 +93,7 @@ etc.). Set `store_raw=True` to also store the peak-preserving downsampled spectr summary.n_inputs # total inputs discovered summary.n_done # results produced summary.n_failed # light curves that errored (one bad curve never kills the batch) -summary.n_skipped # chunks skipped on resume +summary.n_skipped # light curves in chunks skipped on resume summary.methods # methods run summary.errors # list of (key, message) for failures summary.rows # the rows, when sink is None @@ -104,12 +104,12 @@ the batch continues. ## Throughput -On one GPU, batch GLS peaks at **~590 light curves/second** for short survey curves +On one GPU, batch GLS peaks at **~574 light curves/second** for short survey curves (>2 million/hour) — GLS is the method with the most consistent GPU edge, at both single- curve and batch scale. With the `[fast]` extra's multicore `numba` CPU tier, the CPU -process pool now keeps pace with the GPU for several other methods (PDM, CE) at the batch -sizes and curve lengths benchmarked so far — see {doc}`../benchmarks` for the current -breakdown before assuming the GPU wins by default. +process pool now keeps pace with the GPU for PDM at the batch sizes and curve lengths +benchmarked so far — see {doc}`../benchmarks` for the current breakdown before assuming +the GPU wins by default. --- diff --git a/docs/guide/cli.md b/docs/guide/cli.md index aa713e5..4484d05 100644 --- a/docs/guide/cli.md +++ b/docs/guide/cli.md @@ -5,12 +5,14 @@ Python API, so the CLI and library share one code path and give identical result `cuperiod --help` (or `cuperiod --help`) for the full option list. ```text -cuperiod run one light curve, one or more methods → prints the best periods -cuperiod batch many light curves with CPU or GPU workers → Parquet/CSV -cuperiod methods list registered methods and their backends -cuperiod gpu-info show the CUDA GPU and suggested worker counts -cuperiod doctor diagnose backends, torch devices, and the precision each uses -cuperiod grid-info show a method's trial grid for a light curve (no compute) +cuperiod run one light curve, one or more methods → best periods +cuperiod batch many light curves with CPU or GPU workers → Parquet/CSV +cuperiod prewhiten extract a pulsator's frequency solution +cuperiod batch-prewhiten the same over many light curves → Parquet/CSV +cuperiod methods list registered methods and their backends +cuperiod gpu-info show the CUDA GPU and suggested worker counts +cuperiod doctor diagnose backends, torch devices, and precision +cuperiod grid-info show a method's trial grid for a light curve (no compute) ``` :::{tip} @@ -37,8 +39,11 @@ periods for each. - Comma-separated method names (default `GLS`). * - `--backend` - `auto` | `cpu` | `gpu` | a concrete backend name. -* - `--time` / `--value` / `--error` / `--band` +* - `--time` / `--value` / `--error` - Override column names (otherwise auto-detected). +* - `--band` + - Band/filter column of a long-format file. Passing it runs a **joint** multi-band fit; + without it the file is read as a single-band light curve. See {doc}`multiband`. * - `--domain` - `magnitude` | `flux`. * - `--n-best` @@ -91,6 +96,54 @@ row per light curve. Key options: A directory sink is resumable — re-running skips finished chunks. See {doc}`batch`. +## `prewhiten` — a pulsator's frequency solution + +```bash +cuperiod prewhiten star.csv --snr 4.6 -n 30 --spacing --csv modes.csv +``` + +Runs the automated extraction loop of {doc}`prewhitening` and prints a header with the +reason the run stopped and the fit statistics, followed by the ranked components with +their uncertainties and signal-to-noise. + +```{list-table} +:header-rows: 1 +:widths: 30 70 + +* - Option + - Meaning +* - `--max-frequencies`, `-n` + - Cap on extracted components (default 30). +* - `--snr` + - Breger signal-to-noise threshold (default 4.0). +* - `--stop` + - Comma-separated criteria: `snr`, `fap`, `bic`, `amplitude`. +* - `--fmin` / `--fmax` + - Search band in cycles/day (default `1/T` to `max(nyquist_factor × pseudo-Nyquist, 50)`). +* - `--uncertainty` + - `covariance` | `analytic` | `bootstrap`. +* - `--combinations / --no-combinations` + - Identify harmonics and combination frequencies (default on). +* - `--spacing` + - Also search the independent modes for a g-mode period-spacing pattern. +* - `--backend` + - `auto` | `cpu` | `gpu` | a concrete backend name. +* - `--out` / `--csv` / `--save-spectrum` + - Write the full solution as JSON, the component table as CSV, and/or the + amplitude spectra as `.npz` (data, residual, and the spectral window). +``` + +## `batch-prewhiten` — many pulsators + +```bash +cuperiod batch-prewhiten "lcs/*.csv" --out modes.parquet --workers 8 -n 20 +``` + +Takes the same inputs and worker options as `batch`, and the same extraction options as +`prewhiten`. The output has **one row per extracted component**, each carrying the +per-star summary (sample count, baseline, stop reason, fit statistics) so a single table +is self-describing. + ## `methods` — what's available ```bash diff --git a/docs/guide/gui.md b/docs/guide/gui.md index d58ca6f..3a66c93 100644 --- a/docs/guide/gui.md +++ b/docs/guide/gui.md @@ -27,10 +27,11 @@ Add `[gpu]` or `[torch]` alongside `[gui]` to explore on an accelerator — actionable message instead of a traceback. :::{tip} -The window opens with **bundled demo light curves** — a *Kepler* transit, six ASAS-SN -variables (each labelled with its VSX type and literature period), and a synthetic -multi-band curve — so there's something to explore on first launch, no data of your own -required. +The toolbar's **Load demo** menu always offers a **synthetic multi-band demo curve**, so +there's something to explore on first launch, no data of your own required. In a source +checkout (or with `CUPERIOD_EXAMPLE_DATA` pointed at `examples/data`) the same menu also +lists a *Kepler* transit and six ASAS-SN variables, each labelled with its VSX type and +literature period. ::: ## A two-minute tour @@ -46,18 +47,31 @@ required. band. 4. **Load demo → a folder in batch mode.** Scroll the **Sources** dock (arrow keys or Prev/Next); each source computes on demand and revisits are instant (cached). -5. **Toggle the theme** (dark ↔ light — remembered next launch). With `[gpu]`/`[torch]` +5. **Switch **Analysis** to *Pre-whitening*** and press **Run pre-whitening**. The + spectrum becomes the amplitude spectrum with the residual spectrum overlaid and every + extracted component marked; the **Frequencies** dock lists them with uncertainties and + S/N. Click a row to fold on it. The **window** checkbox overlays the sampling's + spectral window (scaled to the tallest peak) — a component sitting on another's window + lobe is likely an alias — and unchecking **data** hides the dense data curve so the + residual and window traces can be read on their own. Watch the **A/Asp** column: a + row marked ✱ has an amplitude entangled with a correlated neighbour. For a g-mode + star, the **Period spacing** tab scans for a regular spacing and draws the échelle + diagram. +6. **Toggle the theme** (dark ↔ light — remembered next launch). With `[gpu]`/`[torch]` installed, the info bar names the backend and device actually used. ## The interface | Area | What it does | | --- | --- | -| **Controls** (left) | Choose the method and edit its settings. The form is built automatically from each method's settings model ({doc}`tuning`), so every knob — grid bounds, `n_harmonics`, transit-duration fractions, backend/device/precision — is exposed with the right type and defaults. Press **Compute** to run. | -| **Spectrum** (centre) | The full-resolution periodogram, rendered at interactive speed. Drag the marker to select a trial period; toggle the **x-axis** between frequency and period and switch either axis to **log**. | -| **Phased** | The light curve folded on the selected period, updating live as you move the marker. **2 cycles** repeats the fold; for multi-band data a **Band** selector overlays all bands or isolates one. | +| **Analysis** (top left) | Switch between **Periodogram** — one method over a trial grid — and **Pre-whitening**, the automated frequency extraction of {doc}`prewhitening`. The rest of the window is shared: same inputs, same spectrum/phased views, same source browser; only the result docks change. | +| **Controls** (left) | Choose the method and edit its settings. The form is built automatically from each method's settings model ({doc}`tuning`), so every knob — grid bounds, `n_harmonics`, transit-duration fractions, backend/device/precision — is exposed with the right type and defaults. For multi-band input a **Band** selector chooses what is analysed (all bands jointly, or one). Press **Compute** to run. | +| **Spectrum** (centre) | The full-resolution periodogram, rendered at interactive speed. Drag the marker to select a trial period; toggle the **x-axis** between frequency and period and switch either axis to **log**. **peaks** hides the peak markers and the shaded selection band together, for an unobstructed view of the spectrum. Double-click anywhere to restore the default view. | +| **Phased** | The light curve folded on the selected period, updating live as you move the marker. **2 cycles** repeats the fold; for multi-band data every band is overlaid, colour-coded with a legend. | | **Raw light curve** | The unfolded time series for the loaded source. | | **Peaks** (dock) | The ranked N-best periods ({doc}`results`). Click a row to jump the marker (and the fold) to that peak. | +| **Frequencies** (dock) | In pre-whitening mode, the extracted components with their 1-sigma uncertainties, S/N, false-alarm probability, blend ratio (**A/Asp**) and any combination-frequency identification, plus the stopping reason and fit statistics. Click a row to fold on that component; right-click to copy or export CSV. | +| **Period spacing** (dock) | In pre-whitening mode, the comb scan over trial spacings and the échelle diagram of the modes that belong to the series, with the mean spacing, its tilt, and the buoyancy radius Π₀. Runs on the *independent* components, so identified combinations cannot pollute the pattern. | | **Sources** (dock) | In batch mode, the list of light curves; navigate with Prev/Next or the arrow keys. | | **Info bar** | The backend and device actually used for the last run, plus timing — handy for confirming that `auto` reached your GPU. | @@ -66,19 +80,19 @@ responsive even while a long grid is evaluating and rapid re-runs don't queue up ## Loading your own data -**File → Open** reads a single light curve through the same auto-detecting loader as the CLI -(`*.csv`, `*.ecsv`, `*.fits`/`*.fit`/`*.fz`, `*.parquet`/`*.pq`, `*.tsv`/`*.tab`, `*.dat`, -`*.txt`). For tabular files a **preview dialog** shows the first rows and the column mapping -cuPeriod auto-detected (time / value / error / band) before you commit — the same -{class}`~cuperiod.ColumnMap` resolution described under {doc}`light-curves`. If a band/filter -column is present the file loads as a {class}`~cuperiod.MultiBandLightCurve`; otherwise as a -single {class}`~cuperiod.LightCurve`. - -**Batch mode** points the **Sources** browser at a whole set of light curves — a folder, a -glob, or a list of files — reusing the same input resolution as -{func}`~cuperiod.batch_periodograms` ({doc}`batch`). Sources are read lazily (a big folder -isn't loaded up front) and each computed source is cached, so scrolling back and forth is -instant. +The toolbar's **Open…** button reads a single light curve through the same auto-detecting +loader as the CLI (`*.csv`, `*.ecsv`, `*.fits`/`*.fit`/`*.fz`, `*.parquet`/`*.pq`, +`*.tsv`/`*.tab`, `*.dat`, `*.txt`). For tabular files a **preview dialog** shows the first +rows and the column mapping cuPeriod auto-detected (time / value / error / band) before you +commit — the same {class}`~cuperiod.ColumnMap` resolution described under +{doc}`light-curves`. If a band/filter column is present the file loads as a +{class}`~cuperiod.MultiBandLightCurve`; otherwise as a single {class}`~cuperiod.LightCurve`. + +**Batch mode** — the toolbar's **Open folder…** button, or dropping several light-curve files +on the window — points the **Sources** browser at a whole set of light curves, reusing the same +input resolution as {func}`~cuperiod.batch_periodograms` ({doc}`batch`). Sources are read lazily (a +big folder isn't loaded up front) and each computed source is cached, so scrolling back and +forth is instant. ## Backends & devices diff --git a/docs/guide/index.md b/docs/guide/index.md index 4a26f24..fbb9796 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -13,7 +13,7 @@ plus column auto-detection and the magnitude/flux domain. ::: :::{grid-item-card} {doc}`methods` -A decision guide to the seven methods: what each is for, its objective sense, and its +A decision guide to the eight methods: what each is for, its objective sense, and its key knobs. ::: @@ -32,8 +32,19 @@ Per-method settings models, environment-variable overrides, and custom frequency grids. ::: +:::{grid-item-card} {doc}`prewhitening` +Automated, uncertainty-aware frequency extraction for δ Scuti, γ Dor, and SPB +pulsators — with combination frequencies and g-mode period spacings. +::: + :::{grid-item-card} {doc}`multiband` -Jointly model several filters of the same star with GLS, BLS, and MHAOV. +Jointly model several filters of the same star: three GLS models, pooled fold statistics, +bootstrap false-alarm probabilities, and alias checks. +::: + +:::{grid-item-card} {doc}`interop` +Run a search straight over nested-pandas / lsdb survey catalogs — row-wise, or +partition-wise with one GPU engine per partition. ::: :::{grid-item-card} {doc}`batch` @@ -42,7 +53,8 @@ output. ::: :::{grid-item-card} {doc}`cli` -The `cuperiod` command line: `run`, `batch`, `methods`, `gpu-info`, `doctor`, `grid-info`. +The `cuperiod` command line: `run`, `batch`, `prewhiten`, `batch-prewhiten`, `methods`, +`doctor`, and more. ::: :::{grid-item-card} {doc}`gui` @@ -65,3 +77,7 @@ A run is always the same three steps, whether you call the function or the CLI: The single entry point {func}`cuperiod.periodogram` ties these together; its batch sibling {func}`cuperiod.batch_periodograms` does the same for many light curves at once. + +A multiperiodic pulsator needs more than the best period, so {func}`cuperiod.prewhiten` +runs that same three-step machinery in a loop — extract, fit, subtract, repeat — with +principled stopping criteria and propagated uncertainties ({doc}`prewhitening`). diff --git a/docs/guide/interop.md b/docs/guide/interop.md new file mode 100644 index 0000000..8228a14 --- /dev/null +++ b/docs/guide/interop.md @@ -0,0 +1,178 @@ +# LINCC catalogs (nested-pandas / lsdb) + +The LINCC Frameworks stack keeps a star's light curve **inside its object row**: one row +per object, the per-epoch arrays in a nested column (a nested-pandas `NestedFrame`), and +`lsdb` spreads that frame over the dask partitions of a HATS catalog. The usual way to run +a period search over such a table — explode to long format, `groupby` the object id, +rebuild a DataFrame per star — undoes exactly the layout the format exists for. + +`cuperiod.interop` runs cuPeriod directly on that layout: no flattening, no `groupby`, no +per-object DataFrames. + +```bash +pip install "cuperiod[nested]" # nested-pandas + a recent pyarrow +pip install "cuperiod[lsdb]" # + lsdb, for HATS catalogs +``` + +Importing `cuperiod` never pulls in nested-pandas, and importing `cuperiod.interop` does +not either — the dependency is checked on first *use*, so even `COLUMN_PRESETS` can be +inspected in a bare install. + +## Two tiers + +| | Function | Unit of work | Reach for it when | +| --- | --- | --- | --- | +| **Tier 1** | {func}`~cuperiod.interop.nested_periodogram` | one row | CPU backend, a quick look, a small catalog | +| **Tier 2** | {func}`~cuperiod.interop.partition_periodogram` | one partition | GPU throughput over a survey | + +They take the same column and method arguments and produce the same result columns; what +differs is how the work is executed (and that Tier 2 returns the result columns only). +Both accept an in-memory `NestedFrame` or a lazy lsdb `Catalog` (which stays lazy), resolve +their columns from the nest's **schema alone** — never by computing — and turn a failed +object into NaN result columns rather than an aborted run. + +## Tier 1 — row-wise + +`nested_periodogram` wraps `map_rows`: one light curve per row, one periodogram per row, +results appended as ordinary base columns. + +```python +from cuperiod.interop import nested_periodogram + +out = nested_periodogram(frame, "lc", preset="ztf_dr22") +out[["best_period", "best_power", "fap"]].head() +``` + +The result columns are `best_period`, `best_power`, `fap` (NaN when the method reports +none), plus `period_2 … period_n` when you ask for `n_best > 1`. `prefix=` prepends a +string to every one of them, so several methods can live in one frame; +`append_columns=False` returns only the results. + +On a lazy lsdb `Catalog` nothing changes except that you call `.compute()` at the end: + +```python +import lsdb +from cuperiod.interop import nested_periodogram + +cat = lsdb.open_catalog("dp1_object") +res = nested_periodogram( + cat, preset="rubin_dp1_object", method="GLS", n_best=3, prefix="gls_" +) +res[["gls_best_period", "gls_period_2"]].compute() +``` + +`meta` for the dask graph is built automatically (`{column: float}`) for catalogs; pass +your own with `meta=` if you need to. + +Multi-band comes from one argument. When `band=` resolves to an in-nest sub-column, each +row is built as a {class}`~cuperiod.MultiBandLightCurve` grouped on that column and the +method's multi-band model runs ({doc}`multiband`); otherwise every epoch is one band. The +band column is **never** auto-detected, so a nest that happens to carry a `band` column is +not silently reinterpreted as a joint fit. + +## Tier 2 — partition-wise + +`partition_periodogram` reads a whole partition's nested column **once** through its Arrow +buffers (list offsets plus struct fields), slices each object out of the flat arrays, and +evaluates every object in the partition against **one** method engine built per partition. + +```python +from cuperiod.interop import partition_periodogram + +res = partition_periodogram(frame, "lc", method="GLS") +res["best_period"].head() +``` + +That is the GPU differentiator: plan and kernel setup is amortized over a whole partition +of stars instead of paid per star. On a CPU backend (no engine) it is still the cheaper +path, because the per-object DataFrame round-trip is skipped. The result is one row per +object, indexed like the input, carrying the result columns only. + +:::{note} +**Deploying on GPUs with dask.** Run **one worker per GPU** and let each worker own its +device: + +```python +from dask.distributed import Client +from dask_cuda import LocalCUDACluster + +client = Client(LocalCUDACluster()) +res = partition_periodogram(cat, preset="ztf_alerts", method="GLS", backend="gpu") +res.compute() +``` + +The callable dask ships to the workers holds only picklable configuration — column names, +method name, settings, grid. Compute engines are **never** pickled: each is built lazily +inside the worker, on that worker's own device, and released when the partition finishes. +::: + +## Column presets + +Survey layouts are stable enough to name. `preset=` fills in every column parameter you +did not set yourself; anything you pass explicitly wins. + +| Preset | Nest | Time | Value / error | Band | Domain | +| --- | --- | --- | --- | --- | --- | +| `"ztf_dr22"` | `lc` | `hmjd` | `mag` / `magerr` | — (see below) | magnitude | +| `"ztf_alerts"` | `lc` | `lc_mjd` | `lc_magpsf` / `lc_sigmapsf` | `lc_fid` | magnitude | +| `"rubin_dp1_object"` | `objectForcedSource` | `midpointMjdTai` | `psfFlux` / `psfFluxErr` | `band` | flux | +| `"rubin_dp1_dia"` | `diaObjectForcedSource` | `midpointMjdTai` | `psfFlux` / `psfFluxErr` | `band` | flux | + +ZTF DR22 keeps the filter **outside** the nest: it has one row per (object, filter), with +the filter in the base column `filterid` (1 = *g*, 2 = *r*, 3 = *i*). The preset therefore +sets `band=None` and each row is a single-band search. A joint multi-band run needs a +self-join that nests one object's per-filter rows into one row first +(`NestedFrame.join_nested`). + +Without a preset, the time/value/error sub-columns are auto-detected from the nest's +schema by the same survey-aware {class}`~cuperiod.ColumnMap` machinery as everywhere else +({doc}`light-curves`); {func}`~cuperiod.interop.resolve_nested_columns` runs that +resolution on its own if you want to see what it decided: + +```python +from cuperiod.interop import resolve_nested_columns + +resolve_nested_columns(cat, preset="rubin_dp1_object") +# NestedColumns(nested='objectForcedSource', +# time='objectForcedSource.midpointMjdTai', ...) +``` + +:::{warning} +**Rubin fluxes are nJy and can legitimately be negative.** DP1 forced photometry — and +difference-imaging photometry in particular — has real negative flux measurements, so +converting to magnitudes would drop or corrupt them. Search in the **flux** domain: both +`rubin_*` presets set `domain=Domain.FLUX` for you, and you can force it anywhere else +with `domain="flux"`. +::: + +## Two version worlds, one code path + +nested-pandas renamed its dtype introspection API across releases, and the ecosystem is +currently split: + +- **lsdb pins `nested-pandas < 0.7`**, which is the pandas-2 world. +- **standalone `nested-pandas >= 0.7`** is the pandas-3 world. + +The adapter supports **both** with a single code path: it reads sub-column names through +whichever spelling the installed dtype offers, and it uses only `map_rows` / +`map_partitions` / `join_nested` — never `reduce`, which upstream removed in 0.7.0. You do +not need to pick a side; install whichever of `[nested]` / `[lsdb]` fits your stack. + +:::{note} +The two worlds pin incompatible pandas majors, so a single environment cannot hold both. +cuPeriod's own `pyproject.toml` declares `[lsdb]` and `[dev]` as conflicting extras for +exactly this reason, and its CI exercises the adapter against the 0.7 line while the code +stays 0.6.10-compatible. +::: + +## Failure handling + +At survey scale a single bad light curve must never abort a run. An object that cannot be +searched — too few detections, no time baseline, a degenerate fit — yields NaN result +columns and the run continues. Filter on `best_period.notna()` afterwards to see how many +objects were searchable. + +--- + +Next: {doc}`batch` — the file/DataFrame batch runner, for data that is not in a LINCC +catalog. diff --git a/docs/guide/light-curves.md b/docs/guide/light-curves.md index cb68eb4..2bb1552 100644 --- a/docs/guide/light-curves.md +++ b/docs/guide/light-curves.md @@ -205,7 +205,7 @@ pg = cup.periodogram(df, "GLS", domain=Domain.FLUX) # or domain="flux" Why it matters: **box/transit methods (BLS, TLS) work in flux**, where an eclipse or transit is a *dip*. If you hand them magnitudes, cuPeriod converts to flux automatically (`flux = 10 ** (-0.4 * mag)`, with error propagation), so you don't have to. The Fourier -and fold methods (GLS, PDM, CE, string-length, MHAOV) are domain-agnostic. +and fold methods (GLS, PDM, CE, string-length, MHAOV, SuperSmoother) are domain-agnostic. You can convert by hand too: diff --git a/docs/guide/methods.md b/docs/guide/methods.md index 2f7a489..054d2f9 100644 --- a/docs/guide/methods.md +++ b/docs/guide/methods.md @@ -1,6 +1,6 @@ # Choosing a method -cuPeriod ships seven period-search methods. They all take the same inputs and return the +cuPeriod ships eight period-search methods. They all take the same inputs and return the same {class}`~cuperiod.Periodogram`, so trying several is cheap — but picking the right one for your signal saves time and gives cleaner peaks. This page is a decision guide. @@ -36,6 +36,10 @@ for your signal saves time and gives cleaner peaks. This page is a decision guid * - Eclipsing / eccentric, want a shape-free statistic - **String-Length** - Minimizes the path length through the folded curve; cheap and assumption-light. +* - Any repeating shape, without picking a harmonic budget + - **SuperSmoother** + - Fits the fold itself with a variable-span smoother — fully non-parametric. Watch the + integer-multiple caveat below. ``` Not sure? Run a few at once and compare — see {ref}`several-methods` below. @@ -44,13 +48,21 @@ Not sure? Run a few at once and compare — see {ref}`several-methods` below. Each method's statistic is either **maximized** or **minimized** at the true period: -- **Maximized** (a tall peak = significant): GLS, BLS, MHAOV, TLS. +- **Maximized** (a tall peak = significant): GLS, BLS, MHAOV, TLS, SuperSmoother. - **Minimized** (a deep trough = significant): PDM, CE, String-Length. You don't have to track this — {meth}`~cuperiod.Periodogram.best_periods` knows each method's `objective_sense` and always returns the *most significant* periods first. It matters only if you inspect the raw `power` array yourself ({doc}`results`). +## Multi-band + +Seven of the eight take several filters of the same star and fit them jointly: **GLS, BLS, +MHAOV, PDM, CE, String-Length, and SuperSmoother**. Only TLS is single-band. Pass a +{class}`~cuperiod.MultiBandLightCurve` instead of a {class}`~cuperiod.LightCurve` and the +method's joint model runs; a single-band method asked for a multi-band run raises a clear +error. See {doc}`multiband`. + ## The methods in detail ### GLS — generalized Lomb–Scargle @@ -59,7 +71,7 @@ The workhorse for periodic variable stars. cuPeriod computes the floating-mean Lomb–Scargle power of Zechmeister & Kürster (2009) — the same statistic as astropy's `LombScargle(..., fit_mean=True)` — but evaluates the trigonometric sums with a non-uniform FFT, matching astropy to ~1e-9 while running much faster. Each peak carries a -false-alarm probability (`extra["fap"]`). Supports {doc}`multi-band `. +false-alarm probability (`extra["fap"]`). ```python pg = cup.periodogram(lc, "GLS") @@ -68,13 +80,19 @@ pg = cup.periodogram(lc, "GLS") Key settings ({class}`~cuperiod.GLSSettings`): `samples_per_peak`, `nyquist_factor`, `fit_mean`, `fap_method`, `minimum_frequency` / `maximum_frequency`. +{doc}`Multi-band ` GLS is native on every backend and offers three joint +models (`mb_model`): a shared-phase sinusoid with per-band offsets (`"offsets"`, the +default), independent per-band sinusoids (`"perband"`), and a regularized model with +per-band harmonics (`"flex"`). Multi-band false-alarm probabilities come from a +within-band bootstrap ({func}`~cuperiod.multiband_fap`, or `mb_fap_bootstrap`). + ### BLS — box least squares For eclipsing binaries and box-shaped transits. Searches log-spaced period segments so the box-duration grid tracks the period, exactly as a transit's duration scales. **Works in flux** (magnitudes are converted automatically), because an eclipse is a dip. Each peak -carries the box parameters: `depth`, `duration`, `transit_time` (t0), `depth_snr`, and the -signal-detection efficiency `sde`. Supports {doc}`multi-band `. +carries the box parameters: `depth`, `duration`, `t0` (mid-transit time), `depth_snr`, and +the signal-detection efficiency `sde`. Supports {doc}`multi-band `. ```python pg = cup.periodogram(lc, "BLS") @@ -83,9 +101,10 @@ for peak in pg.best_periods(5, alias_diverse=True): # alias-aware for box se ``` With the `[fast]` extra, BLS's CPU backend is a multicore `numba` search ~20× faster than -astropy (PDM, CE, String-Length, MHAOV, and TLS gain `numba` CPU kernels too — see -{doc}`backends`). Key settings ({class}`~cuperiod.BLSSettings`): `min_period_days` / -`max_period_days`, `duration_min_frac` / `duration_max_frac`, `n_durations`, `objective`. +astropy (PDM, CE, String-Length, MHAOV, TLS, and SuperSmoother gain `numba` CPU kernels +too — see {doc}`backends`). Key settings ({class}`~cuperiod.BLSSettings`): +`min_period_days` / `max_period_days`, `duration_min_frac` / `duration_max_frac`, +`n_durations`, `objective`. ### TLS — transit least squares @@ -114,6 +133,8 @@ pg = cup.periodogram(lc, "MHAOV", settings=cup.MHAOVSettings(n_harmonics=4)) Stellingwerf's method: bin the folded light curve and minimize the within-bin variance relative to the total. Makes **no assumption about the waveform**, so it suits arbitrary non-sinusoidal shapes. Key settings ({class}`~cuperiod.PDMSettings`): `n_bins`, `n_covers`. +Supports {doc}`multi-band `: each band is folded and binned on its own and the +`Theta` values are pooled by within-bin degrees of freedom. ```python pg = cup.periodogram(lc, "PDM") @@ -123,7 +144,8 @@ pg = cup.periodogram(lc, "PDM") Graham et al. (2013): minimize the conditional entropy of the folded phase–magnitude diagram. Robust on **sparse, unevenly sampled survey data**. Key settings -({class}`~cuperiod.CESettings`): `n_phase_bins`, `n_mag_bins`. +({class}`~cuperiod.CESettings`): `n_phase_bins`, `n_mag_bins`. Supports +{doc}`multi-band `: one histogram per band, entropies pooled by point count. ```python pg = cup.periodogram(lc, "CE") @@ -133,7 +155,8 @@ pg = cup.periodogram(lc, "CE") Dworetsky / Lafler–Kinman: minimize the total length of the "string" connecting phase-ordered points in the folded curve. Cheap and shape-agnostic; handy for eclipsing or -eccentric systems. Settings: {class}`~cuperiod.StringLengthSettings`. +eccentric systems. Settings: {class}`~cuperiod.StringLengthSettings`. Supports +{doc}`multi-band `: one string per band, lengths pooled by point count. ```python pg = cup.periodogram(lc, "String-Length") # or "StringLength" @@ -142,6 +165,42 @@ pg = cup.periodogram(lc, "String-Length") # or "StringLength" (`String-Length` is the canonical name; lookup is case-insensitive and tolerant of the hyphen.) +### SuperSmoother + +Friedman's (1984) variable-span smoother applied to every phase-fold: three local-linear +smooths over span fractions 0.05 / 0.2 / 0.5 of the points, leave-one-out cross-validation +to pick the best span at each phase point, and a final pass over the blended curve. The +statistic follows gatspy's `SuperSmoother` — `1 - mean|y - model|/dy / mean|y - mu|/dy`, +the fractional reduction in mean absolute (error-standardized) deviation about the +inverse-variance weighted mean `mu`. It is **maximized**: `1` is a perfect fit, `0` is no +better than a constant, and a slightly negative value means the fold fits worse than the +mean. + +Being fully non-parametric, it captures **any repeating shape** — an RR Lyrae sawtooth, an +eclipsing binary, a fold nothing analytic describes — without your choosing a harmonic +budget. It is the classic period finder of the Stripe 82 RR Lyrae work (Sesar et al.) and +one of the methods compared by VanderPlas & Ivezić (2015). The price is cost (a sort plus +several smooths per trial period) and a soft spectrum. + +**Integer multiples score nearly as high.** A fold at `2P`, `3P`, … is still a coherent +repeating curve — it just draws the shape twice — so the smoother fits it about as well as +`P` itself. Read the *shortest* period of a high-scoring family as the candidate, bound +the trial periods from above by raising `minimum_frequency` (the longest period searched +is `1/minimum_frequency`), or let {func}`~cuperiod.alias_diagnostics` arbitrate. + +```python +pg = cup.periodogram(lc, "SuperSmoother") # or "super-smoother" +``` + +Key settings ({class}`~cuperiod.SuperSmootherSettings`): `primary_spans` (the candidate +span fractions, default `(0.05, 0.2, 0.5)`), `middle_span`, `final_span`, +`bass_enhancement` (Friedman's alpha, `0`–`10`, pulls the chosen spans toward the largest; +`None` disables it), `min_detections` (20 here). Runs on `numpy`, the multicore `numba` +tier (the CPU default with `[fast]`), `cupy`, and the portable `torch` path, with the same +statistic on all four ({doc}`backends`). Supports {doc}`multi-band `: each band +is smoothed independently on the shared grid and the per-band scores are combined with +baseline-error weights, exactly as in gatspy's `SuperSmootherMultiband`. + (several-methods)= ## Running several at once diff --git a/docs/guide/multiband.md b/docs/guide/multiband.md index 63d0c73..025b607 100644 --- a/docs/guide/multiband.md +++ b/docs/guide/multiband.md @@ -1,11 +1,22 @@ # Multi-band light curves -When you have the **same star observed in several filters** (e.g. *g* and *r*), you can -model all bands jointly instead of running each separately. A joint model shares the period -across bands while letting each band have its own amplitude and offset, which boosts -sensitivity when no single band is well-sampled. +A survey rarely spends its epochs on one filter. Rubin/LSST spreads its visits across +*ugrizy*, so no single band is densely sampled in the early years; a cross-matched +ZTF + ATLAS + ASAS-SN light curve is three sparse curves rather than one dense one. +Searching each band on its own throws away the fact that they are the **same star with the +same period** — and in the sparse regime that is most of the information there is. -Multi-band is supported by **GLS, BLS, and MHAOV**. (The other methods take a single band.) +A multi-band search fits all bands jointly at every trial frequency: one period, but each +band keeps its own mean magnitude, amplitude, and (depending on the model) its own phase. +Seven of the eight methods do it — **GLS, BLS, MHAOV, PDM, CE, String-Length, and +SuperSmoother**; only TLS is single-band. Asking a single-band method for a multi-band run +raises a clear error. + +:::{note} +How much this buys you depends on how sparse the data are. At 30 total epochs across six +bands, single-band GLS recovers nothing and the shared-phase multi-band model recovers +82% — see {ref}`the recovery table ` below. +::: ## Building a `MultiBandLightCurve` @@ -21,15 +32,36 @@ mb = MultiBandLightCurve.from_light_curves({"g": lc_g, "r": lc_r}) print(mb.band_names, mb.n_bands) # ('g', 'r'), 2 ``` -Or split one **long-format** table on a band/filter column: +From a **long-format** table — one row per epoch, with a band/filter column: ```python mb = MultiBandLightCurve.from_dataframe(df, band_column="filter") ``` +Or straight from a long-format **file** (CSV / ECSV / FITS / Parquet — no pandas needed): + +```python +mb = MultiBandLightCurve.from_file("star_ugrizy.parquet", band_column="band") +pg = cup.periodogram(mb, "GLS") +``` + The band column is auto-detected (`band`, `filter`, `passband`, `fid`, …) when you don't name it, and the time/value/error columns resolve exactly as for a single -{doc}`light curve ` (with {class}`~cuperiod.ColumnMap` if needed). +{doc}`light curve ` (with {class}`~cuperiod.ColumnMap` if needed). Bands keep +their first-appearance order. + +The same switch works from the command line and in batch: + +```bash +cuperiod run star_ugrizy.csv --band filter --method GLS +``` + +```python +cup.batch_periodograms("survey/*.parquet", "GLS", band_column="band", sink="out/") +``` + +`--band` (and `band_column=` for file, glob, directory, or `(DataFrame, group_column)` +inputs) makes each object a joint multi-band fit rather than a single-band one. ## Running a multi-band periodogram @@ -37,27 +69,274 @@ Pass the {class}`~cuperiod.MultiBandLightCurve` to {func}`~cuperiod.periodogram` other input: ```python -pg = cup.periodogram(mb, "GLS") # VanderPlas & Ivezić shared-phase model +pg = cup.periodogram(mb, "GLS") # shared-phase model, the default print(pg.best_period()) +print(pg.meta["bands"], pg.meta["mb_model"]) ``` The result is an ordinary {class}`~cuperiod.Periodogram`, so peak finding, the raw spectrum, and serialization all work as in {doc}`results`. +The default grid is built from the **stacked** baseline of all bands (their combined time +span), so the frequency resolution reflects all your data; override it with `grid=` +({doc}`tuning`). + +## The three GLS models + +`GLSSettings.mb_model` selects how the bands share the signal. All three run natively on +every backend — finufft on the CPU, cufinufft on CUDA, and the portable torch path on any +device. (`backend="astropy"` still delegates to `LombScargleMultiband`; it is kept as the +reference the native paths are tested against, not as a fast path.) + +### `"offsets"` — shared phase (the default) + +One sinusoid on a **shared phase** plus an independent constant offset per band: the +`(N_base, N_band) = (1, 0)` model of VanderPlas & Ivezić (2015), and their recommended +search model for sparse multi-band data. + +```{math} +y_k(t) = a\cos(2\pi f t) + b\sin(2\pi f t) + c_k +``` + +All phase information pools into the two signal parameters `a, b` while each band `k` +spends only one nuisance parameter `c_k`. cuPeriod profiles the offsets out analytically, +which leaves the ordinary Zechmeister & Kürster assembly with every trigonometric sum +replaced by its band-centered counterpart, and evaluates it in `K + 2` NUFFTs for `K` +bands — so a joint fit costs about what one single-band GLS over the stacked points would. +With `K = 1` it reduces exactly to single-band GLS. + +That closed form is also the speed story. On a six-band, 100-point star over 200 000 trial +frequencies, delegating to astropy's `LombScargleMultiband` took **55 s**; the native path +takes **0.13 s** — roughly 400×. + +### `"perband"` — independent per-band sinusoids + +The multi-phase `(0, 1)` model: each band gets its own floating-mean sinusoid, with an +independent amplitude *and phase*, and the per-band standard powers are combined with the +reference-chi-squared weights of VanderPlas & Ivezić (2015, eq. 23): + +```{math} +P(f) = \frac{\sum_k \chi^2_{0,k}\, P_k(f)}{\sum_k \chi^2_{0,k}} +``` + +Nothing ties the bands' phases together, so this is the model to reach for when you want a +quick per-band look with one combined statistic — but it is also why it recovers fewer +sparse-cadence periods than `"offsets"` (below). + +:::{note} +astropy's `LombScargleMultiband(method="fast")` intends this same combination but weighs +the bands by the summed squared periodogram rather than by `chi2_0k`, which makes its +output depend on the frequency grid it was evaluated on. This differs from the published +weighting; `gatspy` uses `chi2_0k`, and so does cuPeriod. +::: + +### `"flex"` — flexible regularized model + +astropy's flexible model: `mb_nterms_base` shared harmonics plus `mb_nterms_band` +harmonics-with-offset per band, ridge-regularized to lift the base/band degeneracy. +Per-band chromatic light-curve *shape* — an amplitude ratio and a phase lag that differ +from filter to filter, as in an RR Lyrae or a Cepheid — is what the extra per-band +harmonics buy. + ```python -pg = cup.periodogram(mb, "MHAOV") # pooled F-statistic across bands -pg = cup.periodogram(mb, "BLS") # joint box search across bands +settings = cup.GLSSettings(mb_model="flex", mb_nterms_base=2, mb_nterms_band=1) +pg = cup.periodogram(mb, "GLS", settings=settings) ``` -Asking a single-band method for a multi-band run raises a clear error, so you'll know -immediately if a method doesn't support it. +cuPeriod builds the per-frequency normal equations from per-band harmonic trig sums and +solves them in batch, on CPU, CUDA, or any torch device. It reproduces astropy's power to +~2e-10 across term counts and under both ridge conventions +(`mb_regularize_by_trace`) — see `tests/test_multiband_gls.py`. + +| Setting | Default | What it does | +| --- | --- | --- | +| `mb_model` | `"offsets"` | `"offsets"` / `"perband"` / `"flex"` | +| `mb_nterms_base` | `1` | flex: shared (base) harmonic terms | +| `mb_nterms_band` | `1` | flex: per-band harmonic terms | +| `mb_reg_base` | `None` | flex: ridge on the base columns (`None` = 0) | +| `mb_reg_band` | `1e-6` | flex: ridge on the per-band columns | +| `mb_regularize_by_trace` | `True` | flex: scale the ridge by the normal-matrix trace | +| `mb_fap_bootstrap` | `0` | within-band bootstrap resamples (0 disables) | +| `mb_fap_seed` | `0` | seed for that bootstrap | + +(how-much-does-it-help)= +## Which model, and how much does it help? + +`benchmarks/multiband_recovery.py` simulates faint RRab-like stars on a Rubin-like +six-band cadence — a 3-year span, WFD epoch shares (*r*/*i* deepest), 0.20 mag per-point +noise (about an *r* ≈ 23 halo RR Lyrae in single visits) — and sweeps the *total* number +of epochs across all six bands. Recovery means the periodogram's top period is within 1% +of the truth, with no harmonic credit; 300 stars per cell. + +| strategy | 30 epochs | 60 epochs | 120 epochs | +| --- | --- | --- | --- | +| best single band (*r*) | 0.0% | 37.3% | 97.3% | +| any single band | 0.0% | 49.3% | 99.0% | +| multi-band `perband` (0,1) | 17.7% | 97.0% | 100.0% | +| multi-band `flex` (1,1) | 20.0% | 97.0% | 100.0% | +| multi-band `offsets` (1,0) | **81.7%** | **99.7%** | 100.0% | + +*"any single band"* counts a star as recovered if **any** of the six per-band searches +lands on the right period — an optimistic upper bound on per-band searching, since in +practice you don't know which band was right. + +:::{warning} +These are simulations, on a deliberately simplified cadence: epochs land on random nights +with no rolling cadence and no lunation weighting. Read the *ordering*, not the absolute +numbers. What it shows is that **spending parameters on a shared phase** is what buys +sparse-cadence recovery: the models that give each band its own phase freedom (`perband`, +and `flex` through its per-band harmonic) sit far below the shared-phase model at 30 +epochs, and only catch up once each band is close to separately solvable. +That ordering is consistent with Rubin's own alert-production study and with VanderPlas & +Ivezić (2015), and it is why `"offsets"` is the default. +::: + +Practical guidance: -## A note on the default grid +- **`"offsets"`** — the default, and the right first choice for a period *search*, + especially when bands are sparse. +- **`"flex"`** — when the fold shape is genuinely chromatic and you want the model to say + so; also the model to use if you want to compare against astropy's flexible method. +- **`"perband"`** — a decoupled quick look, or when you suspect the bands are not + phase-coherent (e.g. blended sources, or photometry from instruments you don't trust to + share a time system). + +## The fold-based methods + +PDM, conditional entropy, String-Length, and SuperSmoother join the existing MHAOV (pooled +`F`) and BLS (shared ephemeris, stacked depth-SNR) with the same structure: **each band +keeps its own mean curve, histogram, or normalization**, and only the resulting statistics +are pooled. + +```{math} +S_{\rm mb}(f) = \frac{\sum_k w_k\, S_k(f)}{\sum_k w_k} +``` + +Forcing the bands onto one common curve would be wrong: filters differ in mean magnitude +and amplitude, so a joint fold would be smeared by the band offsets alone and would look +disordered at *every* trial period. The per-band statistics are already scale-free — PDM's +`Theta` divides by that band's own variance, CE rescales magnitudes to the band's range, +String-Length rescales to Dworetsky's span, SuperSmoother divides by that band's own mean +absolute deviation — so pooling needs no separate standardization step. + +| Method | Pooled quantity | Weight `w_k` | +| --- | --- | --- | +| **PDM** | Stellingwerf `Theta_k` | `max(n_k - n_bins, 1)` (within-bin degrees of freedom) | +| **CE** | conditional entropy `H_k` | `n_k` (makes `H_mb` the entropy per observation) | +| **String-Length** | string length `L_k` | `n_k` (a string over `n_k` points is `n_k` steps) | +| **SuperSmoother** | smoother score `S_k` | `B_k`, band `k`'s baseline error (its mean absolute standardized deviation about its own mean) | +| **MHAOV** | pooled `F`-statistic | — | +| **BLS** | stacked depth-SNR, shared ephemeris | — | + +```python +pg = cup.periodogram(mb, "PDM") # dof-weighted mean of the per-band Theta +pg = cup.periodogram(mb, "CE") # point-count-weighted mean entropy +pg = cup.periodogram(mb, "String-Length") # point-count-weighted mean length +pg = cup.periodogram(mb, "SuperSmoother") # baseline-error-weighted mean score +pg = cup.periodogram(mb, "MHAOV") # pooled F-statistic across bands +pg = cup.periodogram(mb, "BLS") # joint box search across bands +``` + +The pooled PDM, CE, and String-Length statistics are **minimized** at the true period and +SuperSmoother's is **maximized**, exactly as their single-band counterparts are; +{meth}`~cuperiod.Periodogram.best_periods` handles the sense for you ({doc}`results`). A +band too sparse to be searched alone is skipped rather than fatal (the thresholds are +`n_bins + 2` points for PDM, `max(n_phase_bins, 8)` for CE, 8 for String-Length, and 3 — +the smallest span window — for SuperSmoother). + +SuperSmoother's weights are gatspy's `SuperSmootherMultiband`: `B_k` is the denominator of +band `k`'s own score, so the combined statistic is the *total* fractional reduction in mean +absolute deviation across all bands, a noisy or flat band contributes little weight, and +with one band it collapses to the single-band score. + +:::{note} +SuperSmoother pools **scores, not phases** — being non-parametric there is no shared-phase +model to fit, so each band's fold is smoothed on its own. For sparse Rubin-cadence data, +where no single band is separately solvable, the GLS `"offsets"` model above remains the +right search tool; multi-band SuperSmoother is for characterizing an arbitrary fold shape +when the individual bands are already decent. +::: + +## False-alarm probabilities + +astropy's `LombScargleMultiband` has no false-alarm probabilities at all — its FAP methods +raise `NotImplementedError`, because the single-band analytic formulas assume one sinusoid +fit to one band. cuPeriod calibrates the multi-band periodogram by **within-band +bootstrap** instead. + +Under the null hypothesis of no coherent signal, each band's `(value, error)` *pairs* are +exchangeable across that band's epochs, so they are resampled with replacement while every +observation **time stays fixed**. That preserves the window function, the per-band sample +sizes, and the heteroskedastic error distribution while destroying phase coherence. The +maximum power over the searched grid is recorded for each resample, and an observed peak's +false-alarm probability is its rank in that null sample: + +```{math} +{\rm FAP}(z) = \frac{1 + \#\{\max_r \ge z\}}{R + 1} +``` + +Two ways to get it. Standalone, when you want the calibration object: + +```python +calib = cup.multiband_fap(mb, n_bootstrap=1000, seed=0) +pg = cup.periodogram(mb, "GLS") + +print(calib.fap(pg.best_periods(1)[0].power)) # FAP of the observed peak +print(calib.level(0.01)) # 1% false-alarm power threshold +``` + +Or attached to the run, which annotates the spectrum's peaks directly: + +```python +settings = cup.GLSSettings(mb_fap_bootstrap=500) +pg = cup.periodogram(mb, "GLS", settings=settings) + +top = pg.best_periods(1)[0] +print(top.period, top.extra["fap"]) +print(pg.meta["fap_level_10pct"], pg.meta["fap_level_1pct"]) +``` + +:::{note} +The smallest resolvable false-alarm probability is `1 / (n_bootstrap + 1)`; asking +{meth}`~cuperiod.MultibandFAP.level` for anything below it raises rather than +extrapolating. `meta["fap_level_1pct"]` appears only from `n_bootstrap >= 99`. Because the +level of a *maximum* depends on the grid that maximum was taken over, calibrate on the +same grid you searched (the default does) — and with the same `mb_model`: pass the same +{class}`~cuperiod.GLSSettings` as `multiband_fap`'s second argument, e.g. +`cup.multiband_fap(mb, cup.GLSSettings(mb_model="flex"))`. +::: + +For the `"offsets"` model on a NUFFT backend the bootstrap is nearly free: the times never +change, so every resample reuses the same nonuniform points and the whole batch runs as +multi-transform NUFFTs — the same `K + 2` transforms as one power evaluation, each +carrying a stack of bootstrap strengths. The `"perband"` and `"flex"` models and the torch +backend fall back to an explicit loop over resamples, which is still native speed per +iteration but scales linearly in `n_bootstrap`. + +`multiband_fap` also accepts a single-band {class}`~cuperiod.LightCurve`, which gives an +honest bootstrap FAP for the ordinary GLS. + +## Is the peak an alias? + +Multi-band data pool several observing cadences, and the combined spectral window can +still have a strong daily or yearly comb. {func}`~cuperiod.alias_diagnostics` measures the +window of *this* sampling, predicts where it would place competing peaks, and reports how +well the periodogram actually supports each one: + +```python +report = cup.alias_diagnostics(pg, mb) +print(report.summary()) +if report.ambiguous: + print("a non-harmonic competitor is nearly as good — quote with a caveat") +``` -For multi-band input the default grid is built from the **stacked** baseline of all bands -(their combined time span), so the frequency resolution reflects all your data. You can -still override it with `grid=` ({doc}`tuning`). +The bands are stacked into one sampling for the window measurement. Harmonics and +subharmonics are reported but never make a result `ambiguous`, since `2f` is expected +structure in any non-sinusoidal signal. Works for both objective senses, so the pooled PDM +/ CE / String-Length / SuperSmoother periodograms can be checked the same way. See +{class}`~cuperiod.AliasReport` for the fields. --- -Next: {doc}`batch` — scaling to many light curves. +Next: {doc}`interop` — running these searches over LINCC/lsdb survey catalogs — or +{doc}`batch` for scaling to many light curves. diff --git a/docs/guide/prewhitening.md b/docs/guide/prewhitening.md new file mode 100644 index 0000000..f6e45d6 --- /dev/null +++ b/docs/guide/prewhitening.md @@ -0,0 +1,289 @@ +# Pre-whitening pulsators + +A periodogram answers *"is there a period?"*. A multiperiodic pulsator needs a different +question answered: *"which frequencies are really there, how well do I know them, and +when should I stop looking?"* That is **pre-whitening** — find the strongest peak, fit a +sinusoid, subtract it, look again — and it is traditionally an interactive Period04 +session, one star at a time, with the stopping decision left to the operator's eye. + +{func}`cuperiod.prewhiten` automates the loop end to end and makes every judgement call +an explicit, recorded setting. + +```python +import cuperiod as cup + +solution = cup.prewhiten((time, mag, mag_err)) +print(solution.summary()) +``` + +```text +Pre-whitening: 3 components from 2500 points over 26.96 d (backend=cufinufft) + stopped: S/N 2.88 < 4 + residual rms 0.00148 reduced chi2 0.984 D=1.00 errors: covariance + + ID frequency (1/d) +/- amplitude +/- phase S/N A/Asp note + F1 12.3400341 7.16e-05 0.0119791 4.19e-05 6.1123 235.77 0.99 + F2 17.8099479 0.000122 0.00697566 4.25e-05 0.4786 143.80 1.00 + F3 24.6799702 0.000214 0.00399532 4.21e-05 5.9160 75.66 1.11 F3 = 2F1 +``` + +Everything the run decided is in the object: the components with their uncertainties, the +residuals and their spectrum, the fit statistics, and — crucially — **why it stopped**. + +## What one iteration does + +1. **Amplitude spectrum of the current residuals.** Not power: pulsation work is done in + millimagnitudes, and the signal-to-noise criterion below is defined on amplitudes. The + default is the weighted least-squares amplitude, evaluated through the same NUFFT + machinery as {doc}`GLS ` (see {doc}`backends`). +2. **Pick the tallest peak** that is resolved from everything already extracted — at + least `min_separation_rayleigh` (1.5 by default, after Loumos & Deeming 1978) Rayleigh + widths away — and locate its apex by parabolic interpolation. +3. **Re-solve the whole model**: every amplitude, phase and the offset jointly, plus a + non-linear refinement of the *new* frequency (`refine`, `"last"` by default — the + established frequencies are swept again in the final polish). +4. **Test the new component** against the stopping criteria. If it fails, the run stops + and the component is discarded. + +Only step 1's *data-dependent* part is recomputed each iteration: the terms that depend +solely on the observation times are cached, so a fifty-frequency solution costs about +fifty-two transforms rather than a hundred and fifty. A 20 000-point TESS sector with +fifteen modes takes about a second on a laptop CPU. + +## Stopping criteria + +`stop_criteria` lists the tests a component must pass; failing any one ends the run. + +| Criterion | Setting | Meaning | +| --- | --- | --- | +| `"snr"` *(default)* | `snr_threshold` (4.0) | Breger et al. (1993): amplitude over the mean amplitude of the residual spectrum in a ±`snr_window` c/d box. | +| `"fap"` | `fap_threshold` (1e-3) | Baluev false-alarm probability of the peak in the spectrum it was drawn from. | +| `"bic"` | `min_delta_bic` (10.0) | The component must improve the Bayesian information criterion by at least this much. | +| `"amplitude"` | `min_amplitude` | A hard amplitude floor, in the units of the input. | + +```python +settings = cup.PreWhitenSettings(stop_criteria=("snr", "bic"), snr_threshold=4.6) +solution = cup.prewhiten(lc, settings=settings) +print(solution.stop_reason) # e.g. "S/N 3.42 < 4.6" +``` + +:::{admonition} How pure do you need the list to be? +:class: tip +The classical S/N ≥ 4 rule is a convention, not a false-alarm guarantee: on pure noise it +still admits roughly 0.2 spurious frequencies per light curve. For catalogue work, raise +`snr_threshold` to ~4.6 (Baran & Koen 2021 for TESS-like data) or add `"fap"` / `"bic"` +to `stop_criteria`, which control the false-alarm rate directly. +::: + +The false-alarm probability is evaluated natively from Baluev's (2008) closed form — +matching astropy's `false_alarm_probability(method="baluev")` while staying accurate for +raw Julian dates — and every component's value is reported whether or not `"fap"` is a +stopping criterion. It is also available directly as {func}`~cuperiod.baluev_fap`. + +After the loop, the accepted solution is polished with one simultaneous fit of all +frequencies and then **re-checked**: the joint fit redistributes power between close +components, so a frequency that cleared the threshold when it was extracted can end up +insignificant. Those are dropped and the solution re-fitted (`prune`, on by default; the +re-check is the S/N test, so it runs only when `"snr"` is among `stop_criteria`), and the +count appears in `n_pruned` and in `stop_reason`. + +## Uncertainties + +Reported errors are 1-sigma and come from one of three estimators, set by `uncertainty`: + +`"covariance"` *(default)* +: The linearised least-squares covariance of the joint fit. The only one of the three + that accounts for correlations *between* components, which matters as soon as two + frequencies sit within a few Rayleigh widths of each other. + +`"analytic"` +: The closed-form expressions of Montgomery & O'Donoghue (1999) — the numbers most + pulsation papers quote. + +`"bootstrap"` +: Resample the residuals, re-fit `n_resamples` times, take the scatter. No linearity + assumption, at the price of that many extra fits. Every replicate re-optimises *all* + frequencies, boxed by the same per-frequency bounds as the fit it characterises. + +The covariance and analytic errors are inflated by `sqrt(D)` with `D` the +Schwarzenberg-Czerny (1991) correlation factor (`correlation_correction`, on by default), +because real photometry has residuals that are correlated point to point and the formal +errors are correspondingly optimistic. The bootstrap is left alone — it already resamples +the residuals as they are. `D = 1` means the residuals look white. + +Phases are referenced to `solution.t_ref`, the **weighted mean of the observation times**. +That epoch is not arbitrary: it is the one at which a phase is uncorrelated with its own +frequency, so the reported phase uncertainty is the smallest — and the most meaningful — +one available. Referencing to the first observation instead would inflate it by a factor +of a few for no gain. + +## Combination frequencies + +A non-linear pulsator's spectrum is not a list of independent modes: harmonics `2f₁`, +sums `f₁ + f₂` and differences `f₁ − f₂` are everywhere, and counting them as modes is a +classic way to over-count a δ Scuti star's mode density. + +```python +for c in solution.components: + print(c.label, c.frequency, c.combination) +# F1 12.3400341 None +# F2 17.8099479 None +# F3 24.6799702 F3 = 2F1 + +modes = solution.independent() # the candidate independent-mode list +``` + +A peak is only ever explained by frequencies *stronger* than itself, and the match must +fall inside `max(3σ, 0.25/T)` where σ is the **propagated** uncertainty of the predicted +combination. Each identification also carries `expected_false`, the number of chance +matches expected for the coefficient vectors that were searched — if that approaches 1, +the identification means nothing, and you should know that without having to work it out. + +## Is an amplitude trustworthy on its own? + +Every fitted amplitude comes from the *joint* solution of all components at once, while +the amplitude spectrum reads each frequency as if it were alone. For a mode resolved +from its neighbours the two agree, and each component records both so you can check: + +```python +for c in solution.components: + print(c.label, c.amplitude, c.spectrum_amplitude, c.amplitude_ratio, c.blended) + +solution.n_blended # how many disagree beyond blend_tolerance (default 2x) +``` + +A ratio far from 1 means the amplitude is **entangled** with a component it is +correlated with: change one and the other moves. Close pairs do this, and so — far more +often in ground-based data — does a mode sitting beside its own alias sidelobe. On the +bundled ASAS-SN HADS demo every harmonic carries yearly aliases at +Δf = 1/365.25 d, and the 3f component is fitted at nearly twice what the data holds +there. + +:::{admonition} A blend flag is not a significance test +:class: caution +A blended component can be perfectly real — an alias sidelobe *is* present in the data, +and the flag never removes anything from the solution. It says the amplitude means +something only alongside the components it is correlated with, so quote them together +rather than treating the number as an independent measurement. Use `snr`, `fap` and +`delta_bic` to decide whether a component is real; use `amplitude_ratio` to decide +whether to trust its amplitude. +::: + +`blend_tolerance` (default 2.0) sets the factor. Two is deliberately loose: the ratio +carries the noise of both measurements, roughly `sqrt(2)/(S/N)` in relative terms, so a +factor of two is a ≳3σ statement even for a component that only just cleared S/N ≥ 4. + +## The spectral window + +Irregular sampling convolves every real peak with the **spectral window** +`W(f) = Σ wⱼ exp(2πi f tⱼ)` of the observation times, so a candidate sitting where a +stronger component's window has a lobe — classically at ±1 c/d for single-site +ground-based data — deserves suspicion before it is called a mode. + +```python +solution.window # AmplitudeSpectrum of |W(f)|, kept with the spectra + +grid = cup.uniform_frequency_grid(t.max() - t.min(), maximum_frequency=5.0) +window = cup.spectral_window(t, dy, grid=grid) # standalone, no brightness needed +``` + +`|W(f)|` is dimensionless with `|W| → 1` towards zero frequency. To vet a doubtful pair, +compare the residual spectrum around the weaker peak with the window displaced to the +stronger frequency: if the peak reproduces a window lobe in position *and* relative +height, it is the sampling talking. The GUI's spectrum view has a *window* toggle that +overlays it scaled to the tallest peak (the Period04 convention), and +`cuperiod prewhiten --save-spectrum` writes it into the `.npz` alongside the spectra. + +Keeping the window costs nothing: its sums are already part of the cached normal +equations that make each pre-whitening iteration a single NUFFT. + +## g-mode period spacings + +For γ Dor and SPB stars the next question is the period spacing, whose mean value fixes +the buoyancy travel time and whose slope traces near-core rotation. + +```python +series = cup.find_period_spacing( + [c.period for c in solution.independent()], + [c.amplitude for c in solution.independent()], +) +print(series.summary()) +# Period spacing: 16 modes, = 2962.1 s (0.0342835 d), slope +0.008011, +# rms 1.9 s, Pi_0(l=1) = 4189 s +``` + +{func}`~cuperiod.spacing_spectrum` scans trial spacings with a comb response — unlike a +histogram of consecutive differences it is unaffected by missing radial orders — and +{func}`~cuperiod.find_period_spacing` then extracts the longest chain of modes following +a *tilted* pattern `ΔP(P) = a + bP`, bridging steps of up to `max_gap` radial orders (so +up to `max_gap - 1` missing modes). Use {func}`~cuperiod.echelle` for the diagnostic plot +in which a clean series is a near-vertical ridge: + +```python +x, y = cup.echelle(series.periods, series.mean_spacing) +``` + +The same functions work on frequencies, where a regular spacing is the p-mode large +separation or a rotational splitting. + +## Many stars at once + +{func}`~cuperiod.batch_prewhiten` runs the whole pipeline over a glob, directory, or +DataFrame with the same worker machinery as {doc}`batch`, and writes **one row per +extracted component** — the shape a frequency catalogue wants. + +```python +cup.batch_prewhiten( + "lightcurves/*.csv", + settings=cup.PreWhitenSettings(max_frequencies=20), + device="cpu", + sink="modes.parquet", +) +``` + +**`batch_prewhiten` forces `store_spectra=False`**: the full amplitude spectra are large +and rarely wanted a million times over. + +## From the command line + +```bash +cuperiod prewhiten star.csv --snr 4.6 -n 30 --spacing --csv modes.csv +``` + +```bash +cuperiod batch-prewhiten "lightcurves/*.csv" --out modes.parquet --workers 8 +``` + +See {doc}`cli` for the full option list, and {doc}`gui` for the interactive version — +the desktop app runs the same analysis with the amplitude spectrum, the residual overlay, +the frequency table and a period-spacing explorer side by side. + +## Settings reference + +Every field of {class}`~cuperiod.PreWhitenSettings` is documented in the +{doc}`API reference <../api/index>` and overridable from the environment as +`CUPERIOD_PREWHITEN_`. The ones worth knowing first: + +| Setting | Default | What it controls | +| --- | --- | --- | +| `max_frequencies` | 30 | Hard cap on extracted components. | +| `snr_threshold` | 4.0 | The Breger criterion (see the note above). | +| `min_separation_rayleigh` | 1.5 | Resolution guard between components. | +| `samples_per_peak` | 10 | Frequency oversampling of the search grid. | +| `maximum_frequency` | max(pseudo-Nyquist, 50 /d) | Top of the search band. The floor matters: the median-gap pseudo-Nyquist of nightly ground-based sampling is a few c/d, and a band capped there sees only the *daily aliases* of a δ Scuti or HADS star. | +| `uncertainty` | `"covariance"` | Error estimator. | +| `blend_tolerance` | 2.0 | Factor beyond which a fitted amplitude is flagged as blended. | +| `refine` | `"last"` | Per-iteration refinement; the final polish is simultaneous. | +| `combination_max_order` | 2 | Largest `Σ|nᵢ|` in the combination search. | +| `backend` | `"auto"` | GPU when available (see {doc}`backends`). | + +## References + +- Breger, M., et al. 1993, A&A 271, 482 — the S/N ≥ 4 criterion. +- Baluev, R. V. 2008, MNRAS 385, 1279 — the false-alarm probability bound. +- Loumos, G. L., & Deeming, T. J. 1978, Ap&SS 56, 285 — frequency resolution. +- Schwarzenberg-Czerny, A. 1991, MNRAS 253, 198 — correlated residuals. +- Montgomery, M. H., & O'Donoghue, D. 1999, DSSN 13, 28 — analytic uncertainties. +- Lenz, P., & Breger, M. 2005, CoAst 146, 53 — Period04. +- Van Reeth, T., et al. 2015, ApJS 218, 27 — g-mode period-spacing patterns. +- Baran, A. S., & Koen, C. 2021, AcA 71, 113 — significance thresholds for space data. diff --git a/docs/guide/results.md b/docs/guide/results.md index 4857c34..ceff6ad 100644 --- a/docs/guide/results.md +++ b/docs/guide/results.md @@ -72,7 +72,7 @@ The `extra` dict carries quantities a method computes at each peak: | Method | `extra` keys | | --- | --- | | GLS | `fap` (false-alarm probability) | -| BLS | `depth`, `duration`, `transit_time`, `depth_snr`, `sde` | +| BLS | `depth`, `duration`, `t0` (mid-transit time), `depth_snr`, `sde` | | TLS | transit shape scalars (depth, duration, …) | | others | method-specific where applicable | @@ -82,6 +82,27 @@ print(top.extra.get("fap")) # GLS # print(top.extra["depth"], top.extra["duration"]) # BLS ``` +## Is the best peak an alias? + +Irregular sampling convolves the true spectrum with the **spectral window**, so a single +signal at `f_true` shows up as a family of peaks at `f_true ± m·f_w` — one set per +sidereal day, synodic month, and year. Picking the tallest is a convention, not a +measurement. {func}`~cuperiod.alias_diagnostics` measures this light curve's window, +predicts where it would place each competitor, looks each prediction up in the +periodogram, and scores it against the peak being diagnosed: + +```python +report = cup.alias_diagnostics(pg, (time, mag, err)) +print(report.summary()) +report.ambiguous # True if a non-harmonic competitor scores >= threshold (0.7) +``` + +A score of `1.0` means "the periodogram likes this frequency exactly as much as the one +being diagnosed", on both objective senses. Harmonics and subharmonics are listed but +never make a result `ambiguous` — `2f` is expected structure in any non-sinusoidal signal. +Omit the light curve and the classic ground-based suspects (sidereal day, solar day, +synodic month, year) stand in for a measured window. See {class}`~cuperiod.AliasReport`. + ## The raw spectrum The full arrays are attributes — use them directly for plotting or custom analysis: diff --git a/docs/guide/tuning.md b/docs/guide/tuning.md index 188914c..eee9856 100644 --- a/docs/guide/tuning.md +++ b/docs/guide/tuning.md @@ -10,7 +10,8 @@ Each method has a settings model with documented, defaulted fields (a pydantic m {class}`~cuperiod.GLSSettings`, {class}`~cuperiod.BLSSettings`, {class}`~cuperiod.PDMSettings`, {class}`~cuperiod.CESettings`, {class}`~cuperiod.MHAOVSettings`, {class}`~cuperiod.StringLengthSettings`, -{class}`~cuperiod.TLSSettings`. Pass one via `settings=`: +{class}`~cuperiod.SuperSmootherSettings`, {class}`~cuperiod.TLSSettings`. Pass one via +`settings=`: ```python pg = cup.periodogram(lc, "GLS", @@ -29,8 +30,8 @@ res = cup.periodogram(lc, ["GLS", "BLS"], settings={ ### Settings shared by most methods -The Fourier and fold methods (GLS, PDM, CE, String-Length, MHAOV) share a common set of -knobs that shape the **trial grid** and **peak selection**: +The Fourier and fold methods (GLS, PDM, CE, String-Length, MHAOV, SuperSmoother) share a +common set of knobs that shape the **trial grid** and **peak selection**: ```{list-table} :header-rows: 1 @@ -47,7 +48,9 @@ knobs that shape the **trial grid** and **peak selection**: - Highest trial frequency. `None` → a pseudo-Nyquist limit. * - `nyquist_factor` - `5` - - Multiple of the median-sampling Nyquist used when `maximum_frequency` is `None`. + - Multiple of the pseudo-Nyquist used when `maximum_frequency` is `None` — the *average* + rate `0.5·N/T` for GLS, the *median*-sampling rate `0.5/median(Δt)` for every other + method in this table (MHAOV included). * - `samples_per_peak` - `5` - Frequency oversampling — higher = finer grid, more compute. @@ -95,6 +98,15 @@ knobs that shape the **trial grid** and **peak selection**: - `n_phase_bins`, `n_mag_bins` (the 2-D histogram resolution). * - **String-Length** - the shared grid/peak settings only. +* - **SuperSmoother** + - `primary_spans` (the candidate span fractions, default `(0.05, 0.2, 0.5)` — strictly + increasing, each in `(0, 1]`), `middle_span` and `final_span` (the CV-residual and + final smoothing passes), `bass_enhancement` (Friedman's alpha, `0`–`10`, pulls the + chosen spans toward the largest; `None` disables it), `batch_periods`. `minimum_frequency` + earns extra attention here: an integer *multiple* of the true period folds to a + coherent curve too, so bounding the trial periods from above (the longest period + searched is `1/minimum_frequency`) is the cleanest way to keep `2P`, `3P`, … from + crowding the peak list. ``` The {doc}`API reference <../api/index>` lists every field of every model with its type, @@ -111,8 +123,8 @@ export CUPERIOD_BLS_MAX_PERIOD_DAYS=30 ``` (The BLS/PDM/etc. prefixes follow the model's `env_prefix`; String-Length uses -`CUPERIOD_SL_`.) A settings object you pass explicitly takes precedence over the -environment. +`CUPERIOD_SL_` and SuperSmoother `CUPERIOD_SUPERSMOOTHER_`.) A settings object you pass +explicitly takes precedence over the environment. ## Custom grids diff --git a/docs/index.md b/docs/index.md index 43e1b19..d3c4179 100644 --- a/docs/index.md +++ b/docs/index.md @@ -16,10 +16,13 @@ Optimized, GPU-accelerated periodograms for astronomy **cuPeriod** computes period-search statistics for variable stars and transiting systems — from a single light curve to millions. One Python API, one command-line -tool, and an optional desktop GUI cover seven methods, each with a fast CPU backend and +tool, and an optional desktop GUI cover eight methods, each with a fast CPU backend and GPU-accelerated paths: the NVIDIA CUDA fast paths plus a portable PyTorch backend that -also reaches AMD, Intel, and Apple GPUs (and a CPU-only path). Add frictionless column -handling, multi-band support, raw-spectrum output, and an N-best-periods utility. +also reaches AMD, Intel, and Apple GPUs (and a CPU-only path). Seven of the methods search +several filters of one star jointly — including a native multi-band GLS with three models +and bootstrap false-alarm probabilities — and the LINCC adapters run the whole thing over +nested-pandas / lsdb survey catalogs. Add frictionless column handling, alias diagnostics, +raw-spectrum output, and an N-best-periods utility. Every implementation is validated against an established reference (astropy's `LombScargle` / `BoxLeastSquares`, and others) to floating-point round-off. @@ -43,7 +46,7 @@ then shows how to load your own. :::{grid-item-card} 📖 Learn the package The {doc}`User Guide ` walks through inputs, methods, results, backends, -tuning, multi-band, batch, and the CLI. +tuning, multi-band, LINCC catalogs, batch, and the CLI. ::: :::{grid-item-card} ⚡ Scale to millions @@ -51,6 +54,11 @@ tuning, multi-band, batch, and the CLI. resumable across runs. ::: +:::{grid-item-card} 🎵 Analyse a pulsator +{doc}`Automated pre-whitening ` extracts a δ Scuti or γ Dor +frequency solution with uncertainties, combination frequencies, and period spacings. +::: + :::{grid-item-card} 🔬 Trust the numbers The {doc}`benchmarks` page shows parity, period recovery, and speedups on real survey data. @@ -71,12 +79,19 @@ you drag across peaks — `pip install "cuperiod[gui]"`, then `cuperiod-gui`. | **BLS** | eclipses / box-like transits | ✅ | ✅ | | **MHAOV** | sharply non-sinusoidal signals (multiharmonic AOV) | ✅ | ✅ | | **TLS** | limb-darkened transit matched filter | ✅ | — | -| **PDM** | non-sinusoidal folds (Stellingwerf) | ✅ | — | -| **CE** | sparse survey data (conditional entropy) | ✅ | — | -| **String-Length** | eclipsing / eccentric shapes | ✅ | — | +| **PDM** | non-sinusoidal folds (Stellingwerf) | ✅ | ✅ | +| **CE** | sparse survey data (conditional entropy) | ✅ | ✅ | +| **String-Length** | eclipsing / eccentric shapes | ✅ | ✅ | +| **SuperSmoother** | any repeating shape, non-parametric (Friedman) | ✅ | ✅ | + +All eight share one API, one CLI, and the full single/batch machinery. See +{doc}`guide/methods` for a decision guide and {doc}`guide/multiband` for the joint models. -All seven share one API, one CLI, and the full single/batch machinery. See -{doc}`guide/methods` for a decision guide. +Multiperiodic pulsators need more than a single best period. {func}`cuperiod.prewhiten` +extracts the whole frequency solution — iterative sinusoid fitting with principled +stopping criteria, propagated uncertainties, combination-frequency identification, and +g-mode period-spacing tools — over the same inputs and backends. See +{doc}`guide/prewhitening`. ## Install @@ -84,7 +99,7 @@ All seven share one API, one CLI, and the full single/batch machinery. See pip install cuperiod # CPU (numpy, scipy, astropy, finufft) pip install "cuperiod[gpu]" # + CUDA 12 GPU backends (cupy, cufinufft) pip install "cuperiod[torch]" # + portable PyTorch backend (AMD/Intel/Apple GPUs + CPU) -pip install "cuperiod[fast]" # + numba multicore CPU kernels (all methods, 20-300×) +pip install "cuperiod[fast]" # + numba multicore CPU kernels (all but GLS, 20-300×) pip install "cuperiod[gui]" # + interactive desktop GUI (cuperiod-gui) ``` @@ -108,7 +123,9 @@ guide/methods guide/results guide/backends guide/tuning +guide/prewhitening guide/multiband +guide/interop guide/batch guide/cli guide/gui diff --git a/docs/installation.md b/docs/installation.md index 2235d74..e63b7a0 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -19,27 +19,29 @@ CPU, the command line, and batch processing over a process pool. | --- | --- | --- | | **gpu** | `pip install "cuperiod[gpu]"` | CUDA-12 GPU backends (`cupy-cuda12x`, `cufinufft`, the NVIDIA runtime wheels) | | **torch** | `pip install "cuperiod[torch]"` | the portable **PyTorch** backend — runs every method on AMD (ROCm), Intel (XPU), Apple (MPS), and a CPU path | -| **fast** | `pip install "cuperiod[fast]"` | multicore `numba` CPU kernels for BLS, PDM, CE, String-Length, MHAOV, and TLS — the CPU default when installed, one to two orders of magnitude faster than the fallback CPU paths | +| **fast** | `pip install "cuperiod[fast]"` | multicore `numba` CPU kernels for BLS, PDM, CE, String-Length, MHAOV, TLS, and SuperSmoother — the CPU default when installed, one to two orders of magnitude faster than the fallback CPU paths | | **gui** | `pip install "cuperiod[gui]"` | the interactive desktop GUI, `cuperiod-gui` (PySide6 + pyqtgraph) — see {doc}`guide/gui` | | **pandas** | `pip install "cuperiod[pandas]"` | pandas `DataFrame` ingestion | +| **nested** | `pip install "cuperiod[nested]"` | nested-pandas `NestedFrame` light curves, one row per object — see {doc}`guide/interop` | +| **lsdb** | `pip install "cuperiod[lsdb]"` | the same adapter over lazy, dask-partitioned lsdb HATS catalogs | Extras combine, e.g. `pip install "cuperiod[gpu,fast]"` or `"cuperiod[gui,torch]"`. :::{tip} The `[fast]` extra is worth installing even without a GPU: it gives BLS, PDM, CE, -String-Length, MHAOV, and TLS multicore JIT kernels that are one to two orders of -magnitude faster than the fallback CPU paths while matching them to floating point. -When present they become the default CPU backends automatically. +String-Length, MHAOV, TLS, and SuperSmoother multicore JIT kernels that are one to two +orders of magnitude faster than the fallback CPU paths while matching them to floating +point. When present they become the default CPU backends automatically. ::: ### What the `[fast]` extra changes Installing `numba` flips `backend="cpu"` (and the CPU fallback of `"auto"`) from the fallback implementations — astropy's `BoxLeastSquares` for BLS, the vectorized numpy -kernels for PDM, CE, String-Length, MHAOV, and TLS — to in-house multicore JIT kernels. -Nothing else about your code changes: the results match the fallbacks to round-off -(BLS still matches astropy), they just arrive much sooner (~20× for BLS over astropy; -~25–300× for the others over their numpy paths). (Note that `numba` currently caps +kernels for PDM, CE, String-Length, MHAOV, TLS, and SuperSmoother — to in-house multicore +JIT kernels. Nothing else about your code changes: the results match the fallbacks to +round-off (BLS still matches astropy), they just arrive much sooner (~20× for BLS over +astropy; ~25–300× for the others over their numpy paths). (Note that `numba` currently caps `numpy < 2.5`, so installing it may downgrade numpy slightly.) ## GPU requirements @@ -50,7 +52,7 @@ GPU acceleration needs: - the `[gpu]` extra, which installs `cupy-cuda12x`, `cufinufft`, and the `nvidia-*-cu12` runtime wheels (no system CUDA toolkit required). -All seven methods have a GPU backend. With the extra installed and a device present, +All eight methods have a GPU backend. With the extra installed and a device present, `backend="auto"` (the default) uses the GPU and falls back to the CPU otherwise — so the same code runs on both. See {doc}`guide/backends`. @@ -91,7 +93,7 @@ cufinufft/cupy fast paths. See {doc}`guide/backends`. :::{note} **Apple MPS** cannot compute in float64 (a Metal limitation), so the Mac-GPU path uses float32. `precision="auto"` (the default) keeps float64 everywhere it is supported and -drops to float32 only where the device forces it (MPS, and some Intel GPUs); an explicit +drops to float32 only where the device forces it (MPS); an explicit `precision="float64"` on MPS raises rather than silently downgrading. ::: @@ -107,7 +109,7 @@ probe.) ## Verifying the install -List the registered methods and the backends available in your environment: +List the registered methods and every backend each one can run: ```bash cuperiod methods diff --git a/docs/quickstart.md b/docs/quickstart.md index 54cbbe0..9eb36d0 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -114,6 +114,19 @@ pg = cup.periodogram(df, "BLS", See {doc}`guide/light-curves` for every accepted input form. +## Several filters of one star + +Model all bands jointly instead of searching each on its own — one period, per-band +offsets, and far better recovery when no single band is well sampled: + +```python +mb = cup.MultiBandLightCurve.from_file("star_ugrizy.csv", band_column="band") +pg = cup.periodogram(mb, "GLS") # shared-phase model (VanderPlas & Ivezić) +print(pg.best_period(), pg.meta["bands"]) +``` + +See {doc}`guide/multiband`. + ## Running several methods at once Pass a list of methods to get a {class}`~cuperiod.MultiResult` keyed by method name: @@ -137,6 +150,20 @@ The result is identical to floating-point round-off; the GPU just computes it fa large grids and big catalogs. On a non-NVIDIA GPU (AMD, Intel, or Apple), install the `[torch]` extra and use `backend="torch"` instead. See {doc}`guide/backends`. +## Analysing a pulsator + +A multiperiodic star needs the whole frequency solution, not one best period: + +```python +solution = cup.prewhiten((t, mag, err)) +print(solution.summary()) +print(solution.frequency, solution.frequency_error) +``` + +The extraction stops on a stated criterion (`solution.stop_reason`), reports 1-sigma +uncertainties on every frequency, amplitude and phase, and flags components that are +combinations of stronger ones. See {doc}`guide/prewhitening`. + ## From the command line The same machinery is a CLI. Given a file `star.csv`: diff --git a/examples/README.md b/examples/README.md index 9867f2d..f4ecb16 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,9 +2,11 @@ ## [`cuperiod_tour.ipynb`](cuperiod_tour.ipynb) — a guided tour -A hands-on walkthrough of cuPeriod on **real light curves**. For each kind of object it -loads the data, runs the appropriate periodogram, reads the peak, and phase-folds to -reveal the signal — three pictures per star (raw → periodogram → phased). +A hands-on walkthrough of cuPeriod on **real light curves** — plus one deliberately +simulated star at the end, because the closing lesson is a search *failing*, and for that +you have to know the true period. For each kind of object it loads the data, runs the +appropriate periodogram, reads the peak, and phase-folds to reveal the signal — three +pictures per star (raw → periodogram → phased). | Object | Method | What it teaches | | --- | --- | --- | @@ -14,6 +16,7 @@ reveal the signal — three pictures per star (raw → periodogram → phased). | Long-period variable (Mira) | **PDM** | non-sinusoidal folds, long baselines | | Exoplanet (Kepler KIC 7532973) | **TLS** | a transit matched filter | | — | several at once | comparing methods, reading the N-best peaks | +| Sparse six-band star (synthetic survey cadence) | **multi-band GLS** + FAP + alias diagnostics | why joint fitting wins in the Rubin era | ### Run it @@ -32,6 +35,9 @@ the GPU automatically (`backend="auto"`). light curves (one per variability class), each with its VSX literature period. - `data/kepler_KIC7532973.csv` — *Kepler* PDCSAP flux for a confirmed hot-Jupiter host, fetched once with [lightkurve](https://docs.lightkurve.org/). +- The sparse six-band star is **not** a bundled file: it is simulated inline with numpy + from a fixed seed, on the Rubin/LSST-like cadence of + [`benchmarks/multiband_recovery.py`](../benchmarks/multiband_recovery.py). ## The desktop GUI (`cuperiod-gui`) diff --git a/examples/cuperiod_tour.ipynb b/examples/cuperiod_tour.ipynb index 54840f0..08bac79 100644 --- a/examples/cuperiod_tour.ipynb +++ b/examples/cuperiod_tour.ipynb @@ -9,8 +9,8 @@ "\n", "**[cuPeriod](https://github.com/tjayasinghe/cuPeriod)** finds the periods of variable\n", "stars and transiting planets. This notebook walks through the main ideas on **real\n", - "light curves** and shows, for each kind of object, how to pick a method, read the\n", - "**periodogram**, and check the answer by **phase-folding**.\n", + "light curves** — plus one simulated star at the end — and shows, for each kind of object,\n", + "how to pick a method, read the **periodogram**, and check the answer by **phase-folding**.\n", "\n", "### The three pictures we'll draw for every star\n", "1. **Raw light curve** — brightness vs. time. Periodic, but the period is hidden by the\n", @@ -26,6 +26,8 @@ "- **Exoplanet** — a confirmed *Kepler* planet host (KIC 7532973) in\n", " `data/kepler_KIC7532973.csv`, fetched once with\n", " [lightkurve](https://docs.lightkurve.org/).\n", + "- **Sparse six-band star (§7)** — the one *synthetic* object, simulated inline on a\n", + " Rubin/LSST-like cadence: to watch a period search *fail* we have to know the answer.\n", "\n", "> **Run it:** `pip install cuperiod matplotlib pandas pyarrow` and run the notebook from\n", "> the `examples/` folder. With an NVIDIA GPU, add `pip install \"cuperiod[gpu]\"` and the\n", @@ -46,10 +48,10 @@ "id": "6cd47ea5", "metadata": { "execution": { - "iopub.execute_input": "2026-06-30T16:27:44.712662Z", - "iopub.status.busy": "2026-06-30T16:27:44.712662Z", - "iopub.status.idle": "2026-06-30T16:27:45.488798Z", - "shell.execute_reply": "2026-06-30T16:27:45.488798Z" + "iopub.execute_input": "2026-08-15T06:01:53.641923Z", + "iopub.status.busy": "2026-08-15T06:01:53.641923Z", + "iopub.status.idle": "2026-08-15T06:01:54.441977Z", + "shell.execute_reply": "2026-08-15T06:01:54.441977Z" } }, "outputs": [ @@ -57,8 +59,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "cuPeriod 1.0.0\n", - "methods: ['BLS', 'CE', 'GLS', 'MHAOV', 'PDM', 'STRINGLENGTH', 'TLS']\n" + "cuPeriod 1.2.0\n", + "methods: ['BLS', 'CE', 'GLS', 'MHAOV', 'PDM', 'STRINGLENGTH', 'SUPERSMOOTHER', 'TLS']\n" ] } ], @@ -95,10 +97,10 @@ "id": "516be844", "metadata": { "execution": { - "iopub.execute_input": "2026-06-30T16:27:45.490301Z", - "iopub.status.busy": "2026-06-30T16:27:45.489801Z", - "iopub.status.idle": "2026-06-30T16:27:45.493309Z", - "shell.execute_reply": "2026-06-30T16:27:45.493309Z" + "iopub.execute_input": "2026-08-15T06:01:54.443484Z", + "iopub.status.busy": "2026-08-15T06:01:54.442981Z", + "iopub.status.idle": "2026-08-15T06:01:54.446995Z", + "shell.execute_reply": "2026-08-15T06:01:54.446489Z" } }, "outputs": [], @@ -154,10 +156,10 @@ "id": "c9f6fe89", "metadata": { "execution": { - "iopub.execute_input": "2026-06-30T16:27:45.494812Z", - "iopub.status.busy": "2026-06-30T16:27:45.494812Z", - "iopub.status.idle": "2026-06-30T16:27:46.736322Z", - "shell.execute_reply": "2026-06-30T16:27:46.736322Z" + "iopub.execute_input": "2026-08-15T06:01:54.447995Z", + "iopub.status.busy": "2026-08-15T06:01:54.447995Z", + "iopub.status.idle": "2026-08-15T06:01:55.621020Z", + "shell.execute_reply": "2026-08-15T06:01:55.620510Z" } }, "outputs": [ @@ -170,7 +172,7 @@ }, { "data": { - "image/png": "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ZLtGDiJkChEHfnj29va6HebrPK246qqrqKCgwOtlDVV27txJDz/8MN1zzz0UFRVF4Uh/fz8tW7aMrr76asrPz+cfQf/85z9dTvPRRx/RCSecwEI5tvv5559P27Zt22e86upquvzyy6mwsJDS0tLooIMOonfeecd0nkuXLqWjjz6aMjMzKSsri4499lhavnz5PuPhJmzlypX02muv+bDWgiB4co7A9cCfD2MwL8wT8xb27Zubb76ZLrjgApo4cWJAt4MdQrVcV+C3iS+/bwIh9t9666300EMPUWtrK61atYqHo43ou2Dw7rvv0k9+8hMWM1taWpxt+OUvf0nvvfceffzxx9TR0eEUKK1E1piYGH4A+3//939UWVkZlLYLgjDAgw8+SC+99BL997//5eP16aefDth1NRDnp2Ce8+xQUVFBf/zjH9kAoT9kMoL+xv2P1evCCy/027IUuI/Zb7/9WCTE+fi6666jxsZGU3H7tttuowkTJlBycjI/MLv77rups7Nzn3EbGhr4/D1jxgxKT0/n+Z566qk+P4gOt+0qWCNCpjAkwBM5PJ0LBr6KpkMViJh5eXl0+umnU7iCi/d9993HF9y77rrL7Y+gxx57jE477TQ6+eSTaePGjSxgnnnmmXwDp9Pe3s6OGdxMQfgsLS2lk046iS+ob7311qBx//3vf7NwOWbMGFq/fj2/xo8fT0ceeeQ+F9+ioiJeHm6yBEEIPMcffzz19PTQoYceKt0dBD788EP65ptv6Prrr5f+jqBthod13/ve9/gGFmIgKCsro7/+9a9BaQMeBpq1AcNx7MKpiRvy6Ohotzem5557LiUmJvJNuSAIwQMPHCBuzZ49e9DxKngHHtZs3bqV7xlwX2F1r3riiSeyMGh83XLLLXyexP2Lv5YFnn32WT7P4oFleXk5/ec//3GaRPTp8D/uj55//nk+H+OagvswCNz/7//9v0HzxL0bDCF/+tOf+IEW7rtgVIGRZvHixfTJJ5941HdCZCJnDGFIgIuf+iErBB8Iebjw4CIVrm5McMopp/CNDhyZubm5LseFwAin0KOPPso32XBj4sbprLPOoj//+c+Dxn388cdp8+bN9Le//Y1mzpxJGRkZ/AQR4uZNN900yN0DFwku+rgwQ8xESM0TTzzBqQ0QSm4ET0bRli+//NKPPSEIghk4f+GGSggOTz75JN/E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os0pcckUHR3NLk0Ftqe+XZW4CTx1nQoBLPazz8xiY6miosKfsxyWRFJBDGMYMAQlODv174O1vp7kbQxFeLg/cJdH0c56+XP/8mVexra6237GPJhWoc668xYipnF+xuUGY18wLkMJqGah+eF4/Pu6zyk4l88QprCwkM477zw67bTT6IsvvqCXX36ZXnzxRfrkk0/o5z//eaibJwiCIAheI/d5guA9VnkddSC42XFaGkOmhzLuHI12XJBwuiJXZmZiOo3JKKLz5pzOTkq9HyFYNnQ0cmj5uKzRg5YNN2b73krmCKc7ZuKh/D0KCOF7FACy2p5DyT07JIRMFDIw0tDQQH/84x9p0aJF/mjXsCWSCmLobYVTUAkZnlQE9+f6epq3MdzEIk9w1XZX36G/3RXCsVsYxh/bzszdZyXuYTguJBDNoyzC643ztZqfLp4anau+CImupnVXPAnv3vZpMMRPT/c5vU2e5j2NRD766CNnkR9ULMcN30EHHcQCpqfFfv7xj3/QH/7wB3Z2zp49m+6//36aOtVeJUdM9/DDD9Nll11G99xzj5drIwiCIAxX5D5PEPyPO5HSbh5FjId8jXABLhw5Z8jnXLQjABv71ThNcW0J3zemJaRy4R+ImGo8gDByVCFv6GziYaVNFc75qfnApQlUTlKuYt5aTQV7q5UbtyNynSbExpuGuwshFDKPPPLIfYalpaXRoYceSn/605/80a5hib8qQQcaq6rYnq5DINY3Up2WgUIVXdJDxmtauiwL4djtR2OBHX/1udVyVY5FVaBp3phMW4K1mVioMBMNfRFnraY1Exl1AVVNN60gjXNoeno8hOPDD7M2DfVjEy5MCJcnnHAC/frXv+aHevHxAz+UPOGtt96ic889lx555BGeH0TJww8/nDZt2kQ5OTkup121ahWPD+rr671eF0HwJ3/pOo/SU+LpVulWQYgI5D5PEPyLO5HSbh5FjIcCP8jzCCC+DQennx1Ho/E7NQ1AiDnckzDE6KKj2jbox7UVm6ispYpio2LYlYlq6moecHSiANCW2u3U0987qMr8mvKNVNFSzQKnGo7wdOTZRB5NyYsZZkImChjsM6NYv0apD0v8UQk60Liriu3JOqhx15c20pxRmaZikzeEY7+Fggff3eIU/n564jQehhOrP1DbDsKocuH6S0SzcvdBkEUBKTxRgyBmJVCa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uecGbBxBCBXWr19P3//+92n37t18vOJ+k5CQMNCrNShZuHAh7dmzh68NhYWFA706gxY8N9xxxx305JNPks1m4+cG3BsF/9Pd3U2/+c1v6MEHH+S2vummm+gXv/iFNLXAz6aPPPII7du3j8aPH8/Pi1lZWX6fJtT597//Te+++y5FRETQmWeeSWeddVafL7yef/552r59Oz+rf+9736Pp06dTOFNeXs59UjxnjB49mq699lrKzc31aFr0bXA9RxvgM5zBcfDmm29SV1cXnXLKKXTBBRf0OU1NTQ3fyzZv3kxjx46l66+/nvuo4Yov+sSWLVu4H1dUVMTXA5xDJ5xwAoUzq1evpqeffpoqKiropZde4hfcfbFs2TLWyFpbW3n7L730UoqM7F9wuISW+5mf//znfIGbOnUqjRo1iv7v//6P/vznP9NQADfw//3vfyy06H96xaqGhgY6/PDDebzjjz+e9u7dy6IMbnjejBMOoMOHi/Z7773HF7Gvv/661zg9PT108skns5AHoRM3h3nz5tEnn3zi93FCEYiRxxxzDDU3N/PDUllZmaVQgU6zfkyZXw7gBjlnzhwWKI899lgW4tAOLS0tXo0TaixdupSOO+44qq+v54s+Ol04N/75z386jfe73/2OLr74Yn5wnjx5Ml1++eX0q1/9KiDjCEIocdlll9FPf/pTvnZAYPvb3/420Ks0aPn444/pq6++GujVGPSsWLGChg0bRrt27aJPP/2Uj+lNmzYN9GoNSvCCMDExkQUKvIzH8zqe3YShDZ450e+AWIF+yOeff05z586l6upqv04T6uD574orruDnQTwXXnTRRfyc6Ar0d/DCC8/0CxYsYMECbQDxIpxFTPQd0IfDfl23bh1/h8mgL2AwQZ8Fos9nn31G4Qyujeeffz5rG9A4fvSjH7Hm0df1dcqUKSxg4bjAS2YIoOGKL/oE+uEw6EAAxbYnJSXxJ8TQcOX8889nAbexsZH77uib9gVMSdAp8GyDNrvtttv42tJvDMFv7N2714iMjDRef/11x7C///3vRkJCglFfXz/oW/qll14yMjMz3Y7z+9//3hg2bJjR1NTE33t6eozDDz/cuOCCC7waJxxoaGgwKisr+d8nn3yycdFFF/Ua59VXXzVsNpuxf/9+x7Dvfe97xpw5c/w+Tiiyb98+o6uri9sJl6P33nuv1zg3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", + "image/png": "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", "text/plain": [ "
" ] @@ -209,10 +211,10 @@ "id": "f98aaa44", "metadata": { "execution": { - "iopub.execute_input": "2026-06-30T16:27:46.737826Z", - "iopub.status.busy": "2026-06-30T16:27:46.737326Z", - "iopub.status.idle": "2026-06-30T16:27:47.163286Z", - "shell.execute_reply": "2026-06-30T16:27:47.162782Z" + "iopub.execute_input": "2026-08-15T06:01:55.622019Z", + "iopub.status.busy": "2026-08-15T06:01:55.622019Z", + "iopub.status.idle": "2026-08-15T06:01:55.963733Z", + "shell.execute_reply": "2026-08-15T06:01:55.963733Z" } }, "outputs": [ @@ -225,7 +227,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABUQAAAFKCAYAAADVOVU0AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAA7sVJREFUeJzsnQeYFEX6xr/NC2wgLrtLzkhGDKcYUEyIinqn55lz1ju9M6Ce4fQOc85nOM+csxgQ9FQEBcmSM2yABTbCLmz4P2+tNf/e3p6ZnpmemZ6Z98czzE5PdXVVdU9319tfSGpqamoSQgghhBBCCCGEEEIISQCSo90AQgghhBBCCCGEEEIIiRQURAkhhBBCCCGEEEIIIQkDBVFCCCGEEEIIIYQQQkjCQEGUEEIIIYQQQgghhBCSMFAQJYQQQgghhBBCCCGEJAwURAkhhBBCCCGEEEIIIQkDBVFCCCGEEEIIIYQQQkjCQEGUEEIIIYQQQgghhBCSMFAQJYQQQgghhBBCCCGEJAwURAkhhBBCCCGEEEIIIQkDBVFCSMzy4Ycfyrp16yTR2b17t7zzzjuyYsUKz7KNGzfK+++/L01NTVFtGyGEEEIIIYQQ4jaSmjhbJg7z8ccfS11dXfMBlpQkbdu2lYEDB0q/fv0cKe+tjpycHDn00EMd6kX8AJFs4cKFns+pqamSl5cno0ePljZt2oRcXoNTiRbgTjzxRElJSWlVZufOnfLZZ5+1WNauXTvp2bOnDBkyRO1/u7z99tty3nnnyZo1a1T7rNi0aZMsX75cdu3aJQUFBdKrVy/p3Lmz1zaNGjVK+vfvb1nPrFmz1N/jx4+XDh062GqjnTFxgrKyMunSpYvcd9998re//U0t2759u/Tp00eeeOIJOfPMM8OyXUIIIYQQQgghJBahIEocB4IThC0tTpaUlCgxaezYsfLGG28oYSqU8t62OWzYMPnmm2+4R03cf//9ct1118lhhx0mHTt2lNraWpk3b57U1NTIgw8+KOeff35I5TXTpk2TI488Uv39ySefyMSJE1uVgTUnRDoI3sOHD1fLKisr5eeff5Zu3brJv//9bznggAP87sP6+npVxx/+8Ae59957W33/1VdfyY033ijLli2TvffeWwmYmzdvlvnz58tBBx0k119/vad9uk0AoiUETDOXXnqpPPPMM+pvtHWfffaxdZzZGZNwCaLglltukZdeeklWr14t6enpYdk2IYQQQgghhBASa9BlnoSFoUOHKhdevL7//nuZPn26er/oooscKU8C51//+pcaXwhzEMgg6l144YUtrEFDKf/cc89J3759ZfDgwepvXxx//PGe/f3ll18qK09YcZ5yyinS0NBgy1V+7dq1csEFF7T67vnnn5ejjz5aDjzwQCkuLpbvvvtOPvroI5k7d66sWrVKiaMvv/xyq/VgPfrpp58qcdEIBGEI871795ZACWRMwgHEa1i3YpwJIYQQQgghhBDSDAVREhEOOeQQ2XfffeWLL76QPXv2OF7eGxDvIAZZ1bF161b13YYNG9RnWA9+8MEH6m+IczNmzJDPP/9cfYYgqAW8d999V4l4ENu8AWvKb7/9VglxixcvFreRmZkpV155pXLlNruwB1MeIiIsK2FJedlllykRFZa+doFIOWHCBGXF6WtcNS+88IJy4R80aFCL5bD2vPzyy5Wl52OPPabCKBiBJSj2MdpoBtamsKJ89dVXWyx/7733pLq6Ws444wwJBLtjoo/D0tJS9fmXX35RZdevX++17vLycnVswiIa8UO9ATEWQjZEYkIIIYQQQgghhDRDQZREDMSKhKuzXYEz0PJWFBUVKatDiFpmHnjgAfnjH/8oycnNPwNY8CHW4o8//qhEpLvuuktuuOEG9d3KlSuVlSBeEMzgityjRw9lwWoOwwu3crj5QwRD/MZx48YpN207Ql8kwfhq8TfU8v/973/VOMIi8ZxzzpGMjAx58cUXA2oPYpdmZWV5jQeqwTEBsRkWoGbgcg+B0Og2boVVrFls++STT5b//Oc/LZajH8ccc4zk5+dLINgdkyVLlqhjFBbRsJz985//LLfddpsSM+++++5W5eEC3717dyVQ//Of/1QPDhAawBs49lC33f1MCCGEEEIIIYTEO6nRbgBJDJDgBS7LSJyDpElOl/cGXKeRJOepp55S4qcGohmsDPE9xCWj2PbII4/IzJkzJTc3VwmhAIIYXkZ++OEHFWcTwhyS+wDEmfzrX/8qTz/9tFxyySWevhxxxBEe0cstIM4msBsP01d5WCCeeuqp0qlTJ/X59NNPV8sQx9MqURLET+3GXVVVpepG3Ngnn3zSb6zLX3/9VVng6hikRiBmQ4SESBgM5557rkqaBMviESNGKOthhG946623Aha0Ax2T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GeTYY491/fr1C9v3008/WX2uW7fOnX766fbeHHbYYVkuI3KH6dOnm2UlLue8q9dcc4079NBDk34erA7pO+nP+vTpY20lkhkzZlj737Nnj2vSpIlr27Zt2O+/+uqrDL856KCD3OWXX+7yG9rugw8+6I477jjXu3fvpB+f+hkxYoSbM2eO69q1q7vgggsylMEykPeSfqtGjRru+uuvDwWixxUel/hotG7dutC/b4sXL7Y+748//rC216ZNm6TX4a5du9zo0aOtHV966aWuVatWUdvRa6+9ZmMqc58bbrghbH5IG4jGRRddZHMmUfigXTFXHj9+vKtYsaIbNmyYWcmL3GX//v3W337xxReuZMmStpDUoEGDpP8mXUBuY4zfuHGjO+uss9ytt95qoTvitduRI0faXJ9xCnmKfjE/5rzJhvF24MCBJisSgua6665zNWvWTOi3f/31lz07GD58uCsIIEu89dZbJuP/61//sjlMUJ6Ixs6dO609zZ071+aLPJMTTjjBFYQFS/QcS5YsceXLl3c33XSTO+mkkzKdn9AW0AvQnpizNW7c2BUEpk2bZmMWcif/J8LEiRNtvPvnn3/Mm6l9+/Y5ugZlmc8Hvv32W3f22WebwIJA8/7777v69evbwJCuoNjlPhjYg3/BSTwCLp0gwi73vXnzZpuwLViwIEtl8hMEGeoOgYn7RbCPBKGda0aBxuCOgI8yjwlCssvkFXTAlStXduPGjTProZkzZ2Yos23bNqu35s2bh7WBoALX8zzXsmVLU5SjVCxatKj9jxIwK2XyCgbh8847z23YsMHqoHjx4q5hw4bu5ZdfDivHwIbwjCLkzDPPdD169HC33357rpTJK1io+fTTT20Ch1COogfhncl8cCGEdyBY35dccknYcWi/tGOEfN5pFOooV5noZKWMyB26d+9uyjuUz5UqVXKDBw+2trdp06aknufhhx+2uv3ll19swkN/EQn7ec9451lIQ5kXXHjhPURxG/mHm3d+w3vRsWNHe2f8OKbJhIkf7yECJ0IFi6rR5ha8r0uXLnWnnHKK9SeNGjVy+/btC42v0Z4ff4QbKMyggKQPot3T940aNSrqIm9OJ/0sbKIIYTJPfUVCf0odMsZS31wHYxBCpE+sOmReIgonvOssmKxdu9b6WhaRmUuJ3IXnTPZj5uYoKVhIibVgkZPfpIvCi7jd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", + "image/png": "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Z52l1rMikLG14l//+pda385rxowZPut69913VR8XLVrUWF5e3vjDDz80HnzwwY2pqamNU6dO9bnuVVddpbYxbdo0R+o99thjGwsKCvz2nxDiH1xH8Pu84IILmi0vLS1V56aLLrrIs+z6669Xv81ly5Y1K6vPlfg9G+vEucoMftf47rvvvvMsu/TSS1W9a9eubVb2jjvuUGVnz56tPl9yySXq2oe2GUHbUe7ll18OuM6LL75Y9XPLli3NymF9c52++uUNlMU1w1zHFVdc0azcddddp/qGa7KRG2+8UfVj586djYHyxhtvqG19/fXXIe13u3279tprG1NSUhoXL17sdR293Xnz5jV+8803je3bt1fXX5z/NStXrmxMTk5WY2Jm3333bXZPhPuXtm3bNlsf1+f8/PzGM844w7Psl19+Udu95557LI/dMWPGtLgfQz149wV+C2jrn/70J69lcB+CbeC+xAzuX8z3W+hTVlZW47Zt25otR3/atGnTWFFRoT7X1NSoe8ZTTz21Wbkrr7xStWnjxo3NltfV1TUmJSWpY54Q4i4w35kwYYLlffwHH3zQbPmnn36qlj/xxBPq89atW9Xnhx56yFMGcxer8/+TTz6plhvPWW+99ZZa9uabbzYrizkNzkd6XhpInVbY7Q+uAfiM870RXM+x/MEHH/S5HVw7UA71mDnxxBMbMzIyGgOhpKREXYcxPwllW3fffbcqi7r+8pe/NG7evLlx9erVjaeccoo6Z3/22WdBtQH8/e9/V9taunSp+vzVV1+pbT311FOWc8+PPvpI3fesW7eu8YEHHlDXfVyLcJ3wRajHAHEHtBQlEQdP6WHpYAaWLrAWhQUintLA+hMvPJWDVYDmqKOOku+++049PcOTMVjd4SkZ3KZgNQrwJA1WK3CNChU88YEVprnNsCb0FtQZ38HlzgjcL+AiEWwSJ1iP4KkgwgI4GX/O2/646KKLlFULxtL4RA7uGrDSBLDcgMUKrFDMbcJ+ggWNHctJI7C8wlNCb4QythdeeKGyNLXzgtufL9BnuEAOHTpUuR3iyTGsmPLz830m8MATRTwRRoIlq+MzmHoxXnayRxJC7GNO9AbXObguG13VELYCVoOwaDGy3377KatHs8UarL7tgG3AIh/hQowgBqL+Xls2wKoQbTNidlsLpE5Y1MG60WzFbnWd8Nevf//732rM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r3mEJDjX8TwZD/CaZ3+cAOd5hBAS39e8pEaayARNQ0ODFBUVqay+SGARjHqNC+3GjRslJydHEolE7Tv7nVj7G3Cfu3ef4/KHC2VhYaEkJzOaTLiveWC//faTn3/+Oah1SWKPYTz1O5b64sa2uqFNkW6DE/cSvOYFBud5zpKo98NWcCw4Hjw2wv9bCeSaR0vREMDgdu3aVUIFOzhRLw6J2nf2O/HgPncntBCN7DUvJSUlIc/5TpKoYxhP/Y6lvrixrW5oU7TaEOq9BK959uE8Lzwk6v2wFRwLjgePjfD+Vuxe82gaQwghhJCIMGnSJI40xzDhj51Y+h24sa1uaJMb2kAIIYSQ0KEoSgghhJCIQCGBY8hjJ7Z+B25sqxva5IY2EEIIISR0KIpGkYyMDLntttvUe6KRqH1nvxNrfwPu88Tb54QQQoiTJOq9RCzDfcbx4LHB3wrPG7FxHmWiJUL+v70zgbdq6v//qpQhGYpQSKGQElEqjzSopBFlaiBkeCRzhAcZkocMydNEUiplaEAoGUqjBqSURGlUqWiW9u/1/v7/+7z2Ofecc8+999x7z7n38369bp29zzp7Wmuvtb7f9R2EEEIIIYQQQgghRKFCiZaEEEIIUSAyVE6YMME+V6lSxbJDi6zxzjvvuN27d7vSpUu75s2b6/GlIR988IHbunWrO/jgg93ll1+e35cjhBBCCJHSSCkqhBBCiLRnx44d7uOPP3Y///yzq1mzppSi2eCzzz5za9ascatWrZJSNE35+uuv3YoVK9yXX34ppagQQgghRCbIfV4IIYQQBYYhQ4a4hQsXuldeeSW/LyUt+fHHH91VV11lz1CkJ1iKnnbaaW79+vX5fSlCCCGEECmNLEXziWXLlrlBgwbZhPXMM8+0LJalSpVy6QrC05NPPplhP0LpscceG9revn2769+/v/v+++/dMccc42666SabuAdJpEx+8vvvv7vXX3/dffPNN+722293F110UYYyq1evdv/73//cr7/+6k455RSr37Jly+ZKmbxi79697t133zX31HPPPdfdc889Yd//9ttv7q677srwu8cff9xVrVo17Di0/dmzZ7sjjjjCde7c2Y4Xea7MyuRlfb/55ptu0aJF7qijjjLLmzp16mQo98knn9jz4dqbNGnirr76alekSJFcKZMX/P333+7tt982qyPOX7duXbuW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", "text/plain": [ "
" ] @@ -253,7 +255,8 @@ "\n", "Eclipses are *dips*, not sinusoids, so the box-search **BLS** (designed for flat-bottomed\n", "transits/eclipses) is a natural fit — it even reports the depth and duration. BLS works in\n", - "**flux**; cuPeriod converts the input magnitudes automatically.\n", + "**flux**; cuPeriod converts the input magnitudes automatically, so the reported\n", + "`extra[\"depth\"]` is in those flux units — divide by the star's flux level for a fraction.\n", "\n", "This is also a perfect cautionary tale: a detached binary shows **two** eclipses per orbit\n", "(primary + secondary), so a Fourier method like **GLS latches onto half the true period**.\n", @@ -266,10 +269,10 @@ "id": "d9973ec6", "metadata": { "execution": { - "iopub.execute_input": "2026-06-30T16:27:47.164786Z", - "iopub.status.busy": "2026-06-30T16:27:47.164286Z", - "iopub.status.idle": "2026-06-30T16:27:47.931474Z", - "shell.execute_reply": "2026-06-30T16:27:47.930967Z" + "iopub.execute_input": "2026-08-15T06:01:55.964739Z", + "iopub.status.busy": "2026-08-15T06:01:55.964739Z", + "iopub.status.idle": "2026-08-15T06:01:56.704821Z", + "shell.execute_reply": "2026-08-15T06:01:56.704318Z" } }, "outputs": [ @@ -278,13 +281,13 @@ "output_type": "stream", "text": [ "BLS best period = 2.59953 d (VSX: 2.59959 d, type EA/D)\n", - " transit depth = 0.0000, duration = 0.192 d\n", + " transit depth = 51.81% of the flux level, duration = 0.192 d\n", "GLS best period = 1.29973 d <- half the orbit!\n" ] }, { "data": { - "image/png": "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799fDXjRoR1BH+09QERERMZiwJOIiIjIiwYOHCjHjh3LcP38+fPN2WDIkkcnW2RBIPulX79+FkfGyXdt3rxZdd+2htkQ3bt3N19Gti66sCPDA5kfDz30kM3Md/I9vXv3Njff02AGxu+//24xMwOZnsh8QWPDAQMGSKNGjbywtkRERMGBAU8iIiIiIiIiIiIKGDm8vQJERERERERERERERmHAk4iIiIiIiIiIiAIGA55EREREREREREQUMBjwJCIiIiIiIiIiooDBgCcREREREREREREFDAY8iTzoueeek2+++cZr2zgqKkruvvtuiYmJsbvMoEGDZMaMGdm2Ts8//7wsW7Ys2x6PiIiIiIgo0CQnJ0vLli1l9+7d3l4VIp/EgCeRQZ555hn5/vvvLa7bu3evnD171mvbeNSoUVKnTh0pVKiQ3WX2798vZ86cybZ16tKli7z88suSmpqabY9JREREREQUSNLT02XTpk1y7do1b68KkU9iwJPIIHv27JFz585ZXDdr1iwVCPWGiIgImT17trz00kviS7p27SoJCQny+++/e3tViIgoEwsXLpTjx497/DZGMurxlyxZIkeOHHG4DA7e/fLLL5KSkpKl+zHSr7/+KtevX8+2xyMiIiLyRQx4Ehlg8ODBcvDgQZk2bZqaVoBTXFycTJo0Sf755x/zco8//rh89dVX8s4776hMx+7du8vSpUslNjZWRo8eLR06dJDevXvLrl27MjzG4sWL1d/uuusuNS388OHDDtfpxx9/lNq1a0vNmjUtjgJ++umn0rFjR3Vf8+bNy3C7YcOGqfW/4447pEePHvLJJ59YDOQw/f3pp5/OcLshQ4ao56VltmI6P57Ps88+K9u3bzcvlyNHDunZs6cKxhIRUfZbsGCBnDhxwqllkZG/YsUKl+7fndsYyajHf+2119Q+2pGpU6fKd999J2FhYVm6HyP99ddf8t5772Xb4xERkeemq//7779qrIkyZX379pUDBw5kWPbKlSvyxhtvyD333KPGm9ZT3DHmxH21atVKHnnkEfnpp58y3AfGrI8++qgaJ77yyisWiTwYQ2IM261bN/UYGC/iMYl8HQOeRAZAALJChQpqJ4CAIk558uTJMKUdgUwMxBITE1WAsFKlSirjEUHMkJAQefPNN6VgwYJqh4aAqX5A9b///U/tgBAYLVmypDRt2tRh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", + "image/png": "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799fDXjRoR1BH+09QERERMZiwJOIiIjIiwYOHCjHjh3LcP38+fPN2WDIkkcnW2RBIPulX79+FkfGyXdt3rxZdd+2htkQ3bt3N19Gti66sCPDA5kfDz30kM3Md/I9vXv3Njff02AGxu+//24xMwOZnsh8QWPDAQMGSKNGjbywtkRERMGBAU8iIiIiIiIiIiIKGDm8vQJERERERERERERERmHAk4iIiIiIiIiIiAIGA55EREREREREREQUMBjwJCIiIiIiIiIiooDBgCcREREREREREREFDAY8iTzoueeek2+++cZr2zgqKkruvvtuiYmJsbvMoEGDZMaMGdm2Ts8//7wsW7Ys2x6PiIiIiIgo0CQnJ0vLli1l9+7d3l4VIp/EgCeRQZ555hn5/vvvLa7bu3evnD171mvbeNSoUVKnTh0pVKiQ3WX2798vZ86cybZ16tKli7z88suSmpqabY9JREREREQUSNLT02XTpk1y7do1b68KkU9iwJPIIHv27JFz585ZXDdr1iwVCPWGiIgImT17trz00kviS7p27SoJCQny+++/e3tViIgoEwsXLpTjx497/DZGMurxlyxZIkeOHHG4DA7e/fLLL5KSkpKl+zHSr7/+KtevX8+2xyMiIiLyRQx4Ehlg8ODBcvDgQZk2bZqaVoBTXFycTJo0Sf755x/zco8//rh89dVX8s4776hMx+7du8vSpUslNjZWRo8eLR06dJDevXvLrl27MjzG4sWL1d/uuusuNS388OHDDtfpxx9/lNq1a0vNmjUtjgJ++umn0rFjR3Vf8+bNy3C7YcOGqfW/4447pEePHvLJJ59YDOQw/f3pp5/OcLshQ4ao56VltmI6P57Ps88+K9u3bzcvlyNHDunZs6cKxhIRUfZbsGCBnDhxwqllkZG/YsUKl+7fndsYyajHf+2119Q+2pGpU6fKd999J2FhYVm6HyP99ddf8t5772Xb4xERkeemq//7779qrIkyZX379pUDBw5kWPbKlSvyxhtvyD333KPGm9ZT3DHmxH21atVKHnnkEfnpp58y3AfGrI8++qgaJ77yyisWiTwYQ2IM261bN/UYGC/iMYl8HQOeRAZAALJChQpqJ4CAIk558uTJMKUdgUwMxBITE1WAsFKlSirjEUHMkJAQefPNN6VgwYJqh4aAqX5A9b///U/tgBAYLVmypDRt2tRh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", "text/plain": [ "
" ] @@ -298,7 +301,8 @@ "pg = cup.periodogram((t, m, e), \"BLS\")\n", "peak = pg.best_periods(1, alias_diverse=True)[0] # alias-aware peak for box searches\n", "print(f\"BLS best period = {peak.period:.5f} d (VSX: {P_vsx:.5f} d, type {vtype})\")\n", - "print(f\" transit depth = {peak.extra['depth']:.4f}, duration = {peak.extra['duration']:.3f} d\")\n", + "depth_frac = peak.extra['depth'] / np.median(10.0 ** (-0.4 * m)) # depth is in flux units\n", + "print(f\" transit depth = {depth_frac:.2%} of the flux level, duration = {peak.extra['duration']:.3f} d\")\n", "print(f\"GLS best period = {cup.periodogram((t, m, e), 'GLS').best_period():.5f} d <- half the orbit!\")\n", "show(t, m, pg, title=f\"Eclipsing binary ({vtype})\", period=peak.period)" ] @@ -322,10 +326,10 @@ "id": "acef3f21", "metadata": { "execution": { - "iopub.execute_input": "2026-06-30T16:27:47.932472Z", - "iopub.status.busy": "2026-06-30T16:27:47.932472Z", - "iopub.status.idle": "2026-06-30T16:27:48.129867Z", - "shell.execute_reply": "2026-06-30T16:27:48.129867Z" + "iopub.execute_input": "2026-08-15T06:01:56.705825Z", + "iopub.status.busy": "2026-08-15T06:01:56.705825Z", + "iopub.status.idle": "2026-08-15T06:01:56.891363Z", + "shell.execute_reply": "2026-08-15T06:01:56.890860Z" } }, "outputs": [ @@ -338,7 +342,7 @@ }, { "data": { - "image/png": "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Qo1rcKzAoYh9Q13PFYh2wxhfFXsEOGegn6AF4BgKdcevAu5uFWGlwLFy+umn87/xHabBOQX7gQLRehhH4jyD8ZwZ0VkidgqCIAiCELQg7xfSN9xzzz18E3nXXXexoK0etCDEetasWfyADiIGEv9DoEMqDHwuuAYpMTCgff755zm/IZLl46YU4YgAObjR13iogJBFpBnBgA5i0UB4AOwr2A/RvyhkhwEeQt3AggULuJ+xb2NghFxuKDyEB4YoXLB06dIegorgGPUA8Nlnn2XBSYUJQpBHKCn2X1T8xbkDYYQIMcYDEjzARTEtQRAEQRDCExE7BUEQBEEIWpATSxXL0/NILl68uIejAiIScmbB8Yxq674mNR8o3H777b2qYMJpoRfBgbsfAjJyMcO1jkqqEJeFvoEA76jgwHvvvWfP9QaHO/ZfuGTgBoHQDAFU6Jvrr7+eHVNG4OhUxfEQdYL8X3CMoLgWKt8eeuih0r2CIAiCEMaI2CkIgiAIgiAIgiAIgiAIQlgg1dgFQRAEQRAEQRAEQRAEQQgLROwUBEEQBEEQBEEQBEEQBCEsELFTEARBEARBEARBEARBEISwQMROQRAEQRAEQRAEQRAEQRDCAhE7BUEQBEEQBEEQBEEQBEEIC0TsFAQT+Ne//kXXX399v/bleeedR99++63T75977jm68sorA9aeJ554gu65556ALU8QBEEQBEEQBCGcWLVqFR100EH93QxBCDlE7BQED3n44Yfppptu6vHZ3r176ccff+y3vnz99ddp48aNdPDBBzudZt++fbRp06aAtenUU09lsXPHjh0BW6YgCIIgCIIgCEK4UF9fTytXruzvZghCyCFipyB4yJ49e2jz5s09Prv22mtZBO0v/vrXv9I111xDERERFCwMGjSITjzxRHrggQf6uymCIAiCC3bt2kXvvvuu339jJmYtHw8CFy9e3Od069atozVr1vg8H7PAfYgMfgVBEARBEBwjYqcgeMCLL75Ir7zyCq1YsYLDCfD66quv6L333qPHHnvMPt39999Pt956Kz399NN0xhln0DHHHEOPPPIIdXd301NPPUUnnHACLVq0iN58802HA5grrriCjjzySDr33HPp448/dtkmDL7Wr19PP//5z3t8/sEHH9BJJ53EguN9991HXV1dvdygah0WLFhAt9xyC1VWVvYImTjkkEOo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", + "image/png": "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", "text/plain": [ "
" ] @@ -373,10 +377,10 @@ "id": "41e70161", "metadata": { "execution": { - "iopub.execute_input": "2026-06-30T16:27:48.131371Z", - "iopub.status.busy": "2026-06-30T16:27:48.131371Z", - "iopub.status.idle": "2026-06-30T16:27:48.316964Z", - "shell.execute_reply": "2026-06-30T16:27:48.316964Z" + "iopub.execute_input": "2026-08-15T06:01:56.892863Z", + "iopub.status.busy": "2026-08-15T06:01:56.892363Z", + "iopub.status.idle": "2026-08-15T06:01:57.077517Z", + "shell.execute_reply": "2026-08-15T06:01:57.077013Z" } }, "outputs": [ @@ -389,7 +393,7 @@ }, { "data": { - "image/png": "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ZubMmekukhBCCFEokJAphBBCiCIHghPWmG3btk13UUSW8OKLL5rWrVubqVOnmrFjx5q77rqr0FraIRrefffd9jw4H87rpZdeSmuZ3nvvPVOxYkXz559/WqvMF154oVBbZt5xxx3m/ffftxaZnTt3Nt27d093kYQQQohCQcl0FyDbYDX19ddfN0uWLDH77ruvufHGG02lSpVMUQD3mCuvvDLX57fddps58sgjg+937Nhh3nrrLfPDDz+YChUqmIsuusgcc8wxJluYN2+eeeONN8y0adNsUHGsBhJpJ9nUlqLVyZtvvmm++eabkM/q169vnn/++aysk3///dd88MEH5qeffjLFixc3Rx11lL0P+LsotxNROMDFdMCAAWbMmDGmVq1a5uqrr7b3a7JBPMEiDCu3vn375ro/4MsvvzTfffedKVmypDn77LPN0UcfHfxu8uTJ5vfff8+1zS677GJOOukkU9jZtGmTueaaa8znn39uGjVqZN5++21z0EEHmWwEMY0XQfIR1Jo3b56ybKK0bcIO3HnnnVY088Mz9+uvv7Yu5CeffLJ97jrGjRtnbr/9dvs3Fpn16tUzf/31V0h52W7w4MG2fVavXt2ccsopKbl/YMKECearr76yxz/nnHNyfU9ZBg0aZEMrNGzY0Bx44IFm4MCB9pyaNWtmy4+lIJx77rmmV69e+RZHP/74YytE8txo0KBBrt8sWLDAtukNGzbY+7lVq1Yh9duuXTtTrFgxU6NGDXPEEUfYc6xbt27IPrZu3WqvEefFeZxxxhl2m2TDtf3oo49sWTifSFaX48ePNzVr1rTPKH4LCNyzZ88OPouo31dffTXpZSxqEHrg3XffNUOHDrXPi/POO8+ceOKJSdmGsSx9EdetRYsW5oYbbjDlypUz6YB7l7KMGjXKPqcuvfTSkLlWfrfhHmI8uXLlSrvgV7ZsWZMOuE9ee+01e+9Xq1bNXHHFFfY5ld9t+O7TTz81ixYtslbn9KW1a9dO8dkYs3HjRvPyyy/bsQljkY4dO5p99tkn39skst9Usnr1atO7d28776Mf6dSpk2natGm+t+F5igfNqlWr7FyS52465zzLli2zZZ41a5a1rr/++uvD9muJbsOC3QMPPGD78Icfftiki/nz55tXXnnFzJ07145tbrrpJtunJWMbxiD01/TRF198ccg4PhqyyEwif/zxh31Q0kC5CDwg6SCYbBQF6DgYoDLoRJRxLyZYXi6//HIrZh188MF2EH/CCSfYTjIbePbZZ60oywCculi6dGlC7SSb2lIsdcJEhAGit93gOuYlm+qEDun777+3rnp77bWXueeee8xZZ51lRf6i2k5E4WDNmjVWeH/88cdNkyZNTPny5e29itiYTNq3b28nk0wYEei894bjvvvus79DTC1durSdeCLqe0UGBrz+F4JYNsBAGOGNidiDDz5o+1Ym5NkEwhfPtFtvvdVeT8Rzxg6pcCmmTe+9997WQo4Jw/r163P9BpFv//33t5NgrOgoCwtxDrZhgdaBWMAir4MBPZbADO5x00aIZ6LGMZMJVoqHH364ncD36dPHfPLJJ2EX1LhnEGxZCHv66aetEP7cc89ZcS7aucQLixKca79+/Wz9Ilj6GT16tL0GLE5wvRH5GC86YikT+6VfvP/++60IQ90ifiYT6g4BGiGb8St1HA7qn2cUZeK86fuZmLpz4fmZ17mI+EFcpE1znyFwY3GPqJXfbUaMGGGFIdcu6QsZq6YLjs0z69BDDzWVK1e24+wPP/wwadvce++9VjRi3J6u+Lj0Z6eddpoV+Fm04P1hhx1mBef8bMPz5+abb7YC2LHHHmuf54zFUx0rG3GY0BhYlrMgR/9NH5LXmCSWbRLZbyrh2Ub/g4EKcxMELZ7JCJT52eayyy6z/RQiJ+NQ+inEzGSPP2OF41LPjEuo/4kTJ9o+lLInYxt0lQsvvNC2T54/6eLvv/8OXgvKzEII55BXHPBYtuHeJKzKddddZxcT0I8eeeSR+EI9BUTSOO200wInnXRS8P3KlSsDFSpUCLz44otFopaXL1/ODCowYcKEiL/55Zdf7G9++umn4Gf33XdfoHbt2oGtW7cGCjtz584NbNu2LbB48WJ7nkOGDEmonWRTW4qlTm688cbAWWedled+sqlO5s+fH/a+GDNmTJFtJ6JwcN111wUaN24cWLNmTfCz1atXBzZs2BD291OnTg1p145169YFBgwYEPE4kydPtv+///779t7w9w9z5swJlChRIvDRRx8FP3vyyScDlStXjliWSHTp0iXw7LPPBtLB77//Hvjmm28C//77b9jvt2zZYvtLXvzthXv/u+++C75v1KhRrmdLYWfz5s0h4wV49913A8WKFbN9Szh4Dk6cODHX5zt27AiMHDky4rGGDRtm2yV9FG2OPsvLxo0bA9WrVw88/PDDwc969epln7kcEy688MLAO++8EzxevXr1AgsWLAj+nn3OmzcvV/+3++67RyzX6NGjbR/qZ/r06YElS5aE3Wbp0qXBejv55JMDl156aa7fvPTSS/Z+WbRokX1/yy23BCpVqhTYdddd7XnQlurUqWPPA/r37x+4+OKL7TX5+eefwx53xIgREc/jxx9/tOPEP//8M1d/52jWrFngyiuvDL7/+OOPA8WLFw9MmzYteK927949+H2rVq3sfr0cffTRgdatW4fcU+Hag2P8+PH2uoerQ3dcP+yb+5a64foddthhuX7z7bff2nbKPQ7bt28PtGnTxvbbwLa0nVWrVtn31OkhhxwSsZwiOlOmTLFta/DgwcHPHn/88UCVKlUCmzZtSngb/q9bt27ghhtuCNn2n3/+Sctl4TlGmX/77bfgZ7fffnugYcOGwfs1P9vQtvfaa6/AW2+9ZbcJd38UBJ988om9/+nvHR06dAi0aNEiX9v4+0nO/4ADDgh07NgxkEr69u0bKFOmTGDZsmXBz84888zAMccck69tEtlvKunZs6ftK127oX6PPPLIwLnnnpuvbfzXjbFezZo1A0888UQgHdx99912POzGZoxTmzdvHujUqVNStqFvufbaawOXX3552q4lXHXVVfb+oA9zz8P69esH7r///kB+tnnzzTcDpUuXtmMZB9d9xYoVgViRkJkkGNRwMV5//fWQz9u1axc49dRTA0VJyGQAfNlll9nBvn+i0a1bNzuw98Igj+3Gjh0byBYiiXaxtJNsbUvRhMw99tjDtpubbrop8MEHH4QMrLK1ThxMJKmbr7/+OlDU24nIXBAwypUrF3jqqadi3ua5556zYon3+b5+/XorNhx++OFRF7AiCZmvvPJKoHz58iHiHv0Nv2USFguIsf369Qu0bds20L59e/t3QS2oIcAiWjA5psz0n36oM77n2ciLv731eOCBB4ZMStlfXguJ2cKsWbNsnUUSJXv37h2oUaNG4I8//gh+Rn/CRIFJezShO5KQ+dVXX9nPvZMpBEwE9ffee8++//TTTwN77rln4PPPP7ciQSyTj86dOwf222+/sN/xnEdQQIh0EwKYMWOGbQ8ILtGIJGQee+yxdrwG3DNNmza1kywmxO5zJpK33XZbYNCgQfa8vvjii8CX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TZo0ySxcuDBt9Xn//feb/fbbz1SqVCnib6ZOnWoWLFhQYGU67bTTzM0332y2b99eYMcUQgghhBBCiEyEudiUKVPSXQwhCjUSMoVIgIkTJ5pFixaFfPbWW29ZgTMdLF682LzzzjvmxhtvNJnEWWedZdasWWMGDRqU7qIIIUSRZ8OGDeaDDz4w69evT+k2ySRZx//333/tfuiTovWn3333Xb73kyxWrFhhvvjiiwI5lhBCCCFEYUBCphBxcsstt5g///zTvPjii6ZVq1b2tWnTJtOrV68QN+qLLrrI9O3b13Tr1s2cfvrpVtQbOnSodf3GevK4446zv8GS089XX31lLrjgAvub6667zsyaNSvPMvXv399aYzZt2jT42Y4dO8wzzzxjjj/+eHPhhReajz/+ONd2d955py3/4Ycfbsv37LPPmq1btwa/7927t+nYsWOu7Tp37mwee+yxoKjLbygr///+++/B35UoUcKcffbZ5n//+19MdSuEECI+EPgQ1hD8orF8+XJz8cUXmyVLlsS8/0S2SSbJOv7atWvtfubPn5/n7wjBEq5fjnc/yaJKlSrmjjvuMIMHDy6Q4wkhhMi/2/inn35q53nMj55++umw3mnM9y699FJz0kknmccffzxkDsaCmptnMpdj/un3qqM/6tq1qznllFPMOeecY41qvMyZM8fcdNNNpk2bNnYu+Mknn+jSiqxBQqYQcXL99deb+vXrW+Hvueees68yZcrkci1H0MNCctu2beb222+32+BqTWdSqlQpK2aWL1/edl4bN24Mbvf8889b8ZJ4lw888ICpUaOGadmypZk9e3bEMg0fPtx2dF7uu+8+06NHD3P55ZebSy65xDz66KNm7NixIb+55pprbPkRMOlIEV45P8dRRx1lRUjvsYnF+corr5hDDjnE/PPPP+boo4821atXNw8++KA9N7bHgsSBSPrDDz9YYVUIIURyQeBDWEPwi0aFChXsZCavECSZRkGW+eeff7b9aSZ5N5QsWdIuOt5zzz3pLooQQogoIDa+/fbbpnv37rZvJofCU089Zbp06RLyu/Hjx1sjGH5DToGXXnrJPPzww8HvDzrooOA8k+c/oiVzL28uBPb9/fff2zBeV111lRk9erR544037HfTp0+3v69YsaKdo7lwX8wzhcgGSqa7AEIUNpo1a2YFyF133TWXeOiH1TEEREDwo2NDlMRKE4444gjbwYwbN84cc8wx1lUNAfKbb76xvwdW8mbMmGGtK+nkwvHXX3+Z1q1bB98jJNJRvf/++6Zdu3b2swMOOMDsvvvuIdvttddewb85F94feOCBdlsmjy1atLAdKWLmI488Yn+HC3vdunXNCSecYEaOHGk2b95sevbsaYoVK2a/p0P20rBhQ9vpMsmuXbt2HDUthBAiL7DewKIDcD+uVauWfT7zvKcf4flP/4FVP8/4qlWr2s94vgMLTAMHDgwKZo0bN7bb8nes0G+5Y/39999m5syZtq9p3rx5rt+uXr3aioXFixe3fSHlDbefvMrsnSwyEaQ/PvLII+3/fqZNm2Y9KPbYY4+QY0WCPhbRtFy5cjHvJ5Y6xCOCvnW33XYL2fbDDz+0E022wWWdusHClu3r1asX/B1lYgLK99HGHUIIIdILRixYZPJsh8qVK9vnOGKm60Mwgvn888+Di3Rz5861cyw3b6xZs6Z9OTBwoV/96KOPrIAJP/74ozUuwfMP2rZta70EAYMZvPuefPLJ4D7oRzGWwbNOiMKOhEwhUsjBBx8c/BsrTDokhEEHkyUmac5lDotJrDNZeWOiFwgE7GvevHlm7733jngcxMSyZcsG30+ePNl+htjoaNSokdlzzz1DtuO4uMhjPbpy5Urb8TIpYzK6zz772N+wSogbOauElAlR84orrrB/77///laIPe+886zlJ+Ir5+PFlct1rEIIIZInZA4ZMsT+jesxkxREMCz5WVRicsPznMkPfQC/53NEOcRGXN0+++yz4L4mTJhgXZm//fbbmBeecLFmn6eeeqq13meRb9SoUdYTwYUgcSFQEOMQMOkP6e9YoMOKxLufaGUGvA3ok7D4Z5Fs6dKldkLoFfkeeughawWDZwGip19E9EPfh5D68ssvh3webT+x1GG/fv1s+ZikOpiA4nZInfFiMZPrRv3Rh+PijiUmsD+E0C+//FJCphBCZDj0VU7EBLzvtmzZYr33MFABjEe8ngYNGjQICaFC30Kf8fXXX9vYzczRyM/g9ZJjX8wZ8ZbD/ZzjuoU4vAvoU+i73HySEDQYu+BR5xVJhSiMSMgUIoUwWfOC1WK4z+hcwCUzIE6KV5h0q3mRYLJEp+TA/QCh0W9V4rVooUNl4oS4SWzLXXbZxR6fyahXdMQtnfhcTJaZTGGZ4lYCcSlHBCUeDBM9JmVnnnmmjdHiyk+5OEf2L4QQInlghYjbGVaZLEq5iRNCGGD5gaWms5hHIPRCf0R8Te/ECYsOLELYXzywL7KwEhuZcCJMsM4991wrwE2dOtVageACd+ihh9rfI3YyuWPyhWDpiFZmJoJ4LpBEzlmhIIbyImYzlpB//PGHFVGJS33sscfa88JDIi84Dgt6XkvSWPYTSx0SxgXLGCw+XV9OKBd37nfddZc9rksyxD6cpa2DONh4bwghhMhs/B4EWF/SNzE/c+Q1H3QWlfQt/E8OBPp7FgO9czQ8/Vgoo7+gX8SSH/GTBUPmdCyI0R/5yWtOKURhQUKmEAngrCWTjbM2oTOLx30M1zRvkp0mTZpY6xIsWJwlJ5YiuKA7mOjiAohrHlaVzkLED6uFTMCYdCFkMpnzrjKygoirPC+sVXBHpxO99tpr7feUiwlYOLc/IYQQqYNJjxME8wJxECEPa406deqYX375Je5jYYGJiAnES6ZfwnUaIRNrTOJE412A+5zrP+kXfvrppxAhM1qZcePed999gyImMNGj/0TI5HjuuPRXQLmwbkT8jIRbDKxWrVrws3j2k1cdkoiBhT8mpfSN/IbzcLHMWHTEqhRrHLblOCwKeqFc9NdCCCEyG5LsMO9yYiWhUrCoZH4WK4QkIVcCnnFAv4nlpRf27xbynPcCxicsGtInYn2pcCQiW1GyHyESAAtIb2KfZIGrNu7Zt912m3UfcIwYMSLPCRjxwwjw7FbpcAvH6gWXODpOIGMe1iYO5wKOGxywSshqXjjoRHGLYxLmzWLOMYkB42BSygTMu8qIJYuL0ymEEKLgIF5mXmCxgdsZloG4VPM8x6rSP1mKBe8CF+CCjWgJCHz0T8T2YnJG5lRexPzyhyOJVmb26Z8MciwWGN3xEEzDlScv3IKeN/t7LPuJpQ7pFwnJwoIgIGLST5599tn2PX0+Fjfs+7DDDrOJGRA2vVCuwpSkSQghiiqrVq2ynmrOwp5nOotizPNihcUrr5EKIVXok7wwz3PJf+hTWBRzczCyldPnEHbGwdySBENCZAOyyBQiATp16mSzfOM+hws1cUiSBRM9VtaYqLGaxmSGji9Soh8gFiZJdZggtm/f3n6Gu/cZZ5xh3QyYoGEN4+JeApMmgk6zLXFa6Bz9FiAOkhJRFsRbr1sdky4ynlNeJnvEbSErHnXjJq9jxoyx1jhCCCEKlmjWmK+//rqNMcnz34UDITHAq6++mtDEzWtZyXuXUA43NiwNvS7YiZaZuF5OsPQmEcILwcX8Ii4YFpL+8uUFfRgTQCxpXLlj2U+sdcgiIGFjcLNncknYFtwN3YSV/psJKQuE9Ku4C+I1Ubp0afsbb7mEEEJkdmJYQoVgdU/uA/qGvAxSwoFwSQ4CYjdjbUl/5BdC6bOYi9G/0g+y2IUnAeBWTn9FiBe2xbWdpHJPPPFEUs9ViHQhIVOIBMDCkFUtJhYk1WEyQlxIXMccAwYMsB2LFyw1cMX2Qkfntfhw8cGYGOGqzcTQu99IEz8sLnHtw60A6w/cuXFlYNLE5A5Bk7+9cVGYbGEJgkDJcbCMoeOjA/bDPrAW9cbuRBxl8kW2WURLzo3O0kFssVtvvTUk+6oQQojk4SwJ6YviBVdmnv3uuY7rGpaSiUDCGxINAf0XgpxL5INrNRM6Yjzicu5g4oVQF0/oEawfe/fubftg17cwcaNvc5M8fvPaa6/ZcrgMsdHOizKQPIgQK5Q31v3EWof081ht4vlA3bzwwgvB7+iD6U+ZhBKnmr6Uc2HfJP9BpCVjeSICsxBCiIKFeRvedCTpof8gBjJCotfTjbBdXvBQcHGSgZAmzAMJE0bMTQxQpk+fHtJfYulJsh8Wvficfsa7GEjYFcKhzJgxw/Yv/u+FKMwUC6Qi0J8QIi0QP4vO0p/kJ7/gfk62dSxTvFad6SqPEEKIHBjGIaSx0IRFPIIYC0osZjGJ8i6oseCE9YbLAI6gRjxLFsH22GMP6/L866+/2njILsmOfxs/xFvmWIRcueyyy6w3wSuvvGKFPcQ3F1Oa78i6fcstt9jysrCGhcrIkSOtO7nbT7QyA4Ig4h+uc0wSe/bsaV/E13R1gicBbt/XX3+93QcWjgiD9GPE2AwH3gNkQ+dYse4nljp0ILgyeUXwdWFdgAVFEumdfPLJdrLJwihhYag/YHJL/ZHZ3VlxCiGEyDzIGUBYLfoGIUTqUIxMIbIIxMZki4bE6yK7OZPPeETMVJVHCCHETrCuQOhC/CNzKeE8sK6/8MILcz1/sergcxdrEYtDkgIQf5Htzj//fOv+TViSSNtEYtiwYdYKBavLiy66yL5HxHRlRCTkhasbxyIcCglxXEzMWMsMX3/9tbX2Z7GMJD0Iok7EdMcbMmSIdd+mPOybpELsxx+T0wvfU2aXMTyW/cRShw6yx+Ix4SxVHbiSI4Tink6dcDzqz0H2czKbS8QUQgghhJBFphAiCliE4FKHS4MQQgjhJZIlZWGF2NeIlZGS3+UHBFfCv2BZGS1kjIM42ZQFt3JvIj0hhBCZB+7gJFDFI00IkTrkWi6EEEIIIRIi24TMVE1ssbB89NFHzVlnnWVjWgshhBBCiMRQsh8hhBBCCJEQkVzCxU6I54n7/xVXXGETLwghhBBCiMSRRaYQQgghhBBCCCGEECLjUbIfIYQQQgghhBBCCCFExiMhUwghhBBCCCGEEEIIkfFIyBRCCCGEEEIIIYQQQmQ8EjKFEEIIIYQQQgghhBAZj4RMIYQQQgghhBBCCCFExiMhUwghhBBCCCGEEEIIkfFIyBRCCCGEEEIIIYQQQmQ8EjKFEEIIIYQQQgghhBAZj4RMIYQQQgghhBBCCCGEyXT+D8XGwHQ5T/3zAAAAAElFTkSuQmCC", + "image/png": "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pb37y09JpBnXhLGYaoZKD+bC766TcjTLAlETXEupKs/3Mq5tXItoL9fi0047bch2HehYGUcJh7oCkXHwoRp1MBjM+h7VXN/61rdqdTCqbl500UXJbdu2Jc844wz9l86ePXu0ChnLUQEus/LlySefPKL2jLSaOVDdmkpwVCibNWuWVg2lEibLplfsHmof3UraTz/99KCqn1RqLysrS3q9Xl33hg0bhm0z1Ubf9KY3abU0Kk1TPY4q2ulVV9kWFTlZHxV0qf46VDXzocYjs938G6ptmzZt0srX1dXVuh9UXKcS3N13350cC1/72te0am762I62bw8G9C//2Ge2744h/7Zs2TJo2ebm5uQHP/hB3S+q5zGXbrzxxn3WyXixLnc9mf/SYY5SNX7RokVaQXDatGlaIbepqWnINlM1l8qJw1XNdavKM44jqUprGC9H3OrSHNtUtOR6VFhYmLz88suTjY2N+yy/bt06fW/y5Ml6LFPd9LLLLkvef//9+6wzG9mqmQPnWap2c27kPLBs2bJ9KnvDzTffrOcK1jF79mytxu1WEU2vPD6adfIalUJZJxVQ//SnPyV/8IMf6DrTz0PD7RfXc65pVCAtKChIvu51r9NrKpXSzzvvvP2u48orr9TPZTKS69twfOELX0hWVVXtU9F8NOM+0n1zq3EzH1g31/YlS5Ykf/Ob3wxUlc+2/2zvhBNO0DnF54Hr5tVXX63VWxk7Kr2zveuuu04rrbrbYoyYE5mwDbaVWSGWtlHllX3let/W1pa1mjn7le071FAVYfk8c8c9Jq644opkXV3doD6kwi5jSds+9rGPJTs6OoasZs4+cV3kesg6ly5dmrzrrruGbAPr5nNf/OIXs76/cuVKfX+4dRiGceRVM3fhusV5lPMl5xnuOe+9995By2RWM3f58Y9/nJw5c6aea6iKzXmCStrZrtXco7z+9a/Xez7e53NcN5577rkxrzMbI9kfqplzbszkmmuu0X5qb28fcv1cE937wmz3KZmVw7///e/rstyju3A/OdQ91Eiu20NVMx/tslxDP/CBD+h9Edun37kHzbz/HIoDHSvjyMbD/w61oGocXHARMOyjCXVyn+5nfmao13nKzpOXkeS8oD1uePRwrw33ZAoHAaFSrltlqH3kNdo81HpHs92xkG37Ix0P+pQnXmMJURsLOIcIdaRwAk+5XMba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pqIoiqIouQ5EJ6wyW7VqleiiKGnC22+/bZo3b27mzp1rJk2aZB577LGUtbhDOHz88cflODgejuudd95JaJm++OILU7x4cbNo0SKxznzrrbdS2kLzkUceMV9++aVYZnbu3Nn06NEj0UVSFEVRlJQhf6ILkG4wq/rhhx+atWvXmpNOOsl07NjRlChRwuQGcJW5/fbbs3z/0EMPmTPPPNP7+dChQ+aTTz4xv//+uylWrJhp06aNOeecc0y6sGLFCvPRRx+ZefPmSaBxrAeiaSfp1JZC1cnHH39sfvnlF5/vqlatat588820rJN9+/aZr776yvz5558mb9685qyzzpLrgPe5uZ0oqQHupoMGDTITJ040FSpUMHfeeadcr7EGAQXLMKzd+vfvn+X6gJ9++sn8+uuvJn/+/Oaqq64yZ599tve32bNnm+nTp2dZ56ijjjIXXnihSXV2795t7rrrLjNkyBBTs2ZN8+mnn5omTZqYdARBjReB8xHV6tWrF7cso7RtQhA8+uijIpy54Z47bNgwcSe/6KKL5L5rmTx5snn44YflPZaZVapUMUuWLPEpL+uNGDFC2mfZsmXNxRdfHJfrB6ZNm2Z+/vln2f/VV1+d5XfKMnToUAmzUL16ddO4cWMzePBgOaa6detK+bEYhGuuucb06dMn2wLpt99+K2Ik941q1aplWWbVqlXSpnfu3CnXc7NmzXzqt3Xr1iZPnjymXLly5owzzpBjrFy5ss829u/fL+eI4+I4Lr/8clkn1nBuv/nmGykLxxPI+nLq1KmmfPnyco9iWUDkXrp0qfdeRP2+//77MS9jboMwBJ9//rkZNWqU3C+uvfZac8EFF8RkHZ5l6Ys4bw0aNDD33XefKVKkiEkEXLuUZfz48XKfuvnmm33GWtldh2uI58lNmzbJpF/hwoVNIuA6+eCDD+TaL1OmjLntttvkPpXddfjt+++/N2vWrBHrc/rSihUrxvlojNm1a5d599135dmEZ5H27dubE088MdvrRLPdeLJlyxbTt29fGffRj3To0MHUqVMn2+twP8WTZvPmzTKW5L6byDHP+vXrpcyLFy8WK/t7773Xb78W7TpM2j399NPShz/33HMmUaxcudK89957Zvny5fJs06lTJ+nTYrEOzyD01/TRN954o89zfDioZWYMmTFjhtwsaaScCG6SdBIMOHIDdB48pPLg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", "text/plain": [ "
" ] @@ -428,10 +432,10 @@ "id": "e69f619c", "metadata": { "execution": { - "iopub.execute_input": "2026-06-30T16:27:48.318467Z", - "iopub.status.busy": "2026-06-30T16:27:48.317968Z", - "iopub.status.idle": "2026-06-30T16:27:49.201613Z", - "shell.execute_reply": "2026-06-30T16:27:49.201110Z" + "iopub.execute_input": "2026-08-15T06:01:57.078519Z", + "iopub.status.busy": "2026-08-15T06:01:57.078519Z", + "iopub.status.idle": "2026-08-15T06:01:57.775588Z", + "shell.execute_reply": "2026-08-15T06:01:57.775588Z" } }, "outputs": [ @@ -449,7 +453,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAwwAAAF5CAYAAAAyD60gAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjExLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlcelbwAAAAlwSFlzAAAPYQAAD2EBqD+naQAAlYdJREFUeJzt3Qd4U1UbB/C3ey8otFDKKntPZQpOEBRxMFQU3KAiCipORP2QJcOBiChDUBEQ2Uv23hQoq0ChdO+9m+Z73tPeNEmTNG3T5qb5/56nT9vMm3Nv7j3vOe85x0apVCoJAAAAAABAB1tdNwIAAAAAACBgAAAAAAAAg9DDAAAAAAAAeiFgAAAAAAAAvRAwAAAAAACAXggYAAAAAABALwQMAAAAAACgFwIGAAAAAADQCwEDgIzt27ePFi9ebO7NsAo1XdZHjx6lX375hRYuXEhJSUkVet73339v1GMvXLggXj8zM5MsQU3uA0srm4rgY2TJkiWqY+vgwYP0448/WmwZ4jxonrKsyLkGaj8brPQMcpSamkrHjh2jyMhIsre3p0aNGlH79u0pICBA43FnzpyhI0eO0HPPPUf169c3+JpXrlyhy5cvi9du2rQp9ezZk7y9vUnOxo8fT2vWrBHbbE5c4bh06RK9/fbbRj1e2i8S3of+/v5033336d1Pv/76K7Vr14769Okj/s/Ly6Pjx4/TzZs3qU6dOtS1a1dq1qxZtX2OmizrV155hTZu3EjPPPMMubi40EcffSTKxxj82G+//ZYKCwvLfSxXEidOnEgRERHiOyQHctkHxpaNscey+uNsbGzIycmJfHx8qE2bNtShQweys7Mz+Nqvvvoqubu7l3nMpk2b6Pbt2+JcNW7cuHI/F3+mP//8U+PYmjVrFv3888+Um5tLpmTK40sOx0VFz3OWqCJlqetcYw1lBLqhhwFkJSsri958801xQZ4+fTqdOnWKTpw4QV988QU1btyYHnzwQbp+/brq8Xv27KH33nuP7t69q/c14+Pj6dFHH6UuXbrQ77//TmfPnqXPP/+cGjZsSG+88UYNfTLL9u+//9L7779v9OOl/cL7786dO+ICM23aNFGp4AuQNt5/r732mqql/X//+5/YP1yJ4v2/bNkyat26Nb3++uuUn59fY5+jOnB58OeZO3euqhXY2GChNpDDPqgIY49l9cdxBT8kJITWr19PQ4YMEY+dOXNmmSBPeg7/rFu3rsx75+Tk0Isvviju5+9EeaKiomjRokVljq0BAwaIir2cyeG4kMM2yEm/fv1o0qRJGrehjKyXvbk3AED94nj//feLyuPevXupb9++Zbq/X375Zbp69aqoPBqLK6KHDh0SrXmdOnXSaLl76623sAOq0eTJk6lHjx7ib64sPfHEE/TBBx/QwIEDVbdL+8LV1ZUeeugh1f8ff/yxeL6tbXG7xrZt2+jxxx8nX19f+uabbyx2v926dUv85l4uqH3HsvrjmEKhoKVLl4oKOwcTGzZsED0Q6rgXYsWKFfTSSy9p3P7PP/9QdnY2tWjRgpRKZbnbGBoaKh6nfWw9+eST4gegIh577DHxA8AQMIBscLf56dOnaffu3WWCBda5c2dR8eceg4rYuXOnSB9QDxYYX/BbtmxpVM4n92pMmDBBFcxwesHDDz9MDRo00Pkcftzhw4cpPT2dmjdvTg888AA5ODio7j9//rzo2mVcefDw8BApN/xjDG655NbEZ599VpUWwelbnMKTkpIi3pNbh5ydnQ2+jjHbsWXLFvE4rvhwi6WEgzdPT08yFqdycCrO9u3b6b///isTMDzyyCMihYItX75cpHGoGzp0qKg4cYVLPWBIS0tTPV4KOHSpyOeIjY0Vxw3j19SXblHefta13/j4Zvw5Ll68KNLsRowYoREYc3DL29mxY0fq3bs3GYMrivv37xeVRq4wcnkaS/0Y5/QSbvnmAG7YsGGqfcLHF9/Oxz7vC04Tq2iZVMc+MKa8qlI2FT2WtXF5cRpIdHQ0ff3116InYeTIkRqPGTt2LH3yyScUFhYmykzCxzX3jiYnJ4vyMETXsaW9zeppJOr73JiyrkgZVvRcJIfvZnnboF1eUllzD9DmzZvF+4wZM0bn+ZV7Rvn7VJXtq8gxb2hbtbfB0PWMxzBwj/w777xjVBlB7YaUJJCN3377TVTg+cSlj5ubW4Xz2LliwxdrXS10nDNfnrVr14rWbu6K5SCDT/ILFiygoKAg+vvvvzUeW1RUJLpw+T5Of+KTOl+kuTLLufgSvkhwegP/cIszn4g5d59b0PlkrA+3bHLK1vPPP09eXl6qYIG3h8uOU13OnTsnUiU4BYtbNA0xZjs4QOPHcflJj+UfY3LotUkXRPXncoWfA8Hhw4erbtMOFhi/Pw+u5DJWl5CQIFI2OC/XEGM/x65du8Tnl/YzlytXlCqzn7XxxTsuLk71N79/TEyM+J9bkrkVuFevXrR161Zx0R88eLBIJ0lMTDT42TIyMkSFg49Pfh63aA8aNEi8pjGkY5wDt6efflp8dv6fjyFOE+NKLu8f3k+cKsjjibTTAI0pE1PuA2PLq6plU5Fj2RD+3jIeX6CNAzDuOVu5cqXqtvDwcPGZtXsdKnJsST/8utqpNtI+N6asK1KGlTkXyeG7Wd42qH9HOM2MK9o87orx5AXc4KWNgwU+N/HrVnX7KnLMG9pWiTHXM74ecI9ZRfcT1FI86BnA3KKiorg2rxw9enSFnjdz5kzxvNOnT+t9zFdffSUeM3jwYOU///yjjI6OrtB7vPHGG0pnZ2fl2LFjlfn5+eI2hUKhHDNmjLg9LCxM9dgvv/xSaWNjo9y+fbvqtuzsbGW/fv2UXbp0URYVFel9nytXriidnJyUixYt0nhvLy8v8XdaWprykUceUdapU0d54MAB1WOysrKU9vb24nOqi4yMVF68eLFCn1XfdkyaNEncVtX9wmXIt+/du1d1259//qm0s7NTJiQkGHzNVatWiee+++67Grfz83j71qxZU+52Gfoc0n5+7bXXlAUFBeI23t9du3YV+05dVfbzli1bxOfYv3+/xu1vvvmmKIejR4+qbrt69arS09NTOWzYMNVtU6dOFY/T3nb+XBcuXFDdduzYMWWjRo3Ee0VERBgsF+mz8+/CwkJxW2JiotLDw0P57LPPKl944QXV7cnJyeKYHD9+fKXKxFT7wNjyqmrZGHssG3Mu8vf3VzZt2rTMa/N283HN90nlxOXp6+srPn/fvn2VQUFByvLoO7Z0lXlFytrYMqzKuUgO301jtuHFF19UXQdiYmLE76FDhyrbt29f5jkLFiwQ5SM9rqrbV5FjXt+2VuR6putcU9FrAdQeCBhAFkJCQsSJVbsSwtauXStOvNLPzp07VfcZc5FmK1euFCdkBwcH8Xi+0PGJs7zKAuPH8XOCg4M1bufn8u3Tpk0T//OFzNvbWzl8+PAyr7Ft2zbx2BMnTmhcJHbs2KFcvHixcuHCheKzcYXiueee03hvrpzdvn1bXJBatmypDA0N1Xjt2NhY8dqffPKJsjKM2Y7KBgyTJ08Wr/fNN98oBw0apHMfjxo1SnnfffcZfL3r16+LcmjYsGG5gYUh5VUIpMqbutmzZ4vbU1NTK7WfjanU5ebmiov1iBEjyjz+/fffF4+/e/euzou49Nxx48aVee7TTz9tdMDAj7t27ZrG7fwZ+Xb+fmq/buvWrVX/V6RMTLEPjC0vU5SNsceyMeciLjMfH58yz+HPy5Vx/nvfvn2i0ti8eXNRVqy6AoaKlLUxZViVc5EcvpvGbMO5c+fK3GdswFCV7avIOcLQthp7PWMIGEAdxjCALEj5j7rm8+aUDe725ACX54TmdBzuDq8Izt3kH55h59q1a2IA7Zw5c0QaC+dklpfmxDmenIahjnNnOd2JZ0NhnNLDU9Xxe/B0g1IKFP+WUgX4ve+9916RC87jDzitiFOAeMpEHtzL3dXaYzR4MDg/h2c74RmDtHPH/fz8RJlwXj/n9nIXNQ/E5HEbPLWjIRXZjsrgfcepTZw/zSkNM2bMoO7du6vuLygooB07dohZsAzlQ3O+NJcjd7Fz6kZ14TSTVq1aadzGszUxHjPC5VSR/Wwszl3nKS91jWGRbuMpgQMDA8vcz9vDz+UxPtr4Nh44a+xn1x7Tw8cWH/vakwzwscjpIerbYKoyMWYfGFtenEpjirIx5lg2Bp/feJyQLjzGilN3ePAzjyfiz2jMNKo1cbwbW4ZVORfJ9bupjveLrnRJY1Vl+yp6jjC0rcZczwC0IWAAWeCTVd26dcsM1GPSgCvOk6zqIjKOjo7iwsw/fJLlAYU//PADzZ8/3+DzuBItzdajjisPUk49V36lSoGuXFTOW+UKGT+eBznyYDWusKu/LueVao+14G3mQeAc5HC+LueYa1u9erXIdea8Vh7gxvm0XKnjnFQecKhLRbejMrRnjNHGn4dzYjmXVhfOxeapdHnQJ1dQDb2WKfDARO39zPuYSdO5GrufK0IaLyK9l6731ze2RTr+dM3zr+v1KvrZebCq9uvw/1I5mLpMjNkHxpaXqcrGmGO5PDwAmMdScSVaHw4QPv30U1GOHDzwT3UypqwrWoaVORfJ+bup3bCla2Ayl4322CqpsUddVbavoucIfdtq7PUMQBsCBpAFbg3hxde48s4D5bp162ay1+YWal0zaUgtZjwrTHn4RM+tQ+oncx4Myq3w0m080wW3ovEUieozSOhqqeSKg/qUodLgXW4p075g8MWIB53ymgSjRo0SA+x4VgptXLHmH8Y9MtxjwAMduVdCF27RMnY7dF1cTIF7DLiliwfcaePt4M/D28itlcbOFmSIKT6Hsfu5IriHiy/WPGWwrgUHmb6KhPRcbpnUpuv1qkNFysQU+8DY8uIZqMxdNhIeeMxBOC+opg+3zvNUrTzL0XfffUdyUJnjq6LnIrl8Nyu7DdzTwTMKadMus6psX1XOEZW5nulTXdcCkD/seZANTkvhkyJfNPkio62yLR/9+/cXUx9q45kkGM84UR5u5edgRt3s2bPFyVOaSo9bwHiqxVWrVunsKeHbuCWMZzbix/ICUOp4MSieBUoXDhp41hHubeHAQb1HhCvW2uXF0x5y17ShlV0rsh38WF55WVfKWFXwdIS6ehe4NZZny+KZeDhlSdc0u+qzLPHFl3tJymOKz2Hsfq4ILm/uOeIUOWmdBmnf8gJcXOHSTsdQfy7PnPLHH3+I4ErCryNNp1jdKlImptgHxpaXHMqGce/YZ599JlrYtae2VMfpdvPmzRMtzXwelIOKlGFlz0Vy+W5Wdhs4hYgr3MeOHVPdxj0I2tedqmxfVc4Rlbme6VNd1wKQP/QwgGxwShJP8cbd2W3bthVzwHPqEJ/EuMWbK5c+Pj46K/h//fUXHTlypMztPN85t+ZwGgBfrDn3mPEUf1wR5QuhMUvc81z0nMfNr8OVV+4F4dZxPsmqr+/AF3s+gd9zzz2q9+YLCT+ec1f5gsIn66+++kq0JPLFgad25dQc/lyGWne4F4YDBS6DKVOmiEo1z+vOedq8XXyx4G3hHGme/pIDASko0heEGLsdPJUhr47NvUA8hR8/t6pzb/P83tz7oz6dqoRbYXmucV6fgKcd5B9988lL06pyIGVoHQZTfg5j9nNF8QWc507n8n/hhRfEccLHNVcyePpFQ7g1mj9Pz549xQWfUxN4Hnyeh52nQa0JxpaJqfaBseVV02UjnYs4hZJbbPmcxuOkON2IV2AuLxVKjisyG1uGlT0XyeW7Wdlt4OCOz818LuOFQnn6U/7MPJUuv56ptq8q54jKXM9MWUZg+RAwgKxwCgG3WvHAqwMHDohAgS+wXJnlFSe5ws8nSQlfwLg1ji9gunoluCWEAwOumPKc1TxwjE/m3Hr9v//9z+iF0hivCs2P5/QYzi3mFkPtQY+c780XRj4B89zXfGHg1jUOTNTzd7nCzyk2/BjuHubeFR4YyEGTtFAW4259DhDU8cmaW+24wi2lb3HXN5cb/5+VlSVaojiXmF/PEGO3g9OGeFE9HkfB+4R7ewzNvS3tFx4EqQ8HgNyVrysvnHuFeGwF096v2nm5N27cEL95vvHyGPocusqa8YWVP0u9evUqvJ914bQEfj3tNDl+fd42nvuc9y0f0zNnzqSnnnpKY9Erfn318QOMF1wKDg4WlQdeWIvfg48TrrRwYKlvoK1E32fnldd19XpxRUF7PxhbJqbaB8aWV1XLxphjWde5iFNPeBDp1KlTRXnp+lzSc/QtgifhiiVXxsuj79jStb8qUtbGliHfXtlzkRy+m5XZBsZlywEUf06+xvDr8KB4fi3ePvXvUFW2z9hj3tC2SvcZcz3Tda6p6LUAag8bnirJ3BsBIGe8Sit3A3PrD5gOX6Q4WFm8eHGVXoeDHm7FLW+ROgAAAKgc9DAAQI3jfGZuveZu9aricS88GBwAAACqB3oYAMqBHgYAAACwZuhhACiHoXxQAAAAgNoOPQwAAAAAAKAX1mEAAAAAAAC9EDAAAAAAAIBeVjmGgecN5hUree5oXgwLAAAAAMDSKZVKsW4Lr3PEC9+ailUGDBws8EIpAAAAAAC1TURERJlFHKvCKgMGaVVKLkwsZw4AcjR58mTxe/78+ebeFAAAsBDp6emiUby8VewryioDBikNiYMFBAwAIEeOjo7iN85RAABQUaZOucegZ6iSv/76S/wAAAAAQO1klT0MYDopKSkoTgAAgBqatCU/Px9lDeTg4EB2dnY1VhIIGAAAAABkjgOF27dvi6ABgHl7e5O/v3+NzPiJgAEAAABA5lNlxsTEiBZlHtBqyukywTKPh+zsbIqPjxf/N2jQoNrfEwEDAAAAgIwVFhaKCiLPre/q6mruzQEZcHFxEb85aKhfv361pyeZPWDIycmhv//+m65du0avv/46NW/evNznJCUl0dq1aykuLo46duxITz75JKJtAAAAqJUUCoXG7GkATAoeCwoKqj1gMGuf1sqVKykoKIg2btxIs2fPprt375b7HM7f4yCBg4ysrCyaMmUKPf7448jpM5NHHnlE/AAAAED1qolcdTni3hVevVjusmt4O2vyeDBrwNC+fXu6fPky/fjjj0Y/Z+rUqdS0aVPau3cvzZ07l/bt20e7d+8WAQTUvBYtWogfAAAAsD48CDsxMVHVC6KO02Xy8vKqPNPimDFj6OrVq6rXjIyMVP1IefymwtubkJBQqefytgwZMoRqI7MGDD169CAfH58K5fBt2bJFHDhS1wunMA0YMIA2bNhQjVsKAAAAAOqzNr3//vtUp04dkS3CM/ZwinhYWJjqMZyBsH///jKF9vvvv1O9evXE83iWn0WLFukt2IsXL4qK+D333KN6za5du1KvXr3Ez0svvWTSnXLu3Dl68803K/Xcpk2binEmO3bsoNrGoobZc8pSbm5umRZt/j80NNRgtMhLZav/gGnMnv8d/Wjgiw4AlZ8FIzo9joqUmEIRAOTnrbfeoiNHjtDJkycpLS1N9DJw5f3gwYMGn8d1sFdeeYXWrVtHycnJItOEx7EaSl9/5plnNG5btWqVqodh27ZtGkEMpwVpj5VV78ngeiSPhZXqh7zd0nbx87t160Y//fRTmV6U1NRUjdt0PZeNGDGCVqxYQbWNRQUMPGaBeXp6atzu5eWluk+XmTNnisdIPzwlGVTdzfhMiknLpeQsLCIDYGqxmQkUEn+NTkScQ+ECgKxwRXnZsmWip6B169biNicnJxo2bFi5Lf5cX+MskZ49e4r/69atSz/88IPexx86dEj1WPX3lwKGzMxMkQ712muviawVPz8/kRYkVfA3bdpEEydOVD13z549ImBh3PsxdOhQGjhwoPgcFy5coOPHj4tKv+TTTz8lX19f0Tjdpk0b0eOh77ns3nvvpQMHDlBtY/ZZkirC3d1d/OZIVh0fFNJ9unz88cc0efJk1f8cCSJoqLr8wuKWT0WR0gSvBgDqFEXF+cC5hfrzfwHAOuXkK+hWQma1vX5QPXdycdQ/6w73CHADbKtWrcT/XGHndSKYs7OzqGDrw2sGfPTRR6Il//777xfBwFNPPaU3RZ2DAu11Bt577z0RoLDPP/9czB51/vx5ioqKEjMHjRo1ir7++muaN29euZ+VA4ATJ05Q586dxf/qlX2ekTM4OJhOnz4t3o+Dj0mTJqnSrLSfK30+aeyGtI21gUUFDI0bNyY3Nze6fv06DRo0SHU7/9+2bVu9z+MdVpt2GgDUfqVhuHXOigIA+nGw8NgPR6qtiLZO7EcdArz03u/g4KBKwWE8SJjHE3D6D48v4FZ8Q6ZPny7GP3BF/L///qMOHTqIln2u52nj3ggew6qdkjR48GDV/9xj8OKLL4pxFIx7FD755BOjPiuPjVCv8Kvjz8HbNWDAANVtPObC0HM5eOLZi6p7mtOaJvuAgQcz89iFd999VxQ+D6jhLrDx48eLiPLKlSsih46jQACA2gbhAgDo6gHgSn11vr4hPL29lC503333iUo09wSsWbOGfv31V4PP5fEAvFI1Z4ZwDwP/cCs+T7H/zjvvlHl8y5YtRT1Q6s3QhXs11McucJoS3yYFN7xOgUR72lNpATRduLGZt2n69Ok679f13PDwcGrWrBnZ28u+il0hZv00Z8+eFYNepJ33yy+/0M6dO+mhhx4SP2z79u2iu4cDBjZr1izq378/9e7dm7p3706bN28Wg2E4kAAAqG19DNY67zoA6MfpQoZ6AKobp/1MmzaNnnvuOTFOlNOKeKKGU6dOlakoS+MNJNwLMWHCBJFWxLn/nNZz7NgxncEC4/rg0aNHVfVCXXjsBPcy8PgBHufKFXyeUZPxuAMeiM2DszlQ+fbbb41OSx89erR47Xbt2oneBP5s/Nl5Zih9Dh8+XCvXpzJrwMA9BNx9xD98wEmkqJA9/fTTIjiQBAQEiIOLAwVe6XnkyJEGDyKoXnvzW9DjbRqimAEAAKzIhx9+SE2aNKGlS5eKCjoPNubehj///FP1GL6Nxyuo43W0eCDxggULxNoK/BheV0s9xUgdD6Lm+zhA4QYUfrx6PZFxmjpvA6/VxWMHeEyEFIDwml/c6Myvw9vLgQVPncr4dXh6V+1eBem2vn370urVq0WQwZ+XU6N4oPOSJUt0Ppf99ddfNGfOHKptbJQcEloZHvTMg3V48LT2jEtgvCvR6TTk+8P07D2NaeZTxd2TAGAajz8/nK4m3KBfl/xKA5uVNpoAgPXhqUBv374tUl20K8vWgMcjPPjgg+JHzq5cuSKCn+XLl5vtuKiuOm7tSrCCGudhk0s2efJfrh0AAAAs0zfffEOWoF27djUWLNQ0i1qHAeSFU6sfdLxJDuEnzL0pALWWDYY9AwCAmSFgAACQISUGPQMAgEwgYAAAAAAAAL0QMEClWd9weYAahO8XAADIBAIGAAAZwxgGAAAwNwQMAAAAAACgFwIGqJKNeR0ov9XDKEWAaspIwkLPAADFPv/8c9q3b5/4Ozo6Wiyi1rx5c7H+gSEDBw6k8PBwnffx4sAJCQmqxYJjY2NR3DogYAATQLI1QPWxQeECgOwMGTKEmjZtSkFBQaJCvmXLFp339ezZk958802xqrP6/R06dBALj0mOHDkinjN79myd78cBwsaNG+n+++8X/3/33XfUsmVLsXJ0ixYtDG5rZGQkFRQU6LwvIiKCFAqF+PvJJ5+kGTNmVLAkrAMCBqg0bvlsaJtGthlxKEUAk0MgDgDyxRX4L7/8kv777z8aN24cjRw5ku7cuVPmvnnz5pG9vb0IHM6ePau638HBgdauXat6vUWLFpGPjw+lpKTofL+VK1fSU089RTYl3a5hYWFi5Wde5djR0dEkn4kDhnXr1mkEMlAMAQNUyT0OEWQfcwmlCFBNkJIEAHLl5+cnUoI4YOBW/uDg4DL33XffffT999/T888/T19//bXq/vHjx9OSJUvE34mJiXThwgV65JFH9L7X7t27qV+/fuLv9957j7Zt20avvvoqdevWTdx248YNkVLEPRejRo1SBS/aOH3p0UcfFQHM4sWLNe5zc3MTn+PECSxIq82+zC0AACAbmCUJALTlFeZTVHr15doHePqTk73xrfY3b96k27dvU2BgoN7HcBrS22+/rfq/ffv2ZGdnR5cuXaIdO3bQ2LFj9fYuSAFBkyZNxN+ffvopXb58mUaPHk0PP/ywSDfi13/hhRdEzwb3RgwbNkwEMLa2pW3j/LjHH3+c3njjDfH4n376iWJiYjTeh9OiQkNDRZoVlELAAAAgQ0hIAgB9OFj46L+Z1VZAsx7+mJrXaVzu47iS7+TkJAYNT5w4kbp37673sS4uLmXGEXAvw88//0wHDhyg/fv30/z58/U+v7CwUKQ2MV9fX3J1daX69euLIOX8+fNUVFRE06ZNE/fzOIjff/9dpC2pj2/g4MTZ2Zk+/PBD8f/ChQtp2bJlGu/DqVL6xjtYMwQMAACyhkHPAFC2B4Ar9dX5+saYM2cOPfDAA+Tv7y8q2oacOnVKDFJW98wzz9CUKVNowIABovJvCAcGPIMRpzlp4zEH7u7uqv+5V4HTi3Jycgw+jsc+cMCjjnscGjcuP1iyNggYAABk3MWAMQwAoI3ThYzpAahuPE7BUBoS45b/TZs2ieBi6dKlGvdxhZ3HLnDvQ3n69+9Pp0+fpj59+pS5j9ObeLajgwcPiuBj69atlJmZWSZA4fENnD7FYxR69epFq1evpvT0dI1t5TSmvn37GvHprQsCBqiSDKUTeTqW/0UHAAAA6yGlK8XFxYleAR74zIORtZXXs6D+ejwGYtKkSWXu8/T0FKlF3GOhVCpF6tKqVatE+pH243igMw+u5vt4ilYOeiScGsXrMtSpU6dSn7k2Q8AAVbI3vyWNbmK4dQEAKt/FgEHPACBH27dvF9Og6rsvPz9fDGr29vYmDw+PMvfXrVu3zPOmTp2q9/06d+4snsO9DDzD0S+//KLxusOHD6cnnnhCzLhUr149jedyz4MUGPD0rzw9a3Z2tgggeI0G6fE8pmH69OkVLAnrgIABqgwpEwAAANalYcOGlbrP0P36AhAJpxBJi6zp6pngNRq0gwUWEBCg8T/3QHCwwBo1aqS6nXsftB8LxRAwQJW0sYsnuySeTaATShIAAACqjfqA5eqAYEE/BAxQJW3sOWDQP28yAFRtWlVpVVMAAABzwUrPAAAAAACgFwIGAAAZw6BnAAAwNwQMAAAAAACgFwIGAAAAAADQCwEDVBqPxYwu8qQid+MWXQEAAACAinnrrbcoLS2NzAmzJEGVnCpoTM0bYOE2AAAAazJx4kSaNm2aznUPTO2jjz6iO3fuiIXgAgMD6bXXXqOgoCCTvX5KSgr9/PPPFBYWJhaFGzduHDk6Oup9fHBwMK1cuZJiY2PFqtCLFi0StxcVFdGvv/5Kx44doxYtWtB7771Hbm5u5d5Xnk2bNtHnn39OXl5eZC7oYQAAAACACtmyZQtlZWXVSKnt3LmTmjVrRkOHDqXU1FS69957KSkpySSvXVBQQH369KGMjAy65557xOJtb7zxht7HHzp0iO677z5ydXWlYcOG0aBBg1T3zZgxg7777juxfUeOHKEXX3zRqPssAXoYoErucbhLDjG8DgMWbgOoDliHAQDk5rfffqOEhATRy8Ct5PPnzxcV4ldeeYXWr19PjRs3pvHjx4uW+qVLl5KDg4N4Ht82d+5c8vDwoMLCQvE6Z86cEas2T5gwQWPVZW0DBgygwYMH03PPPUf79u2j48eP02OPPVblz8K9FhwESD0l3bt3F++jz9SpU2nmzJkiTUidUqmkH374gbZt2yZ6KcaOHUsNGjSg8PBwUR767mvSpEmZ90hPT6cFCxZQYmKi+LxygIABKk2pJGpom062mTkoRQAAgBry9ddfU0xMTLW8NldkOf3FkM6dO4sW9kceeURUtDkA4LSZs2fP0ksvvURdunQRj+PggVN9pIBh48aN9L///U88/tlnnxWBQv/+/enWrVs0cOBAkepT3mrO2dnZopdB3+NmzZolXkcXDmwaNmyocZutra1GWhV/hm7duul8fn5+Pp06dUqU/+uvvy5ShLg3glOMOIDi1KYePXqIx3L5dOjQga5cuUIuLi5679MVMDz++OOibLj3Yvr06SbrTakKBAwAADLGrVYAAHLCFV/uWeCKbdOmTVW3z5kzR6TrlIcDBE4z4hSj7du3q1rVubeBAwd9gcCyZcvEY9q1aycCDV169+6tsU3qOFAxhIOB2bNni23TJTk5WZyTuTfl+eefp6tXr4o0Jq74c0oTBwLqvcIc1PBgZf7Rd5+2a9eu0e3bt0UvCvd+PPXUUyJ4MDcEDAAAAAAWpLweAHNp3ry5wZRKHvjLoqOjxWDh4cOHq+7jv1u1aqX3tTkQ4JZ/Hizcq1cvvemanKqkr4eBgxl9QcPRo0dF78jmzZtFj4Eu9erVEz0SHDDwuAd27tw52rt3rwieOGjIzc0lZ2dncV98fDz5+/uTn5+f3vu08e08sJuDBcblZM7BzhIEDAAAMoYxDAAgR05OTpSXl2fwMVzZ5dmN2rRpQ6GhoSInn7Vt21a01nNaDv8YQxrDUJ7K9DBwaz6nGHGwwL0X+tjZ2VG/fv0oIiJC/M/jMDg1jCv0np6e1KlTJ5GGNWbMGPF5edYlDnIM3aeNgybuuYiLixOBBgckXFbmhoABKk1PcA8AAAC1HLfyjx49mlq3bi3GBujCg3sffvhh6tq1q2hhlyrsvr6+NG/ePNHiz6/DFWrGKUeculMVHFhUBG8XD57mwOWrr75S3b5mzRpVKlS3bt3EeA3GYzCeeOIJWrVqFd28eVOMQXj00UdV93Gq0urVq0VF/5NPPlF9NkP3qeNehzfffFOMA+EB2Dx+wdvbm8wNAQNUybXC+tS9jg9KEcDEMHYBAOSMZzg6ePCg6DXgQOCnn36iunXrajyGK+BDhgwRA5W55X/37t2qSjK36PO0pFx55vELTBocrY3HFfBA6+rqKeFARR/e7oZqA6W5h4HHLJw4cUL0APA0qVJPMAcely5dEgOnOa2pY8eOqucZuk8bBxfPPPOMKFt+f055MnfQYKO0wqsSH5jcfcSDTXRFd2Cca7HpNHjhYRrdM5BmPY1pVQFMafDox+hm8m1as/xP6hFQPRdKALAMnPvOA2F5LQIpBx4gV8dxUV11XCzcBgAgY1bXogMAALKDgAGq5EHHG+QYfhylCGBiGOwMAABygTEMUCUeNnlkk188TRoAmI4VZosCAIBMoYcBAEDGMBkZAACYGwIGqDQbVGUAAAAAaj0EDFBpSgzHBAAAAKj1bOWQp3v69GnaunWrWA3Q2Gmkjh07Rtu2bRNz2gIAAAAAyNGKFSvEWhSWzKyDnnmuWF7Q49atW2LZ8FOnTtF7770nFqzQ5/DhwzRixAixOAgv/c3BRsuWLUXwYO5FLazRqYJAGtisnrk3AwAAAGrQ33//TQkJCWRnZ0eBgYE0aNAgjYXXUlJSxMJuw4cPV9XfwsLCxOrFvKqyKW3fvl28NuNVl4OCggw+Pjg4mM6fPy8ex6tNq+OG6JMnT4rF1QYOHGj0fYZ89tlnNHjw4CqvYm21PQxcgHFxcXT16lXav3+/2OEzZsygffv26X0OBxT9+/eny5cviyDh2rVrdP36dfrxxx9rdNuhWHSRFxV5+KE4AAAArMjMmTPFys1ciZ42bRr16tWL8vPzVff/+++/oiFYoVDQgw8+SJ9++qmo33EFfd68eSbdlqioKFEf5G3iQMCQyZMn0xtvvEFHjx6lV155hUaPHq26b+3atTRgwABRJx03bpyopxpznzWwN2cq0urVq+nDDz9U9QzwjujZs6e4/YEHHtD5vJycHI3IsU6dOuTr6yvSlAAAAACgZrz55pui5ZwDBc76OHToED300EPivk2bNokgget7n3/+uapFfs+ePfTiiy/SlClTTLYdr732mvgdEhJS7mNHjhxJ8+fPF3+Hh4eLOmVRURHZ2trSF198QcuWLRO9IhEREdS+fXsRYNSpU8fgfbrs3buXEhMTRbBUG5gtYIiMjBTdVZ06ddK4nf/nriJ9eCdzZOjh4UFNmjQR0S3//c477+h9Tl5envhRT4UC0xjuFEJON67znkORAgAAWCFORXJ2dlb1MHC+PmeCcCMwL0Kpnr7Dj/H399f7Wlu2bBEVeV3GjBlT5fRz7gnZuXOnyG7hHo8PPvhABAupqakiY2Xo0KHicZxm1apVK1En7datm977dDVwv/XWW6J+2rdvX1FvzcjIIEtntoAhLS1N/Pbx8dG4nccm8E7Th/PGWrduLXohmjVrRhcvXqRnn33W4AHEXVRffvmlCbceAKCmYCUGACjrp59+0lksnGLDrd7Jycm0Zs0avT0D7ObNm6Jiq+s+Y3DlPjQ0VIxP4EwPriAzfs2HH364zIr18fHxomfhhx9+0Pua3HrP6UW6qDf+VjWFiQMaHvfAAQTj8Rienp4a4zC4TsrbnGDgPl0N4lzu/NpeXl4i0OBxupbObAGDk5OT+K09ajwzM1NEqbpwlxEPkuYDkqNDPhA5uOjatauIDmfPnq3zeR9//LHoNlLvYeDoEKoG6zAA1ASs+AwA8sSVe3t7e7rnnntEEMAVZLZx40aNsQEsJiZGDEj++uuvVWlLunD9jOt7huqOVcVjF/iHM134/Z577jnRgM11UCk9Saov8u0+Bu7TxhP5tG3bVlUW3MitL23JkpgtYOAdxAfZ3bt3NW7n/5s3b643IuRI9vvvv1dFrdyzwCPzOVdMHz7ATHWQAQAAAJhbeT0BXEkt7zGctcE/VR3DoI4HOfNYhl9++UUjsOC6GgcLTz/9tMHXrM4ehsLCQjGuQEqJcnFxEbM88e08HtbPz08MhubJdTgg4DERPKOTr4H7tAUEBIiggVOvHB0dKTY21mDmjKUwW8DAvQj3338/rV+/nl566SVxW1JSkqj4q4+eP3v2rOhW464t3lkcZHD3Dh94Ev6fdxAAAAAAmM+RI0fE2AWuLEuT1fDMSJyWw70M0qyWb7/9ts7nVyQlSnL8+HFRX+SGZc5A4Ur6yy+/LKYx5bQpHpDdsWNHEcw89thjov7JKUU8k1Pv3r1VQRNno7zwwgv06quvipk4eYCzVL+cbOA+dfxaPHUsZ8RwTwrPAKovc8aSmHUdhlmzZolIjQMG3mFLly4Vg0h4J0sWL15MJ06cEJEcH3w8OIVH3XMQwT0RnCfHER9PcwUAUPtgDAMAyA+nHPHkM9o4HUlae4FxGo80WFhfz0FV8RgDfm2pMZn/5uBA6rGQ0oM424RnaVq5cqUIKjgI4B4PKWuFx1fwZ+IAhGdy4rQlyRQD92n7559/RJ2WezO4HstjGtzc3MiS2Sh5visz4p3K3Va8HgNHfzyynGc9kvz8888iDUmaAovt2LGDdu3aJXokeOfxfLgV6VLjriQ+eHjgNQ9igUruu9h0GvHdfzS0QwOa9XwfFCOACQ0e/RjdTL5Na5b/RT0CMAsZgDXjAcW3b98Wk73IvbV6zpw5YjZLqZIONXtcVFcd16w9DIy7qNSDAW3jx48vcxsPmuEfML8MpTORs7u5NwMAAABkgNfXgtrHrCs9g+XzsMklys0092YAAAAAQDVBwABVmlb1Qceb5BRxAqUIAAAAUEshYAAAAACwAGYedgpWfDwgYAAAAACQMV4rgPHc/gASafFj9RWoq4vZBz0DAIB+0nR/AGC9eA0qXlOApw/lyqG02jBYb89CdnY2xcfHiwWMpYCyOiFgAAAAAJB5w0GDBg3EFJrh4eHm3hyQCQ4WpFWrqxsCBgAAGUPOMgAwXry2ZcuWSEsCgXuaaqJnQYKAAapkY14HGtUxEKUIAABQzTgVSe4Lt0HthCQ4qDIlYdYGgOqCMQwAAGCRAcOPP/5o+i0Bi8NjMRvappFdZpy5NwUAAAAA5BQwTJ48mRQKhem3BiwKT/97j0MEOcaGmHtTAGoh9NwBAIAFBwwdOnSg06dPm35rAAAAAABAVio16Hns2LE0evRo+uyzz6hdu3Zi5L66Hj16mGr7AAAAAADA0gKGd999V/x+7bXXdN6PaQABAKoKC7YBAIAFBwwpKSmm3xIAAFCDMQwAAGDBAQOvLAfAMpRO5OHogsIAAAAAqKUqvQ5DfHw8LVmyhKZOnaq67ejRo1RYWGiqbQMLsDe/JeU17mXuzQCotZCYBAAAFhkwnDt3jtq2bUuLFi2iOXPmqG7/448/aMWKFabcPpD5OgwAAAAAULtVKmCYMmUKffTRR3Tx4kWN29944w1auHChqbYNZK5AUUD3NzxGNklYhwGgumAkAwAAWOQYhrNnz9LmzZvF3zZqzcwtWrSg0NBQ020dyFpiTgL5Z9mQbVaYuTcFAAAAAOTUw+Dg4EDp6ellbr969Sr5+vqaYrsAAABjGAAAwFIDhqFDh9IXX3xBCoVC1cMQFhZG48ePp2HDhpl6GwEAAAAAwJIChnnz5tGZM2fIz8+PioqKxADoVq1aiQBi5syZpt9KkCUlkqsBqu/7hbIFAABLHsNQr149ETBs2bJF/OagoVu3bjR8+HCRrgQAAAAAAFYcMPD6CwMHDqQnn3xS/IB14my0LLd8crBxN/emAAAAAICcUpIWLFhAbdq0oYYNG9Kzzz4rAojr16+bfutA9mL9MijFz9XcmwEAAAAAcgoYrl27RtHR0WIsg6enJ82fP18jgAAAAAAAACsOGFiDBg1EcMDBwg8//EBjx46l+Ph4+vvvv027hSBr/nEe5BOXbe7NAKjFsKQ6AABY4BiGPXv20IEDB2j//v1i0DMv2MZjGv766y/xG6yHW5Yj2VKBuTcDAAAAAOQUMDz88MNigbYpU6bQxo0bxaxJAAAAAABQ+1QqJYnXWuBpVGfMmEHdu3cX6UjLly+nO3fumH4LAQAAAADAsgKGjz76iHbt2kUpKSlizAIPeF6zZo1ITWrWrJnptxIAAAAAACxr0DO7ffs2hYSE0KVLl+jixYtipWdb2yq9JFgQDMUEAAAAqP0qVbsfM2YMNWrUiFq1akWzZs0iFxcXmjNnDkVERNCtW7dMv5UgWyk+OZTh42TuzQAAAAAAOQ16dnZ2FuMY7r//fhE4gHVSElGyTza5k7O5NwUAAAAA5BQw/Prrr6bfErBcyE0CqL6vF75fAABgiQGD5MiRI3T16lVSKpXUrl076tevn+m2DGTPhmwoMNKb7CnT3JsCUGspuSsPAADA0gKG2NhYevrpp+nYsWNUt25dsrGxocTEROrTpw/9888/5O/vb/otBVlyzLcjW1KYezMAAAAAQE6Dnt955x2yt7enGzduiEAhISFB/M238X1gHZRiFAMAAAAA1GaV6mHYuXOnmEa1adOmqtt4DYYVK1ZQly5dTLl9AABWDWMYAADAInsYeL0FJ6eyU2nybYWFhabYLgAAK4cePAAAsOCAYeDAgTRx4kSx0rMkOTmZ3n77bTHVakXl5uaKcRFFRUUVel5qaiplZWVV+P3ANDB5CwAAAEDtV6mA4fvvvxerOzds2JA6deokfgICAujy5cv03XffGf06HCBMmjSJvL29qXXr1uL11q9fb9TsTN26dRNrQDRv3pzGjRtHGRkZlfkoUEWx9TMopb4ryhEAAACglqpUwBAUFEQhISG0atUqMVvSM888I/7mgIHvM9bcuXPpjz/+oDNnzojegmnTptGzzz4rXkefCxcu0MMPP0zDhw8XPRzcM8H/86BrqHlZ7vmU6+6AogcwOfThAQCAPNgoeREFM2nSpIkIEGbNmqW6rWXLljR06FBauHChzuc8/vjjIv3p6NGjlX7f9PR08vLyorS0NPL09Kz061i7Q7eu049nFpI7taVlozA7FoApDRo9hG4lh9O6lX9T1wYdULgAAGC2Om6lF267efMm/fDDD2LhNsYLt/G4BmN7GOLj4+nu3bti7QZ1ffv2pdOnT+t8TkFBAe3Zs4dmzJgh0pl4OldfX1+ys7Or7MeAKrGhoLC6ZEtpKEcAAACAWqpSKUmbNm2itm3b0smTJ8XYA/45ceKEuG3Lli1GvQZX9hkv/KaOAwDpPm285gMPkOb7eexCx44dyc3NjV5++WWDg5/z8vJExKX+AwAAAAAA1RQwvP/++/TNN9+IIIF7GfiH/+aW/ylTphj1Gra2xW+tPQ0r9yLo6zHgFaXZsmXLaNeuXaKXgsc78N+ffPKJ3veaOXOm6J6RfgIDAyvwaQEAAAAArFelAobo6Gh6/fXXy9zOt/F9xuAZjhgPWlbH//OMS7rUq1dPrPXA4x64V4NxCtQLL7wgFpPT5+OPPxa5XNJPRESEUdsIhmGlZwAAAIDar1IBQ/v27en8+fNlbj937py4zxgeHh5ialTuHVDvXdi7dy8NGDBAdVtSUpIqCOGeh/vuu09U+tXxDEv8evpwkMEDP9R/AAAAAACgmgY9cwv/iBEj6IMPPqCePXsST7TEU6PyNKmffvqp+FvSo0cPva/D06jylKzdu3en3r1707x580RQMGHCBNVjpk6dKtKdeBpX9sUXX9CgQYPEYGkeIM3jKFauXCnSogAAahsbTK8KAACWGDBMnjxZVZnX9t5772n8b2jW1ieeeILWrFkjFnvjxeB4EPOhQ4fEwGcJ/62eosRBAg+s5qlYOcBo3LixCBhGjhxZmY8CVcAjSiIapZIrGb/2BgAAAABYQcDAC6aZCi/8xj/6qK/RILn//vvFD5hfvqOCHAnT2gKYmtkWyAEAADBFwODt7V2Zp0EtTJVwzLcje1KYe1MAAAAAoJpUeuE2ABYY6U22lInCADCx4kmkAQAALHSWJAAAqF5ISQIAALlAwAAAAAAAAHohYIBKK0IbKAAAAECtZ/QYBkMrKWsbPHhwZbcHAAA0YDQDAABYSMAwfPhwjf/z8vJUf9vY2KjWW+BVlXNzc025jQAAVgyjGQAAwEJSkjgIkH54kbWuXbvS4cOHxf/Z2dnib74NKy5bV7vnreZJFNPcy9ybAgAAAAByGsMwf/58sUJzv379RI+Cs7Oz+Puvv/4S9wEAAAAAgBWvw3Dnzh2di7fxbXwfWM/CbW6ZjuRMBebeFIBaDGMYAADAAnsYunXrRpMnT6aMjAzVbenp6TRlyhRxH1gP/3gP8onPNvdmAAAAAICcehh++eUXevzxx6lBgwbUunVrMeA5NDSU/Pz8aMuWLabfSgAAAAAAsJyAoUOHDiJA2LhxI125ckXc1q5dOzGTkoODg6m3EQAAAAAALClgYBwYjBgxwrRbAwAAAAAAtWOl5/j4eFqyZAlNnTpVddvRo0epsLDQVNsGMqfE/PAAAAAAtV6lAoZz585R27ZtadGiRTRnzhzV7X/88QetWLHClNsHMpfvqKBCRztzbwYAAAAAyClg4NmQPvroI7p48aLG7W+88QYtXLjQVNsGFiCiUSolNHI392YAAAAAgJzGMJw9e5Y2b94s/raxKZ0jvEWLFmIwNFjPOgwAUE2UKFkAALDgHgYe8MzrLmi7evUq+fr6mmK7wELUSXEl95Rcc28GQC2GyAEAACwwYBg6dCh98cUXpFAoVD0MYWFhNH78eBo2bJiptxFkzCfFhTxS8sy9GQC1DzrwAADAkgOGefPm0ZkzZ8RCbUVFRWIAdKtWrUQAMXPmTNNvJQAAAAAAWM4Yhnr16omAgVd15t8cNHTr1g0LtwEAmAoykQAAwJIDhh9//JH69u1LTz75pPjRvu/tt9821fYBAAAAAIClpSRNnDiR+vTpQ6tXr9Z5HwAAAAAAWPlKzwsWLKCXX36ZPvjgA5GSBNa50nOWWz7lujmYe1MAai2sqA4AABYbMPCMSHv27KGVK1eKWZNSU1NNu2VgEWL9MijZz9XcmwEAAAAAcgsY2H333UenT5+m2NhYuvfee+n69eum2zKQPfVF+wAAAACgdqpSwMCaNGlCR48epS5duoigAayIksg/zoN84rLNvSUAAAAAIKdZkiZNmqTxv6urK/399980d+5c2rt3r6m2DSyAW5Yj2VKBuTcDAAAAAOTUw7Bw4UKdt/MA6J07d1Z1mwAArB6WYQAAAIvrYThw4ID4PXDgQNXf+vBjAACg6pSIHAAAwFIChvvvv1/8ViqVqr/14ccAAEDlYUoBAACwuIChoKBA598AAGB6aHYBAACLCxjs7e11/g3WLcUnhxzJ09ybAVCLIXQAAAALG8NgDIxhsB7JPtnkTk7m3gyAWgcpSQAAYLFjGIyBMQzWBlUbAAAAgNqqUmMYACSBkd5kT5koEIBqgoQkAACwyDEMABLHfDuyJQUKBAAAAKCWqtTCbQAAAAAAYB0qFTDk5OTQp59+Sq1atSJnZ2fR+6D+AwAAphkahDFhAABgkQHDZ599Rtu2baOvvvqK8vLyaP369fThhx+Sk5OTCCQAAKCKMHgBAAAsOWBYt24drVq1ikaPHi3+f+KJJ+ibb76hFStW0J49e0y9jQAAVgyRAwAAWGDAEBkZSe3atRN/u7m5UVpamvh7yJAhdO7cuQq91u+//07du3enRo0a0aOPPkoXL140+rmzZs0iX19f0eMB5qnGxNbPoBQ/FxQ/gKlhtmIAALDkgIFzau3s7MTfLVu2pF27dom/T506RV5eXka/ztq1a+nVV1+liRMn0t69e0XQwOs9xMXFlfvcY8eO0dKlS8X7ZWZiWk9zyXLPp1x3B7O9PwAAAADIMGCoW7eu6u/JkyfT2LFjqUuXLqKHYfz48Ua/zowZM+ill16icePGUevWrennn38Wg6Z/+ukng89LSUmhMWPG0LJly8jDw4OqS5GyiL49uoQi0qKr7T1qBWRMAODrBQAAtValpjRKTExU/f3CCy+IXoYTJ05QmzZtaPDgwUa9BqcxcfqRejoR91o88MADdPjwYYPP5V4JHj8xYMAAqk7ZBTl0KjKYChSF9PF9b1Xre1lqxkRQWF2ypXRzbwoAAAAAVBOTzIHaq1cv8VMR0dHFrfZ+fn4at/P/wcHBep/HvQ/h4eG0Zs0ao9+LZ3LiH0l6Oiq4AAAAAADVHjBwLwGnB2lr2rRpuc+V5haXxkKoNsjenoqKinQ+JyQkhD7//HMxfsHBwfi8+ZkzZ9KXX35p9OMBAOQC6zAAAIBFBgw8ExKPW+AKfGUvcPXq1RO/ExISNG7n/6X7tB04cIAyMjKob9++qttSU1Pp+vXrtHr1ajFYWjsAYR9//LEYa6HewxAYGFjuNgIAAAAAWLtKBQwvv/wy9ejRg5YvX07e3t6VemMOCpo1a0ZHjhyh4cOHq24/dOgQPfXUUwbHLqjjWZU4gPjf//6nM1hgvKAc/4BpYawzAAAAQO1XqYDh2rVrYmByVWcoeuedd2j69Ok0YsQIsRbD/PnzxdiGN954Q/WY9957j86cOSPez9nZWfyo4yCBb+P1GAAAAAAAQAYBA0+BeufOHerYsWOV3nzSpEkUHx9PDz30kBiUHBAQQBs2bKBWrVqpHsMpSLrGSYA8RDRKJVeb5ubeDAAAAACQU8AwZ84csXYCD0AOCgoiGxvNJUk7dOhg1Ovw87755huRTpSVlaWzx2LhwoVUWFio9zV4XENFBkBXCHJuypXvqCBHG92pYABgitMQTkQAAGCBAUNOTo5IS3ryySdNMquHra2t3vQmd3d3g8+t7BiKitAMh0CdY74d2ZMChQIAAABQS1UqYOAZh7iHYeLEiTVSYQd54kAqMNKbbCnL3JsCAAAAAHIKGHj60tmzZ5fb+l9bICEAAMx2/qlgjy0AAICp2VbmSW3btqUbN26YfGMAAAAAAKAW9DDw2IVRo0aJ1ZNbtGhRZtAzr9FQK2DwgkFo9wTA6QcAaqfv9tygwR38qbV/1abQBysOGD777DPx+7nnntN5P7rQAQAAACzXgj2htPZMBB396AFzbwpYasBgNesioAkdAAAArIzU8IsGYKhSwPDqq6/S+vXrK/NUqGVuNU8id5s25t4MgFoL6zAAQE1TFJUEDCh6qMqg5x07doi1GKwFhjIAAACAtShQFIcKRZilDaoSMDzwwAO0adOmyjwVahm3TEdyziww92YAAACAieQrisRvxAtQpZSkoKAgevHFF2nr1q3Url07cnR01Lj//fffr8zLggXyj/cgW7Ke3iaAmoYLNgDUtIKSgKEkMwmgcgHDgQMHRKAQEhIifrQhYAAAAACw7IABoxigSgFDcHBwZZ4GAABGw+gpgOpyNvoSzT78E/3+1AJydnBGQWspKJRmSULRQBXGMFjb7CT4vgCAOc5Amr8BwFSOhJ8Sv9PzMlGoBsYwYNAzVKmHgSUkJNCSJUvo6tWrYp5eTlEaP348+fr6VvYlAQAAAGqODXrydCksKg4YbFE+UJUehpMnT1KLFi3o119/pby8PCooKBB/8218H1iPfEcFFTqiowrA9IorMliHAcD00G9nXEqSrS0CKqhCD8OUKVPopZdeonnz5pGdnZ24TaFQiNv558iRI1Sb4OuiX0SjVHK38a/BvQEAAGAauL7rVlDSw4DygSoFDGfOnBHrMEjBAuO/P//8cwoICKDawgZfFaNLCgAAwGJgNK9BRSXzqSIjCSSVyiVxd3enqKioMrdHRkaSh4dHZV4SLPR8WyfFldyTc829KQC1Fuo1ANUHDYO6Yf0FMEnAMGLECBo9ejTt3LmTkpOTxc+OHTto1KhR9Mwzz1TmJcEC2djYkE+KC3mk5Jl7UwAAAIyGMQyGKRAxgClSkr799luaOHEiDR06lIqkkfS2tjR27FgxrgGsBU65AABgwZBRqxOmUwWT9DC4ubnRsmXLKDo6Wqz6fPDgQfE33+bq6kq1BWYngarIys+m97Z/SYlZyShIqNKZCABMC9d3wxAwgMnWYWB+fn7iBwDKuppwk6IyYulw+Cl6st1gFBEAgMxgDINuSEkCkwUMPEvS0aNHxfgFbbwmA9R+ONECAIBFQsed4eJB+YApAoaPP/6YFixYQAMGDCAfH5/KvATUEllu+eRg427uzZA1dH1DlY4fXLgBqg0avnRDDwOYJGDgsQq7du0SAQNYL67HxPplkLtN7Vl7w9SzSAEAgPygIccwBVoqwBSDnnlV5x49elTmqQAAUAGo2ACYHr5X5ZRPScCAuAGqFDBwzwL3MAD4x3mQT1wOCgIAACwOAgfdFMUz5gNULSWpcePG9Pzzz9OLL75ILVq0KJN68f7771fmZcECuWU5ki0VmHszAAAAjFcyNggBg+GUJGTWQpUChv3791Pr1q3p5MmT4kcbAgYAAAAAy4SUJDBJwBAcHFyZp0EtgyG9KB8AAEuk6lnALGQ65RTkkKtLGhHVr9H9ArVsDAMAVLylBqAiEJADVD+kJOl2KHotdWhzGClJoIKAwRhI4tNTLkaVHgBUAQJOANOTmnHQnKNbWn58yfkHRx9UcaVnAD6RpPjkkCN5ojAAAABqWYsg4gWQIGAwBkJsvZJ9ssndxsmoYrQ+6IKBqkPKBEA1XtdxfS+nmBAyQDGkJAFUm5KFb1DCAACyhIBcN5uSBi9FEa5gUAw9DAbga1K+wEhvsqdMIx4JAAAgr0AB13l9igMGxAsgQcAAVeKYb0e2hCUhdUNKEgAAWHDAgIgBSiAlCSoNuY0A1QkBJ0B1UfUsIEff4NlHoUSDIBRDwABQTTAbL1QNkiUAqhu+ZeWlJCFggGIIGIyBmp+ecjGq9KxWacMVLklQleMIxw+AyZV8rzDouZxpVXH+gRIIGAxAfbgcOJEAVCPMg25JzseE0Mi/J1Babrq5NwWgXIWKIrqVUP6EJehhANkMej5z5gwtXryY4uLiqGPHjvT+++9T3bp19T4+IyODli1bRseOHSN7e3vq168fvfLKK+To6Fij2w3FYutnkIuND4pDB3RMgWmgh8ESnI++LH4nZqeQlzMWs5Q7ax/D8O3uUPr54C26+tVgcnG005+ShPMPyKGHgSv9ffv2JQ8PD3rhhRdU/2dlZel8fFFRkQgq7ty5Q08//TQ9/PDDNG/ePBoyZAgpFAqTb591nkYqJss9n3LdHcy9GQC1FlICLAS6pC2MdU+reiWmuCcst6C8upMS5yAwfw/DJ598QkOHDqWFCxeK/7ni37BhQ/r1119p0qRJZR5vY2ND58+fJx+f0hZtDiB69Ogheiruvffe6tlQK22BMBauk/rKBSUDYG0Q4FkWax3DYFdyecouUJDuHIHiB9iQUqzFID0erJfZehhycnLo8OHDNHz4cNVt3NPw4IMP0u7du3U+hwMG9WCBSelL+noloHoFhdUl/1tpKGZDCwMh4IRKse4WUEuDBgKwJHa2xdW/7LxCPY8oiRBslFjtGcwbMERERIgUo0aNGmnczv9zypGx5s6dS76+vgZ7F/Ly8ig9PV3jx9x6z9xLP+67Ye7NAACZKg0UEDJYAhsrb7G2NKqGHCvdXXYltb/sfMMpScU9DFZaSCCPgCE/P1/8dnFx0bjd1dVVdV95fvvtN1qyZAmtWLGC3Nzc9D5u5syZ5OXlpfoJDAwkc4tJyxWDjiwZFoA0DC2OUDVSDxXK0SJglgOLorTyAM/O1saogIF7GBAwgFkDBim1KDk5WeP2pKSkMmlHuqxevZomTJhAv//+uxgHYcjHH39MaWlpqh/u3agQXAgAoIZZe4XGUiEF0bJY6/6SGrRyC/UEDEppDAMhJQnMGzAEBARQvXr16Ny5cxq38/9dunQx+Nw///xTTKXK06s+99xz5b6Xk5MTeXp6avwAVD+MEoMqwMJ/FgU9imBJFCUpAkV6UwVKxzAgmwDMPq3q2LFjRVpRfHy8+H/79u0UHBwsbpfMnz+fXnvtNdX/a9asoZdeekkEC2PGjKneDbTSlgcwLRxFUJXjBqchy4DmAUtj3WfmwpIoQPptcAwDIgYw97SqX375JV2+fJlatmxJQUFBdPXqVZozZ45Yi0Fy5coVOnHihPib04l4vQYeh7B8+XLxI5kyZQo9+uijZvkc1iyiUSq52QSZezMAah0pbzhPX8oAyBJSyCxD6Zhnaw0clBo9DfpCYAeHPFKg1QLMHTDwAGfuVQgNDRUrPbdt21bMeKSOAwEOFKTH79ixQ+drtWvXrka2GTTlOyrIyUbXKpEAUBWp2cWTP4REpdGwtihL2cNYN4tk7XVhfT0MSmWR+N2s8QUqUo6o4a0COTJrwCBp1aqV+NGFgwiJg4MDPfTQQzW3YbgAlMsx347sbdACCmBq0mUcpyHLYu0VULAs+tKNCilX/LbhMQzFsQNYObOOYbBWuy/HUm0RGOlNvhGZ5t4MmUMNAipz2BQfNwgYLAPGMFiW0lQkpVUHtvp6GFxtmojfSckBmFYVBAQMZrDlYgzVrunoatelslBRSCP/nkDnoi+Ze1MAatm3yxpYZwXU8lj3SurS51bo6z6QplXFSs9QAgEDgJasgmzxe8+tI1UqG7QMgylaQHEcWQabkh1lvYNoLZO1rsMgDXbW18NQpDr/FKGHAQQEDADVzEqvR1BFtbQDrxbDjgLLCxj0zpJUcgKyteWAoSa3DOQKAYMZanq4rMibaq/Xwqbd7IIcc28CVBQu1hZBOluggcAylO4n6/yCFZakIhUq9MySpNbDoH/qVbAmCBjMoBbWQ2uXWnrFv5UcTuM2TKZrCbdIDgoUBfTz6dWUmZ9l7k0BqDKkJFkWqUJcO8/2Ve9hkNaB4YDBWtO2QBMCBpmJz0yk93Z8WamW4LDkcDFYNy4zgWrKreZJFBvkRbVJbc0EiUiLFr/vpkWSHITEX6d9YUdp540D5t4UmbLuWVwslVwqV4VFCjoZed7cmyF7ctlfcl3pmVOSsHAbiGMBxVDzDFVE990+RlHpsaI1uDIVMHY7JYJqA77gLTz2KyVmJZMlsinZ0xgEqZs0O4etDU5DhuD4sSxy2V+br+2meUd/obupUebeFJAhKRVJ3yxJUiCFlCSQ4EoNVbowumU6Ukp0erWUYnR6LB2LOEvrr2ynmqTK3ax1fQwSeXyuopKVRBEwQG0ilxbrtNwM8TtfUWDuTZEluewnufYwSNdBW5GSVKObBjIli5Werc2Rm4kG7i3Jq6zEN9QcX2r/eA+qp6jmlZ5r+oPV1pwkmSkNGFDQukk51rhaWwKpgUHK/TY3HDcoJ0OkngV9YxjQwwDa0MNgBFNXZxIz8038ilAdjO1hSM1JE93/cie3FrXSnhychnSXTzGEU5ZBinuVpGchLDMdQAjILeu8KLceBqzDABJcqY1Qs6cTaXXFilcTarqhduJftXNAXUVb5n4+8wetvvAvZedbxpSlcku1QgeDYVZan7FYcqmAFqkCF3l93+VCHntJvrMkKTXWYbD20gKGgEF2qp6SVJlgAypfsS5UFJbzCNOdbNNzMygmI55qA1yDyi0hrd8gb/JKSUIPg5EFRNY+6NlwORQPeq6hjQJZwxiGWkguLVyWSs65v5N2TKes/GxaO2pxhZ8r30+FANcy9xvI+fxRhKQ2i9pf5lq4Te86DEhJAi3oYZAdy0lJYvmOCsq2tamdAZcMPxYHC5Un5aSSTFjnhbriUE4WNY2yXBpsVNNimntD5E0uu6umSYGCFDiUIaUk2RRREVZ6BvQwyJFlpSRFNEql+ERPqk2yKjsWwWIuzPLaUHltDYBpZv+Sz6B5fMN0lo+1RgolCssbw1BybrYRYxhqeONAlqy6h+FaTPWsH2CNJ8LYtNxqe+2a/DQXY6/Sh7tn1OA7Wq/SWThQodFdPiW/rbxiY3mzJMljf8llO+SqtHSss5wUJWMYpLEMhtZhwErPII4Fay6GZ34+TuFJWWRJKUnHbyXR6hO6V4E2R72rToorNcwpotQc008Va+qK5O6bh8RicIbcTL5T+v5VbJmTth/1PajaOgzyaLEGYwc9y2N/qWa5wUrqhsvJSgOG8noYSlPalEhJqkaJ2cn058WNFtEwZNUBA0vNLjBinviap+/geXbpCfpsY4ie51ANt9gqySfFhQJyq3nhNhP59exfNH3/AoOPkc0MJ9VAbickmW2ObMltv4FuNjLbX6qKMDrwDJeTPHZXjXNwTKUWTc9SgZ4xDKr6j62iVl8Xze23s2to49VdlJEvt8brsqx+liR8DUzDUvJkC4oMT4GqrIbWQbm1YMlnT8mrXOSqdLYbkDOpoUYulStV4CKPzZEfmewncwloeIk83JOpsDC/nJQkZblTr0LlST2ARUXyb3i1+h4GU53c0/MyqziDDVhqEGItn8PUSiejQvnoKaGScsLF2pLIZX9JFT65NVjIhTWPYeBZj2xtixvPCov0pBOrMhaU+mdSgiqzs7ETvwsRMFjPyf3VjR/Q+M0fkzWp7mpebmEe1TRlJT5faeqavCu+crssYtCzcf67YnjcDZjXpqu7aeHx31RnDNlU0JXyCmDkSmml4xdsbYtbtBVKzbRsPl5WnQinPEVpi3dhOT3zUHm2trZGZT/IgdX3MBhzLjX2hJKnyLfa01d1DJv4Yt88M+xwyyz/isCsRBZG3nGoXtkFOTTz0CLKzJN/bm5V/HHxXzp294zqf9mkJFnBucwUrDGg4hQj7jlghUWaAcP5iFT6fGMIFagt71ygkH9l1lLZlaQkFSj0j6eVC6sPGAyl5sm9xVhbRn5mzb6hDVGWWz4lO1TPYWSOiNsKrx0gV6qULcs8KM9EXaTzMSF05O5psibVMQ6qMpQyC2B0ORJ+imYd/sks723NAZV6ipF2D0NCRnHPvliDoaSKWKAVVEDVFCoKVbOpSSlJ+QgY5E9+rQuVD1I2X/uPalqsXwbddKs9Y+et+SJiLpUNzPfeOkJTdnxFtVVtORItreGl8uQ1ZqA0cJHH9ujy/YnldC76knneXHXtl2/5VBf1QcwKrYa57HzpfyXZlMyLYwn59ZbkufUTacW5deJvO1s7iwnK0MMgu3OF0mBOf/dOO8jNNZVqA05ZMCZdwWwX4Fq3oJi8DvYfT66oUjEvO/c3RaTHUO1VOg+6JZJa0KwlBU5qyZdLi74lVIflEEzKuXyqew0GVkSaFdXs/JLgwEZJtjYlAQNSkkzuUPhJrZQk+ad9WX3AIJfWIGPEZyaSnZ2C6tXVvXCbMXjhspiMeBNtkZL84zyoRVZhpU77E7Z8Qi9vfJ9qUvl7u+LHw53USAs7lsx/kTYFSyltY8Wn59KZO8l6ZzWxVLZWEjDIbVYraTvksj26yCGYlHP5VBf11Z3LBAx5ClVDhZ2Ng/i7QCn/yqylUZQ0qEiDnpGSZAHkd67QfwKtbIU0JCpN1c347o4vadL2L8hU3LIcqU5B5XJ2cwpyZdcKVZnWwYy8Gh47UuvYWHSuuKk8tfiYWH1e17SPCvmdqCpQETN/pbAmzx1yaTgo3Y7q256qnvukOejNUWmXx14y3xgGaWyUQisYyCqpK9jaFKkCBoUFtH5bmiKtMQxISbIAcuk+LmXM9thUqIL92A9H6N01wVSd5FaKUHPWXNpM7+34ssaLvLYdc5EpOXpTkixx4STrCheYlJJUJK8ehmp6/eCYy/TKxg/obmpUlXsYpNbWmiSXwM5ssyTZFukc9CylJBX3MDiKvzGGwXSk76UqYJCmVbWAoMyqU5Lq+kQanCVJbqoS29yIN74laPbhn+iLffMpM8/4A7g6KwU2ZrpIVPh9lZayUJppbbiyg6LSK79WQGV7kGr7BV/901lkwGBlYxhUCyvLbeG2atqesJS74nd8VlKlX8O25Ltvzikla/t5RN8YBruSdRiKtHsYSq77NjZFZF/Sw1CIlCSTkYLj0oYFG4sJyqw6YGgaGEIJ2foHTcaXTC9Ws3lLhi6uld+Oilw0zkZfoqsJN6jDF7vo3N0Uo55TW+oE6uUkk+u+3gHjZO0Lpcl4/5iExkqrlvdhSytiteR4s7SVlaUAppq3pyrnE+m55ly0Ss7n+epSqChSrfSsJAM9DLaOOmdSgspTlAQGpXWNktQwBAzyZ2j0/+DvDpnkPUYuOU5bL0YbfExEcnbJOIOKn71G/j1BrDZaHa7HZpAlupMSWamZHdRL/2YFemVq2rgNk+nY3bNUG1S2viGbipmJ7QzRbMTw8kywyEHP1dWjZSmpBrW9h8EUVAFDSQ9DWm56zb13yZEpl/1Vk3ILC1Tn3SIy1MMgpSQhYDAV7cBAUbImhiWUsVX3MLDotOwqPT+3QEET/zqv+p+XVB/6/WGNx5y6nUyfbDA813T/Ofup3bRdRr2nUln2Erzx6k7Dz+EBarkV7/Yt71qT4pNDUc7Fg3aqS0Uvd3mF+fTh7hn058WNlXix0gdUJCWr+Jk1e2G+lnCzgs+Qb8UBSo1ffU5jfzk55lh0D0Ot6dEy8vPKZVxcdQYKPNvewdsnxN82Jhj0zD0MJyLO0WubpppwFj/DpOksFUr5p4KYEtcDtl+KUP2vv4ehiOxtS1KSLKD121IotI436X9LOA6tPmCQojvGaTixuk5WBi54Z+6k0JYLpb0HvKT65ejiVpLYtFxq+tE28bedre7X+GHvDaN31vbrxSdoL4/ECm2jpNN0w0FFZST7ZJcEDPKpFEhfvMrM0a95kZXPZ5ICodrZwl7xcg4vmcpW1/5bc2kTpedaZs+Yvv0rlzEMPMD12yNLjGyVLQkYZPY9spZpTKszRerzvd9STKZ0rbQxyRiGiLTi62hMRhzVBGnBLEto2TWlt/48T8uPqTU22SjKzJJka1tAdnaFZC+lJFlAZdZSexiKVD0M8i9jqw8Y1E+mPND3HbUpR+3tiytoN5Nu6y1AQ61Jp9XmVJcChsvRaRqPmfdfKOUXFlFgwyvUukVxQMDeWVPaayGJyyweXGZnV7anoLyLMm+mX339n0MfrhgkVGFQmylU+IJXzsO5Beur/QuNSFmq2PtWtEeiorIKNHvDqlox4el1/71SfhDJqXLVWWGtTHVD35zVXInZcGUnrb7wr8bUjzcMfIflaOPVXZRfVBr0ZBixwGFN+D34HzoVFUz5WsGrrsDi17NrrKuHQXbTqpb8robN4UVEJVXZvaUpSYXk6uAi/s4pNG667aqSZqexhNxxUzp7J1k1fsGGHKhQkS8aNlOyir/TOfkK6tF5F9nbFZJDSUoSxjCYTqFW8CU1vljCcYiAwcDZ1MWpOIc93cBc09rPlk6egxce0jiRZhYmiQPipeWny7zG+rOR1MAvTKPnILnky6vxXiUHFi/YLll7prRrsTxSAKTt79N3KS1bdwUsOvsavbX1M4rU0Vrv7pZCgZHe1CMvjeb9d41MISEjr0xFWNc+SsxOFgGe+oVL24XYK2Vu44s5V5RD4q/r/EwFisrnsyZl6t8WU9AOCqtaMeHA6a9Lm8p9HKfKTd98mUzp0J3iVS4rW6HUFyCr8sipdD9+c/BH+nTPHDKF6Iw4VYtQdbC3z6OGfqFl0uk+3f8ZPb9uIl2KM833rLKki9uZ6IsGH3c9MYysTVJOqkxTkqphe0wUBNqUpAVxK39Nr8kgzX9vCS27plSgKJ0hyd7GhWztiv8+HpaksQ6DuN/WQQSc2pVcMOEYBilgsIAyRsBASkrNzhet/OW5GZ8hHseV+f3Xo+lc9CUau+xU2UK1LSDXeuvpUnS4qkegU9uDtO7yttKZl9TsuhxbwZzg0m39cH3xhbuyp29uVZj6zyWatjlE5/3p+Qnid3J28cWQHbuZSHcSs6hJoyvkmG8nfg7cMJxaxeM4otJiKdXAoLa0nALqOWMP/XZEszX4amxymUGf/908LFLIQksqJtxb8PPp1RVaSEjXZemPk6WraHPswNukjY8Bc6QdaFesK7oFVdlkDmpNhQOVH0+uULulEgFDBSos6oEhB6SRKcU9Nf9c3k7zjy0V+djGLjT47vbptP5KcZphdWgccIUaNQzVeR/nee+5dYTMSToHfX9iudGrO1vLSs/HI87KbEHB6uvxsNETvHPlWzt10piUJO4xLB2kTTVCPVjhqaGTso2bEdDS5YsZkoorpw62LmRbkpIUlphMW6/vpWy1nnJO21Iqbc067a2Er7m1YYC6okzAoLCYwNXqA4Y8RS51+eo/emPVmTKF4+JSmhLAFdZnfl1Hb63bQOO3TqKZh36mWYd/Ei2C2lxdMsjevoC2hxZf3KUvZESq7pmSDoYWV8p1tXbzl+SrLVfEzCm5iuKpNB3sdXx5jbgoSys7qs+G0H3GDmrX6ghl5KWK/y9ElAYGbN+14l6PyWvPq8ZbPPfrSbp/3gEy1tGbiWKmqPd2fkmvb5pabkqP9lSuYUnxtCMkVqMXRPvjXk4IpX1hR2lb6D6dF8h0HQO+dVX61XsYolJzqPOXu8vc3+qzHbTy+O0yX3ztV5PuN1l9SU/Py424jDIz6xhSmZxyfWNwTLHC98+nV4keo4oo7zOov0eeorQCM275Keo3e7/4+++QLWKgJa9+bgzponk7xfhevfJw8Cmtwi6trmqIfUnetbnoumBzgwt/V9RJrcWmqADmFSpEwGrKIH3O4cW0+6ZpZsHTVh0VdD72yksDq+qYCh7EnGlk6ptU2dY2+/AieuGfSRUO/LnSLm1nzbW0Fr9fZn62WHxy6dm/yFpIvQpOtm5kV/L3laSz9HvwerJxKL2W2Nva89mfDt2Io58OVHSSDdP65cyfNHrtW2TpCjGGwXIFJ+0gR4dsup29V3Xb1ivB4iLYqEGoxqmlVdBpSrMtfpy3Z4LOSnjxOU/3CTossfzWb/Vsh5af7qBnl22m1acvi5lTwtNuqe7j7dsZUtoyaqN1Uf/l9B9iAbbNJQOyxUVMq44VlpBFHm7J5O6WSgV2N+iD9RfoiUVHtT5P8ZMSM3PFeAvNz6mubAWOB5AnZKRTopGpOtIFo2xlUElv/XmOOn+1W8xKVfyYku5rUlJwRKqq1Zifq2vV0GE/6GqZNe5Cqr790pRz28N/1BjvwgoU+WKKW6kV+JtDP+p/zaxkikyLEWMDjJ0yUzvVQaqYPLzgkNrMOvr9dq44p5wZSuXSeM+SbTNlG7Gu1qqTEedVx4C0j3W5En9DPKa8HobTURd0BiHShAQVFZ6UVaEg2VjP/3pCc3Y0G6VRaRRciV584JaYT92ULkWm0asrT+vtcdU+Bvn4eH3VWeo7a59GGqX6/plUxVXmfzkYRu+vu0AhUcbtu8z8rHIryZxS9Ws1VRA5H196/5tJd4yuhBvCQe2YfyZVqKW3IglJHIwsOrWSftDo+dPPRs9/F2KvlnksN2a8vKJsKq56YMk9DFKgUJkVb7lXY8W5tRUKqqR9pEo5lkkqmSltPB9Fc3eVpjFK5wtpDIOzvauqtyE1p7iRRWlT2tji5uhMpLQlB/s8mrPzerVv70PzD9LM7WWPIbY3zLy9q9XV6KJKSUIPg/xxa33jRleovm/xqpXs90tL6IWVmoNB5x4srWyVRzp98lgD9fQhfastt2lxTPX3Iq0ovsh9J3VqW7ai0n/2fhq/unQe/rxCpUYEuyfsiFiA7Z2SKV8jknM0gpuBc/eLlm9X1+KLsNKmUOe6A1LA4OCQS05OmaJyrouypKX7TlKqajAxV6hf+ud/NHP7NdUJyhDpfK29Hep1wzaf76QjNxJVt4XGZtDwRUdV09by7Qdul5an5E5S2elzH/vhiGowb0hUmgjCdMkrLKJJa87T9ksxIv9TsM0pMxg8JKE4reuXM39o3L7jRtn99+bWT2nyzq+o0/RdNGLJcdVFk4MI7R6NjtN3ibEqZQYD6rnA8QmpvArTrhsHydjua9679va6ByIaqtyzXw+H0a2ETLHOCI/r4d//XY0q8zhpayevvSD28V0d++tyfChN3z+fjkWcKRNU7r8eL6YLVG/dPX7b+J4Aqbz4gsqD/rTxGI70nHyNoFF7kC+nOFXU6TvaaRCG91uR0obWnYmgjl/sptk7r9Geq6adgnLu7uviNb8+8D2dibpQ7sWOW/453ZCpTyctBTZkZLjJKY+cZmgoYC9vWmiuLD6/bhK9/O/7tOX6f6rbJ2z+hL7YN49qyqZru2nmoR8pJSeNPtkzWwwUN4S/Q7qOd3XSuYZ7tbXXyYlJ0+zd4Uafj/65qDqmeZFHXbOGceonp9mqTyLAY3RMjRsz9l0r/n4a6mHIL7luVGbWosPhJ2n7jf10rCQtrLxjLT4zkYJLxrhJaz8Ut6abHgeNvC6QObz7dzAt2n9LdU5LLrnGSWMYPBzdVQGDlM7r7FQa4Lo7upKtXZ4YY1nXp3o/A6eL8rV/yaGKj38y1bgybvRQbyzh79DSQ2FlvmMm7WFAwGBZtHsJ2O1EzdmMzsXr7r52d08mR0etk33J9dHeroB6dtlODfxKewaYpztXeEsPGk+P0pbQAP+y3X62tmW/DBl5heThnkiNA4orqZlqJ2NjUmCkCnR93zvid779JbqdpDldq51dPtmWtHg2a3yJOrc7ICrnOimLW7o/3PMxTd+/QCM9q3HQemrW+KJGJVi9FYGnouVZGngtCn6h6Kw7Wi2cyjKzT6VlF19UZu3SrNQUKpQag9T5C88XByktTHvSVCkF6Ymf9tFL62eQv46ZpHi8xqbgaHrzj3MlFWjd9A121E7BUdew0XEKTbwpKgTLzq4RQYR2OldGbqEYq7L6wgaN+wr0nCSfWzdRTHuoL7gr3tayz+VWa+2UNC6f+r7h1LLVTkrLSVe13ksnPS4T9bI+fOeUaCnhSvWwH4/Q/7ZdFa2Lx28l0bXYDBH4xGaUrbxIlZt/zxcHE/fNLU4bUpdSMqg0Oi1V4xjncSY8mUDH6bvpqZ9Kj8+fD9wy+kIirTT79p/nqe20sjNH7b+eoAr+U7LL7k/uzeMUpycXl/ZU6nMnJUL0RKlX4qQZSspzLjyVPlh/UXUcGjoepcro/P9Cxf7g3gDuceQyOR8TohFUnom6KHqdpNuuJ12nOUd+LvN62j0a6uOvYtLU0sDUL7pGBJbzjv1CS8/+qTPQtS1Jh0vUKqPribdEOUrjq3iGrIKi4sdcjC1tVU3KSaGrJWuWcKOA9kx1+nAPLp+X1FPGjMWVUWk9AWm6UH1+OnBLHO/GzLKmPeh90MJDNEGtd5HLj7/Dm0NC6G5q8b6Ze+RnenXThxrPi0/Ppa+3XqGvt17VOevYvmtxtPtyLO2/pjsgVe9B0nUuuaLWkyc9NC5d83vD5xApEOJeBan3RDq38PFq7PdC6qk4HH5KNa5NHw7i3t72uep/KciQplk1NX4/XheoOh0JPyXSK/XhHng+D3+3pzit2MEhjwoLHcjL2U3VmJejKK4T+NYpDQyc7Z1Ufwc1Da7Ud8FYtxOzdN724foLGucP7XM6B2Sj172l93t2KzGWTt8tf5Y8vtZ1+/o/+vTfS+K4nLhtGm2+FEpz/jtH3+4u7iWtSFokH7/cqHNGbbZMXSl3Um+/JQwsr56QugKSkpJo7dq1FBcXRx07dqQnn3ySbEumOzPlcwzx8S7bquLibNw87i2baX5J7+m6VfW3m2vxhUyqhHKuoLNTJrVpeYKSUhpSWHgXnYuwSVF+UNPS1/arV/Yk2DrolCqYcHAoPbEuO3FSY3tSUv0oPLKDWDFW4u0ZRz8c3kNOjqUncX6/nFwPtTLIpEYNNbshnRyzyNUlnRwdiyPu2PrF5eSbFUlJyY3E36FJYXTsjuYg6ro+pV/m0Uv30+20W9SiafH/13IXkW+dTqRQOIjXDmhwg34/765WjukibSy/wFVU2o4nLyAq+Q4GNT1PSSkBqiDtn8u7KdCrgeq5f1zYRpuvb6MeXYr/z1NLxWnf5gh9sOsmeRQ8Tj5eceTgpHlx9K0TRWHhXcVaG8zHK4biMjSDqj3XS8tn0f4b1KS4CCgsOVzzcTfOEdlm0UNB/TVu9/GKFz9vbT1OjnbFi+TwDDl8Epzc9zWKTi3eP9y6wz1G6jaci6SJvTjgTKA2LU7SnF2NRMpNkWuR2AdP/nSIPn06j3oFdqKsHO/SbQk7Iipb6vj/JXszaMP5KLox41FysCtJFSgsoqaBxfty44U7tC18sfh7eJtHKTQ8iA6ERlGPzqWVmR9OLhc/g5uNoIuRxcdIXkERxWcUf44f91+nPl3LBt8penp31Ek55wv+u0lDu5cGnNxrIVHYJGkExfqCtb1X48qctLn8d16OJQeHHFp8cjW93vPZkkF/So0xTXE5t+no3dPUt3FP8T/vq+yC4sqOQ531RPSg+JsHUfL7Nyo5HrlCmJSVRjtvFvc4xWaWfh+/3nmAunbYTVnZXgbLIDu/+H2kBgdpZi7ehqw8JS0/lEpfPtGBvFwcVJXenw9foAZeNuTi4CpaHBNzvWnnndU0qffL4jNk5+fQnCOL6cHm/YiohUZYzZXBvAJOZyxOGbkck0quxbNfinJRljQsODrmUk6Op+p5f58JU30nPd2TaGfoYRrefmDpfiqpFHKgxoGTNO3tichz1Duwu8ZnlhoPkks+K/dgnosJobCUcNWg9jqu3gYDc8mrf62n2KxoauinefuxW9yoYENB9R3Ix9VNjBX589RdVSAUVM9d9Gz2DqpLOYXZNHn9Qeoa6EcXIjI4xVunqLTiwCQtz/C1ZFdJaml0ag75uDoSx0d13UsranFqx4k6qadLahjg/RGZUvyd69DmMKUayDoML/nOcKsuv440zocHIXOvxcsrSsf03Zk1VHw/toRcoOhEH5r0UEuNHqQipUKciwa191fd9uP+G/TT88X7kQ8DPlL487WoX3p9UU8ZPHM3kbzcSo7lhDSiNkSfbwqhP07epbBvhoigkY8Td0e3Mtd6Dnb3lqSB8jmIf9aOKj5P6ZJc0vCgfSzqGh/EZbry/Dp6pOUAaujhJyqr/J2wt7OnaZtCqKG3iwhq3h/UWnXO1Ed6Hy7r386uoZe6jiQ3R1cRMD7Szo9a+pWWTUXwNkqTEKh/7qi0JNEgmJfnKsZJci+PJLDhNVIo7MjdyVlkWbRtfo2KbIrL38mptDVdO/VTex/qw9/RzIJs8nYuPScYk/apPnNjVFoyJabb0tozkdS3ha/qvlG/bSU7r130zYPTqb67j7jWMe7FCfRqWOZ1P97zlUj1/NF7AdX3dNb7/peiir+v3DjYudUt8b07dOsyde2wl+4WeNEH61wpPCmb1o7vbfBz8Dl5xrar9EDb+vTXuWO08ZIdHf9grM4ehqm7vqHbqREmTUniTI8bUTrW6rL0gOH27dvUt29fatWqFfXs2ZOmTJlCy5Ytoy1btugNACrznMrgFvWq4oquOp42tVO7A6oKtHolWptUSZPwjET6AhNtGcrLZQIi7aCIx2NoJ0NwT4d6b0e7VmVTezq312z5zXIvvtA0dL9FDdV6UhaeXKR3++x81lMLn9L/+ZzUvInmNI27w0pTCphv3UgxINTVpWzroG+du6rnc1AWnVnaQsLBgiFxWbEUR0upeRPd97s4p1NydhZ1bLufXJyzaNaxs3RP19L7fwleqHMfffTfLI3X+eXc0uLfZ/7Uuy1SKx/Pwc84teL23U7UNDCF6vuWTa+pVzdSBCYcLLANlw9SYMOrqgSQ1kEnafetZNp9a5/G87SDhQkbZ1BSXnGZOTg8SHeSEyghJ1JUBP4+XzoL2OawX8mu5Jq68doOOh/yINXxLq3MfLX/R5K+gjtvrxPllJpWj7y9Emh/rB01adSI/OqFE9c/tXGL5pHrW6lJoxC6G9VO3LY9dB+1q9eK7qRGiErAtZLtrlcvlC7EllYOuXfIwUEherGksUWsfeuj9NLG0h6HCf8sIju7AOreaRd9uecy+dcvff9XN35Af4/8idzdksVxv/8OUXpGQzoUsZsGte5EDvZO1DqoNA/7TOQ12hd2guo4+9DBcM1eN24pdbBzoAlbPhH/B9VpQo5Uj4JjLmtcjDnVhlv3uAcnsvAqOTgQOTtrtrKlpqltJFfOHG/QPV2LWwnzC5zoyy121NTXjRYHzxa3nQoeStE2v1CvwG40usPj9Gfo/6hLe6J/b+8jP+cW5O7qRxejiyuLl+NvUFi0D20Jn6fKEXaghhqNJTzIMD2jLnl6FAdiUrDARq19ky6E3U9tW54RPYnBlx+gkb9upB9H96c0m9L0It7nf4aEqwIGTnvh2aYc7RwpX5FPjVy6qR674NivFNcpkTrUa0//he2nV7uPptSSyQ7+ORdFQzr50sIj6+lm+inq1aibaixWYVEIHbxR+r3nXiCu3PGxI+FxXbbuR6hhaVsEbb62m3beOEjbj/YhO9sC6t55l6gYjugwVFTcef9wy3hGbh59svM3cqdu5F5/gwgS9vPp20Cj9NJzvxXv5+xkUclcfjScToQl0S8vdBcVsYuxV+mb/avoTkoXsrV1op039tKRqF1UmOtP61/8nO4kZlMDb0fR0qndy7P5+i7acGUXBfg3pqjYVqKnRez/81y51l3x4F4XP/e6VMfFm6JKAosrMek04ufjNOOZAFUvzYzDs8jOricpFPbk6JAr0ja5QsopapHRrahbkzHkbOdGmVR8rIYnZ9GUtZE0rk/puTkmLZPm7TlDT3b1E0ElT6zx55Vguq/VZyWfoVA1bomdjC09T5+M5Bb/p+mv02Hk7pZOE7fMouFth9DS8z9TJ7929NnAiaVlUaQQwa62B77dRx8PbUl3sg6LRpqm3o0oPiuR/Nzr6d1fHHiejDxPbX1b0KHwk+I5ay5tERVSHpvx1YNT6Lvjy+hi3FVaOux7+v14aaPQ/W3qU6/mdcucBxYeLz4G2LPr3iYfZy9qWbeZWMuEzxHdfIfQ3F3XRU/d5rf7iWN2x439osyGtnpALFAZl5lIVxJu0ogOQ8jZzkkcO9yQsT3kBrm4ZFGOovSazWlwPi5e4tj638HvqWlg8e3br7mSk6MNtWh2joqKik/SyakNydfNVfzt4aWZ2eBS2IvCkuPJt0NDSk2vpzqv7rpxlFrUHywqtwfvnKQBTe8VvTsc+EsNXjyd+dpLW+hG8h1xTuXt5c8l1c+4IeXD3d/Q/x78QKRBtfJtLm6/m5wtGkJ4wbiPNgRTzy47qCibW6MC6WpM6Tmp0GUv2SiLaMJfOyk+2Y8mDCmuHEdlxIrxgw8F9aPs/FxadyaW7m9dXzUu7Pez++mxDi2pTb0WIn3xyN0z1L9JcaPP7usXROqs1GubmFUcVN7JuE52TkQ2dmm0rmSmwGux6dTGv2wgxD1y7/0dTE93a0j7bp2jrSGe1KVD8TUjI/c5cnOyE2XF+0giBQvsRFgCjelYQF6uDqJ8eR/zuZJn8PJ19aHRHZ8oLQNFoTieG3qWBumS134/Q2HR1RMw2CjNuCzlyJEjKTIykg4fPkx2dnYUFhZGrVu3pt9//52effZZkz1HW3p6Onl5edHwZS+Tg2vxwiQAADWplU8XCk3RPyD43G+HRO/Zw+8H6X1MfGIg5ea5U+MA3QMF5aRD/XY0uGV/+vboEqOf4+nkRdHJNmJihppWWGhP9vamS8HgFJDMbG9R+eJFynhsgT6eyj50LT5OoxFGH0WRLdnpSFs1xN+pJ4VnXFL1MHvZN6O0wtK0jejYINHgxb3SHnnPUoZT6QDx6NgWVK/uXY1e7VPnh9LgTu6UbPd3mffKyPQhD/fi5qkWdZrSzeQ7YgySodmkmrj2ofDssg1WkgAPf5r1yMd6Z2RS33dcYb2vyb108E7pwqhV5a7oQyHR6eRfP4xu3elKPZr4UpsmMaSgDHq9x3OUX1RAk3doppfqUs+xHZ26aUf5OQH02iOpVMfFRzTGsCbejfSuaG/I2E4v0cqLZac95h4FaUaklLT6dCOsJ619O4C+PfpLmce+1+Mr+uXQbfrxuW7U/otd5O6WRO1aFY+1u6dhL7qbfkv0kLas04puJBdPhjKh6wfUxNeePvpvpup13u/7hugx54qvLdnRi53G0t7wnSJ9yM3BhbIKcsTYkY/6v0nf7w+mhPxL5OScIr4rPNMk42yMhu6NKM9Bcwr7OxHtKT6xKd3TVbNR8OsHptLn+2aL4NZeEUT+gcXlKRnRdiT5ebqKqb3HdH6SNl7ZS5kFxY27Idf6i0ZJ7QZM6b6ABqF0T4O+9PVjD4pZGU9EnKe37x0rejx/ORBNMdm3RAOQdlq4g60TFRTl0bu9X9EIIrUFOt9Hj3ZoRMvPraV5g7+gVRfWixRg1sZtFL05oDNl5KfSvrBjooGna4MO1LZeC1HG9zfrQy523vTj3ijydLpD+9+dTWlpaeTpaXwvj2wDhsLCQvLw8KB58+bRm2++qbr9oYceIh8fH1q3bp1JnqMLAgbTCQorblW51dy8q0ED1DYcMCQkN6JBHxS3wIG8Rce2ptw8Z2repOxgcdDt9t3O5OGWJHqQTSEiujUFaqXRylETr0AKTzPd9MzKnA5k46J7LSVdzl96iAoKnenwx11pys6vqaNfG/r3hAs19L8pegsXDVlI9TyK0+IeWXBQrNHQrZPmFOO1npIoPbMujWj3FG2/s0wVbJkap6G6uRo3rspYBdn5tPHlZSYPGMy2DsPdu3cpNzeXWrTgnNlS/H9oaKjJnsPy8vJEkKD+A2Cprt/qWW6uuyWIS2hCdyI6VOg5nCZRUdyyVhG5ucXd9JWRkVmn0s/NzvEQPQaSlDQ/kYJw/eY9lX5N/e+llpdTjrDwzhSXUDLgiHPM73QVLdDGyMtTy2EqR3xiYzod/Cjl5LoZfBynYkVEt9HbsqzL5es8PoOMek56OftQShNLz6hDZ4IfpTMXBlN4ZDuKim1OicmBdPVGL5FKyJVXPr7DwjtpPN/DtrTsYuNLy5VdujqActNLvxOJSY0oNr5ZmW24cbubuE8SeqsH3b7bUfV/Tq67OI6jYlqK/2/d6UIxcc3FMaYuL99ZzLzFFAXFn7ugQHeve3DIA3Q3qq3q/7MXBtHZi49QZXE5JqX4U1ZqT/IsGCa2j7LuU5V/VrYnxcQ3F+cJN3tPcnfw1Dnm70LIQ6q/Y+Jaih4XSXRccVkXKuzp0uXBGsfBzdDHqL3reMpNGiZ6SNTPRdwrws/l4+zm7a6iPDk1j3sTboRpjrHRpzCvgepYSUhqRHEJpftx/cGOFHn7cZ3PS0sNootXBmhU7rl1m8uBy0OSm1t8DeDj7/S1pnT5el/VfXzM8L7h+x5rPFUck1yG/F2+G9GFtr79CK0b35saeTag9/q8Klr4k1MD6EpoHxra5C1VsMB4LMq/Ex6gcR3fpuSU0hQYLhNWz7U+vdrlNfE3Nz+nJHYQZcf7k3sH+Fhlyan+Ir3JqagZZWfXUZVzcnJjKlI4U2JygOr7Le5Lb6xxvPF5vJ33AzSy3UiRDsvlUVRkT5ExrSgmqh9lxQ9XPZZfy97GVfUd+6jfe9TAqTc90WIsZWUVj4dITWug+g4kxfUSr6PaBwn3ifROynyEnu/ZmW6FdxXbdX+zvjylJOXmuYrvV1Yap8/aUkGW9B23FdvV1vMxKkweSeO7fEItvbtSZHRrcexI+PvIgkMepMvX+9O3g0qnaOfeFS47Pr/weZq/27xfisvXRnVO5e3lYzEiqo04RsLDBonycrEJoIaOpd8JUzJbD8OlS5eoU6dOdPz4cerVq5fq9qlTp9I///xDN2/eNMlz2PTp0+nLL8suztT208XUoeMFSkppQHV9YsTJNDfXjer4xIoDnS9gubnuFNDgOuXnu5KTUxYVFjpSfoELNWl0WRyUPDiZK2+x8c1FVxQP/otPbCJyXwsLnKh502BxAUxLry/yk12cMikxuZFY/dmv3h0RzTO+uCSnNCQnp2zxHu5uKSJnnx/Hz7tztyO1Cjol3ic907ckz1gpxjrwgZif70L29vnit7/fLbENXLnirvz8Ameysy0U92dle1Md7xix3Ty7U3aOF3l5xlNiUiA19L9BobfuEe/dtPFFcSArCh2oaeAlMRi6oNCJChUOpCi0F2kQPIB7YF5xrtwhVx/x2PxCZ2rod4MKCpzJyTGb7kR2EJ3P/Ll42/i18/LcSFFkJwaDJyQFikFZvJpko4bXKIf3Qb4rpaWXjkr09oqloiI78cOfRVDaUJHSlpoGXhSfibcvNc1f5EA2D7xGkXFNxDbY2+WL6W0LC53E9tjYFon3YJyfy5+dB3dzefFn4vfKyvImDydPyi5MEs/jgdb8uXn2iMxsH1IW2VJBoSN5uKVQWno9MRiW56nOyvES+5dzJh3s8yk5lU9IPLUuD3bPFrnF/N4uLunk7Rkv3rNQwfs6WXwG3tc88Jv3LZ+M3VzSydauUIxJyMurK+bH7uTfmE6pZl1QlnTs25CPdwwV5LuIsuOy5Ndp6pdOmQWplJPtT9l5dmKf13XxE92lPM0u48/GJyH+za0cBQVO5OhQSBlZXuTjHU35ea6qAdM80xQP5M/O9RDHJs+0wfmwzesE0JWYNFr1yj206dJZWn9KQXXrRInB9rztPJCdy4gvnvzd4TK3KXKn1Ew3+nZEZ9p7PZJsHG9SYoaSTl33EeXE28rHpvQ5ma+7c5k1PToHelMdNzsKqJtH8al2dCY8mZIzeegmD9RVUlt/b/L3chED/hzsc8V2Jac0EMeRp7MjBdZxpW5NXOlM9HlKyCigxOTGdF+remKWl44BnmRvZytm5eI8+l3v9qM918JpV+gZupuopGHt7hHpDgdC4ykqLZUae3vTkI4B9OP+m+KCO6pHI1p24px4r/bNoik2VUlxCc2pY6AttfCtS46ud6lHg3vFLE9LD4eJAahjejURU/j9dyWO3E6vFIP9uj/3Pj3Y1o/ORETQgj3nycepERXY3KXk9DqUmqWgZoHXyNexAzXwKSJvxwa08ljp1LwB3i40d0QnmrXjMt1KjqD7WjSjg9fS6YkuAXT+biqN6OEncn27NPakqJR8Ck/KJGfHQopMSyI3+zqUkaukkT0Cycnelvq0qEvrz0ZQi3qeYnD9kbBb5O5Qp2Sf2IjvWtemdpST50DXYnKpY4Av9W5eTwwaHtG9EaXlZdKyM5tpTNeH6f5WzSg2M5oW7I4mP+8CerX3vWJq0YV7b4i1IH4b15FOhSfRmdupNG9Edzp+K4W+2r2dAt1bUkGhPQ3t1EBs0+3EDDoXEUtN/fIov8CGElJ9qHH9DDpyM4YebdNDPKZHEy9acSyCshWJ1LheLn388EMUk54mZgka1duVuvl3o0X7b9KCUV3EmhLuTnZi8LCNTR691r8F2dk40qrTwdSjiT8duJZI12IKaGjHhjR+QJCYNYan3OXplhv5uNCZ8BTqGOBFgXVcxDHz7kMtxfz1nRrxeTaJnu3aQwyYvRqTLqaQfLxzQ5H7HJYcS2tPJdPLfYPo+Xsbi8kZjocl09dbQsVgWlfXDLJRuFNuQRHZ2impdf265O3qQG6OdjT5kdYUlpBJ07dcoXub1aFmvm7imOIBqjxz2+iejcjNyZGcHWxFrvy2i7GiXB5oU5/quDlSfS8H8nQpJCpyo882htC0x9uJgbyrT4bTgpFdRA59WGIG3Yqzo0AfF7ocE0vBkTHUt1krMeCaZ6bq3KiOGACenJ1JEx9oQ1EpuWRvR/T93jDqEuhGnz3eirJzHeiL7bsoP9+DolPsycPJnhr5uNLT3QOoX4t6tPVitNimj/65RKPuCaQ/ToTTI+39ydXRjh7rVDyYNS49h77fe1NMg+3kYEPZBVnUKaABdWmWS6duJ9HQdt2oVX13yi9U0GebLtNLfZrR9bgMauPvIcYYTPzrPPVv5UPdmjjSwt2xIm+eJwh4/5HWYnS2o30erTp9ifo2aScmgGjg5UKPd24gZnhztLOluu6OYlDsK/fVo923N9HHA96gP06fp4sRCsrMcRSz9w1s7UN7rkeK68+z9zQWg8F5ZrNHO/hTKz9XOhueRu5ODnTkZgIlZ2XTj8/1JAc7Oxq/+jTd357HPDWmGVtvUkMfe2ru60ZJmUp6qlsAebo4iLVXXunXhFacOkFD23UgJ0cFHbiSQ74ePFjeRoyRubdVDp0PcyJvF1dq19CTJgwIojtJWdS8nruYAtnX3VH8rY0nSOBy5QHcunBVcevFGGrt70EuDnb0yb+X6OEOHjSqewtysnekzLx8+mb7dXFe+XxoWzGw3tPZQYwN8HF1oIGt69MXmy+LCTDaN/CkHq1jKeSOrzgv8j7gY3j+qE604XwYJeXdpQl9HhLfk34t69L/du2hUV16UYeA4msRf1+D6rmJmYj+PhNJ04e1F5/rQlQUBceGUFS8P33xWFcxrXdrf096uF1pfYLP7dsuRdATXRqTs2MOnbydTg+2biymoP/w0ebUop47FSjs6YtNIfRC7ybUvUkdWns6ghp4O1P/lvUoKTOXvt19g7oEeokFZXk8EJ/vR/Zyov7N2tDcXTfo4yFtVRNPMJ6SncdEOdrbUtsGnhR8N1WMe+HvI5cR/x2WfJdsld70z7kIquPqSvc0qyOe16NJHTFbVFDDNNp/WUkv9mpJM3cdo6C6gTS2T1PxPedZCA+FJtLr9zUXrxVyJ4a6BAXUnpQkHrzcvHlz2rlzJw0aNEh1+xtvvEEnT56k4OBgkzxH6mHgHwn3MAQGBpq8MK3RTz8VzwuuniIGAFUnfaek7xgAAICxafe1JiWpcePG5ObmRtfVpqVk/H/btm1N9hzm5OQkCk39BwAAAAAAZBww8AxHvH4Cz26Un18828KVK1foyJEjNGLECNXjNmzYQAsXLqzQcwAAAAAAoBZMqxoVFUX9+/cXMxx1796dNm/eTAMHDqS//vpLtWDIq6++SidOnKCQkBCjn2Ou7hprlJxcnE9fp07lB3sCQFlISQIAgIqqrjquWRduCwgIoIsXL4pKP6/azGss8BSp6p5++mnq3bt3hZ4DNQeBAgAAAEDtZtaAgbm7u9Nzzz2n9/5HH320ws+BmoMeBgAAAIDazWxjGKB2WLNmjfgBAAAAgNoJAQMAAAAAAOiFgAEAAAAAAPRCwAAAAAAAAHohYAAAAAAAAPnOkmQO0tITPFctVE1OTg7KEqAaSItT4jwFAADGkq4Zpl5mzawLt5lLZGQkBQYGmnszAAAAAABM7tatW9S8eXOTvZ5VBgxFRUUUHR1NHh4eRq8OXR0RIActERERWG0aZSkbOC5RlnKE4xJlKUc4LlGWcsQrPDdu3JhSUlLI29vbZK9rlSlJtra21KhRI5IDXrbblEt3WzOUJcpSjnBcoizlCMclylKOcFyatq5rShj0DAAAAAAAeiFgAAAAAAAAvRAwmImTkxN98cUX4jegLOUCxyXKUo5wXKIs5QjHJcrSmo5Lqxz0DAAAAAAAxkEPAwAAAAAA6IWAAQAAAAAA9ELAAAAAAAAAelnlOgw1hRdlCw8Pp65du5Kbm5tRz7lz5w4lJiZSmzZtyN3dvdq30VJERUXR7du3qXPnzmLBPUNu3LhBcXFxGrfxc/i51k6hUIjy4fmZeQVIe3t7o1dHj42NpZYtW5KXl1e1b6elLADJZcm4LB0cHMr9bnM5qnN2dqYePXpU63Za0vkyOTmZmjVrZvTaNDExMaJMg4KCqE6dOtW+jZaCy4SvI1yW5X1fpeuUOj4v9OrVq5q30nLk5+fTqVOnyMfHh9q3b1/u4+Pj40WZNmnShOrXr18j22gpCgsL6eTJk+I73rFjR72P4+vNzZs3y9zer18/smbx8fEUGhpa5vY+ffqUu+5CUlIShYWFiUWD/f39K/7mPOgZTOvIkSPKxx57TOnr68sDypXnz58v9zkZGRnKQYMGKd3c3JStW7cWv5cvX271u+bEiRPKJ554QlWWx48fL7dMxo4dq6xXr56yb9++qp9XXnnF6styxowZSn9/f2WbNm2UzZo1UzZs2FC5ceNGg+WSm5urfOaZZ5QuLi7Ktm3bKp2dnZULFiyw+rKcO3euKD/+rjZv3lzp5+enXLduncFymTJlitLb21vjuOSytXZ79uxRdu7cWZRjx44dxbH2zjvvKBUKhd7nFBYWKseNGyeOx3bt2imdnJyUX375pdLaHTx4UNmtWzdl06ZNlZ06dRLlM2HCBFFe+nz99ddKDw8PjeNy8ODBNbrdcvfee+8pbW1txTW6PO+++644HqXjkv+HUh9//LEoywEDBhgslsWLF4vjV/245B9Dx7I1WL58udLR0bFMuWRnZxt83rRp0zSOS64TGTrH6oKAoRrwgb5p0yZlcHCw0QHD+PHjlS1btlQmJSWpDgo7OzvllStXlNZs6dKlyg0bNiivXr1aoYDh+eefr5HtsySffPKJMiEhQaOiwCfkyMhIvc/57LPPRMVYesyWLVvEfjh69KjSmnG5xMXFaQQQfBIPCwszGDAYU+GwNitWrFCGhoaq/j979qw49/311196n/Ptt98q69Spo7x586b4/8CBA+I527ZtU1qzVatWiXOl5NKlS+K4NNT4xOeBe++9t4a20PLwMcWNJcOGDSv3+8vHsqurq7j2s3PnzokAeOXKlTW0tfJvHOB6ztNPP21UwBAUFFRj22Ypli9frgwICKjQc7hh0MHBQXXdvnbtmtLLy0v53XffVeh1MIahGowfP56GDRtGdnZ2Rj2+oKCAVq9eTW+99ZaqW33cuHEUEBBAK1euJGv26quv0pNPPml06owkJyeHzp49K9KYOHUEiGbMmEG+vr6qopgwYQLl5uaKctJn2bJl9PLLL4tjkT322GPUpUsXcbs1+/rrrzVSDbgsOW3h9OnTBp/Hjzl//rzoauf0MCAaO3asSHWTdOvWjby9vUUaoj58/D333HMiFYkNGDCA+vfvb/XH5ZgxY0Q6q6RDhw5Ur149g2UppYlcuHCBrl+/Lv6GYtHR0fTaa6/RH3/8QS4uLuUWCx+XfO2X0l85HXno0KFWf1xKqTRcr/n999+NTrfma/elS5foypUr4twJpeUSEhJCly9fNqpc+Lh88MEHRdoSa926NY0YMaLCxyUCBhngPOjMzEzq3r27xu2c28yVC6i4LVu2iIruPffcI/LL//vvPxSjFqlyK1W6dJ3g+YKpfVxymeK41F2WLVq0MHicHTp0iF588UVRuW3UqBFt2LABxyWROP8dOXKEdu7cKSoVXMl94YUXdJYNB7lXr17FcalHdna2KMtdu3aJyq6rqyu99NJLBo8z/j5zAMaVCs5tXrVqldUfl1wp4wBs0qRJouJvDC5HnC/L4mwWbhjg47EiY2N43BdXbIcMGSIauxYtWmT1x6U0duvpp58WDXjcyLxgwQKqzHHJQQc3WBsLg55lgAf6sbp162rczv/fvXvXTFtluR5//HGaN2+eKD9uLZsyZYr4cvGXo3HjxubePFngwU/co/XUU0/pHcRn6LiU7gOitLQ00avIFzVuHdeHW8H5WGzQoIGojHAvxbPPPkvnzp0zaiBlbcYt4B999BGlpKSIQbjaPTjqUlNTRQUEx6VuPOEDlyWXEw+8nTZtmjjm9OnZs6cYCMkDdNnChQtF0Ma9PtY88Jl7ZPk4e//99416PF9rMjIydB6X6enpokfR2KyD2ubbb78VZfDpp58a/Zy2bduKngWpx4yDWG5s4QbARx99lKxVy5YtRV1GumasXbuWRo8eTU2bNhXZGLrw9VrXccnHJO8X7fv0QQ+DDEizq3DLmXZajaOjo5m2ynJxcCB9ATiViU9WfDLftm2buTdNFvgEwZVbLqPly5frfRyOy/JlZWWJVh5OV+C0wvICWanixrNZcEWO9wF6GYq7yLlVnLvYDxw4QJ9//rne1kQcl4bxzEhcllypOHbsGH3zzTc0f/58vY8fNGiQKlhg7777rqiUrFu3jqwV92BxwPD666+LMuTy5FmnOAjjv7kXRxsHA/y91nUd59utNVi4deuW+D5zo8rx48dF+XHvNTe08N/cu6ivgUU9vY57HPv27Utr1qwha9a3b1+NBqaRI0fSAw88YLBc+Jyp67hkFaljoodBBqSTNbeyqXd98v9oEa86/rLwdHjl5fFaA24BGzx4sGhZ2LNnj8HpK3ncAl/ktMsNx2VpsMD5yRyA7du3TxxjFWFjY2NUfrm14V4aTo3ZsWOH6AXTxl3wPE0yjsvy8bSV/H3nsuTeLWP5+flZ9XHJ321OCVYPWqXxHdx7w63dHJhpf595ukocl5o4uOKyXLJkiUYaNldguSx/++030WBgDGs/Lg2Vi/bUyNp1TF3HJY8VK2+aenXoYTCTa9euicE8jHNGeXDa5s2bNVJGjh49Sg8//LC5NtFi8JzEPGCPcUVYO5LmVkvOxecytmZSsMCDpHhMB58sdLUGcYqMtEYA59qrH5fcKsHPtfbjki+CHCxwCs3evXt1dunygPszZ85oVELUcbohV0Ks/bjULhdO1+IUGfUy5Yshz4MvVcw4oFA/LjkPd/v27VZ/XGqXJafU8HdavSz5uDtx4oTe8k9ISKDg4GCrPi65gsut3+o/fMzde++94m8pWOBKF1+nJXxe3Lp1qyh3xr95PJ01ny85aNUuS04p4sZR/lsKFjgvn//Xd1xyTwT3UFjzcamrXPiazOWmXi6clsi3SRO+8PHH50f1iTY2bdpU8eOyQnMqgVGioqKUhw8fVv7+++9iCkqeBov/59slPK0Yz50r4ekqeVpAnkv833//FffxnOR5eXlWXeoxMTGi7NasWSPKcsmSJeL/iIgI1WN4CtXu3bur1rNo3769WCtg586dyp9//lkZGBio7NOnjzI/P19prQoKCpT9+/cX61nwscZlKP1wGUveeOMNsbaA+poiPB3bBx98IKYKfuSRR8Qc72lpaUprxXNXP/jgg0ofHx8xXZ16Wap/xydNmqRs0qSJ6n8+LufMmaPcsWOHctmyZWJ6Qf6OZ2ZmKq0Zrxcwe/ZsUS7r168X01fyugAXLlxQPWbq1KlirQsJT1XN01W+9dZbys2bNyuHDx8u1hhRn+rWGvXo0UM5c+ZM5fbt25X//POPuM7wmj5nzpxRPeaLL74QUypKevbsKdZo4efwNatDhw7KFi1aqKb4hmKjRo0qM60qT6fM123JrVu3xForL774ojguX3jhBfE/3w6aU59rT6v6ww8/iGs8X6vYQw89JNYO2Lp1q5himaf+5Sm+1a/91mjIkCHKTz/9VFzH//77b1FXrF+/vsaU3jwdPZcl14dYdHS0eAyv+8PHJV/nefpfnna5ItDDUA24xYG72rgLjvPNfv31V/G/eksED+jp1KmT6n/Og+ZZLTjv9IcffhDTX3Eur7WPYeAVIbnsuEy4LHlKNv7/4MGDqsdwCwVP9cl4ujaeaYVXieSZA3hWms8++0w8vryVeGsz7nXh1gYuq1mzZokylH64jCU8y4/6bApc5lx23JL23XffiZxSzuk1diXe2ojTErg827VrR3PnztUoS/XvOA/O4wGlkv3794tenu+//158199++20xu5Kxq8DXVpzOxa1k/B3n6St5SkrueVE/P/KAPm7dlfD3ncuay5MH6fLYEG41t/ZVdXfv3i16WziVhtNm+PvKZan+neY01969e6v+52ORWx75OdwazrPZcI8tVs7WxGWp3brNM52przzM33luBedrDV9/+PrN//PtUKpVq1ZlVnlu2LChuN5wDyL7999/xfWc61E8nobHgPHYEi5za7Zu3Trx3Vy6dKkYt8C9BJyxop4ix1krXJbSuBnp/MgzTfFxydcvvo5XtLfGhqMGk38iAAAAAACoFdDDAAAAAAAAeiFgAAAAAAAAvRAwAAAAAACAXggYAAAAAABALwQMAAAAAACgFwIGAAAAAADQCwEDAAAAAADohYABAABUeOHD0NDQKpfInj17xEJLhvAyQLwQES/cVpXXMSVeMCotLa3G3g8AwBIgYAAAAJX333+ftm/fXuUS4RXWN23aZPAxy5YtEysMu7i4VOl1TL3y9Oeff15j7wcAYAkQMAAAgMqjjz5KrVu3rvYSKSgoEBXzTz/9VFal/+GHH9KSJUvo7t275t4UAADZsDf3BgAAgPG2bNlC7du3J1dXV7pw4YJone/bty/Z2dlpPK6wsJBOnDhBycnJ1KZNG2rVqpXO13F2dqYzZ85QgwYNqGfPnvTggw9S8+bNNR6blZVFR48eFalD/JiGDRuW2a6kpCTxGD8/P+rSpUu5n+Off/4R28zvV5HXOXDgAMXGxpKNjY14TNeuXcnLy0t1//Hjx6moqEiUiTp+TX5Onz59xP9cduHh4RQUFCTKQRIYGEj9+vWjX375hf73v/+V+zkAAKwBAgYAAAsyceJEatGihcjr79y5M507d078v2vXLnJzcxOP4fuGDRsmgommTZvSyZMnadCgQbRixQqytbXVeJ2bN2+KivmQIUNEMMApSa+++qoqwOCK9vDh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", + "image/png": "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", "text/plain": [ "
" ] @@ -498,10 +502,10 @@ "id": "c33c5672", "metadata": { "execution": { - "iopub.execute_input": "2026-06-30T16:27:49.202613Z", - "iopub.status.busy": "2026-06-30T16:27:49.202613Z", - "iopub.status.idle": "2026-06-30T16:27:49.216655Z", - "shell.execute_reply": "2026-06-30T16:27:49.216151Z" + "iopub.execute_input": "2026-08-15T06:01:57.777460Z", + "iopub.status.busy": "2026-08-15T06:01:57.776952Z", + "iopub.status.idle": "2026-08-15T06:01:57.788111Z", + "shell.execute_reply": "2026-08-15T06:01:57.788111Z" } }, "outputs": [ @@ -534,6 +538,238 @@ " f\"backend: {pg.backend}\")" ] }, + { + "cell_type": "markdown", + "id": "mb0intro", + "metadata": {}, + "source": [ + "## 7. Multi-band search: when no single band is enough\n", + "\n", + "Rubin/LSST will not hand you one dense light curve per star — it hands you six sparse ones.\n", + "Early in the survey a faint RR Lyrae may have only ~60 visits *in total*, split across\n", + "*ugrizy* over a three-year window, so no single band is solvable on its own. But they are\n", + "all the **same star with the same period**, and a multi-band search is what spends that\n", + "fact: one period, fitted jointly, with each band keeping its own mean magnitude.\n", + "\n", + "The star below is **synthetic** — the one deliberately simulated object in this notebook,\n", + "because to watch a search *fail* we have to know the true answer. Its cadence follows\n", + "`benchmarks/multiband_recovery.py`: WFD-like epoch shares (*r*/*i* deepest), an RRab-like\n", + "sine plus a 0.35-amplitude second harmonic, per-band amplitudes and mean magnitudes, and\n", + "0.20 mag of noise on every point." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "mb1simulate", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-15T06:01:57.789115Z", + "iopub.status.busy": "2026-08-15T06:01:57.789115Z", + "iopub.status.idle": "2026-08-15T06:01:57.792593Z", + "shell.execute_reply": "2026-08-15T06:01:57.792593Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "6 bands, 61 epochs over 1096 days: u=4 g=5 r=16 i=16 z=10 y=10\n" + ] + } + ], + "source": [ + "rng = np.random.default_rng(8)\n", + "\n", + "P_TRUE, SPAN, N_EPOCHS, NOISE = 0.5537, 3 * 365.25, 60, 0.20 # d, d, epochs, mag\n", + "SHARE = {\"u\": .06, \"g\": .09, \"r\": .26, \"i\": .26, \"z\": .17, \"y\": .16} # WFD epoch shares\n", + "AMP = {\"u\": 1.05, \"g\": 1.0, \"r\": .72, \"i\": .57, \"z\": .53, \"y\": .48} # amplitude scale\n", + "MEAN = {\"u\": 23.4, \"g\": 22.8, \"r\": 22.5, \"i\": 22.4, \"z\": 22.4, \"y\": 22.3} # mean mags\n", + "\n", + "bands = {}\n", + "for b, share in SHARE.items():\n", + " n = max(3, round(N_EPOCHS * share))\n", + " t = np.sort(rng.integers(0, SPAN, n) + rng.uniform(0.05, 0.45, n)) # random nights\n", + " ph = 2 * np.pi * t / P_TRUE\n", + " y = 0.7 * AMP[b] * (np.sin(ph) + 0.35 * np.sin(2 * ph)) # RRab: sine + harmonic\n", + " bands[b] = cup.LightCurve.from_arrays(t, MEAN[b] + y + rng.normal(0, NOISE, n),\n", + " np.full(n, NOISE))\n", + "\n", + "mb = cup.MultiBandLightCurve.from_light_curves(bands)\n", + "print(f\"{mb.n_bands} bands, {sum(lc.n for lc in mb.bands.values())} epochs over \"\n", + " f\"{SPAN:.0f} days: \" + \" \".join(f\"{b}={lc.n}\" for b, lc in mb.bands.items()))" + ] + }, + { + "cell_type": "markdown", + "id": "mb2gridnote", + "metadata": {}, + "source": [ + "### One band first — and mind the top of the grid\n", + "\n", + "*r* is one of the two deepest bands, with 16 of the 61 epochs. One setting is *not* optional\n", + "here: left to itself GLS stops at the pseudo-Nyquist frequency `nyquist_factor × 0.5 × N/T`,\n", + "which for 16 points spread over three years is **0.04 cycles/day** — it would never look\n", + "below a 27-day period. Sparse survey data always needs `maximum_frequency` stated\n", + "explicitly.\n", + "\n", + "The joint search is then one extra object: `MultiBandLightCurve.from_light_curves`, handed\n", + "to the same `cup.periodogram`. Its default `mb_model=\"offsets\"` is the shared-phase model of\n", + "VanderPlas & Ivezić (2015) — one sinusoid for the star, one constant per band. We draw the\n", + "spectra against *frequency* here, because that is where sampling aliases live: one cycle per\n", + "day apart." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "mb3search", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-15T06:01:57.794096Z", + "iopub.status.busy": "2026-08-15T06:01:57.793601Z", + "iopub.status.idle": "2026-08-15T06:01:57.938126Z", + "shell.execute_reply": "2026-08-15T06:01:57.937623Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "true period 0.55370 d\n", + "r band alone 0.43547 d <- wrong by 21%\n", + "all six bands 0.55372 d <- right to 0.004% ('offsets' model over ugrizy)\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "settings = cup.GLSSettings(maximum_frequency=3.0) # search down to P = 0.33 d\n", + "\n", + "pg_r = cup.periodogram(bands[\"r\"], \"GLS\", settings=settings) # one deep band, alone\n", + "pg = cup.periodogram(mb, \"GLS\", settings=settings) # all six bands jointly\n", + "\n", + "print(f\"true period {P_TRUE:.5f} d\")\n", + "print(f\"r band alone {pg_r.best_period():.5f} d <- wrong by \"\n", + " f\"{abs(pg_r.best_period() / P_TRUE - 1) * 100:.0f}%\")\n", + "print(f\"all six bands {pg.best_period():.5f} d <- right to \"\n", + " f\"{abs(pg.best_period() / P_TRUE - 1) * 100:.3f}% \"\n", + " f\"('{pg.meta['mb_model']}' model over {''.join(pg.meta['bands'])})\")\n", + "\n", + "titles = [f\"r band alone (n = {bands['r'].n})\",\n", + " f\"all six bands jointly (n = {pg.n_samples})\"]\n", + "fig, axes = plt.subplots(1, 2, figsize=(13.5, 3.4))\n", + "for ax, p, title in zip(axes, [pg_r, pg], titles, strict=True):\n", + " pk = p.best_periods(1)[0]\n", + " ax.axvline(1 / P_TRUE, color=\"k\", lw=3, alpha=.18, zorder=0,\n", + " label=f\"true P = {P_TRUE} d\")\n", + " ax.plot(p.frequency, p.power, lw=.5, color=\"#4c72b0\", zorder=2)\n", + " ax.plot(pk.frequency, pk.power, \"v\", color=\"C1\", ms=7, zorder=3,\n", + " label=f\"best P = {pk.period:.4f} d\")\n", + " ax.set(xlim=(0.2, 3.0), xlabel=\"trial frequency (cycles/day)\",\n", + " ylabel=\"GLS power\", title=title)\n", + " ax.legend(loc=\"upper left\", fontsize=8)\n", + "fig.tight_layout(); plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "mb4checks", + "metadata": {}, + "source": [ + "### Is that peak real, and is it the right one?\n", + "\n", + "`mb_fap_bootstrap` resamples each band's `(value, error)` pairs in place — every observation\n", + "*time* held fixed, so the window function survives — and reads the peak's false-alarm\n", + "probability off the null distribution of the maximum. astropy's `LombScargleMultiband`\n", + "offers no FAP at all; here the peak lands on the `1/(n+1)` floor, meaning not one resample\n", + "came near it.\n", + "\n", + "`cup.alias_diagnostics` then measures the spectral window of these six stacked cadences and\n", + "scores every frequency the sampling could confuse with the peak. A `clean` verdict means no\n", + "non-harmonic competitor gets close — the ±1 cycle/day daily aliases show up in the table,\n", + "comfortably beaten.\n", + "\n", + "Folding all six bands on the recovered period closes the loop. Subtracting each band's own\n", + "mean is exactly what the `offsets` model profiles out, and it drops six sparse curves onto\n", + "one RRab shape." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "mb5fapfold", + "metadata": { + "execution": { + "iopub.execute_input": "2026-08-15T06:01:57.939131Z", + "iopub.status.busy": "2026-08-15T06:01:57.939131Z", + "iopub.status.idle": "2026-08-15T06:01:58.115248Z", + "shell.execute_reply": "2026-08-15T06:01:58.115248Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "peak power 0.700 bootstrap FAP = 0.0050 (floor for 200 resamples: 0.0050)\n", + "null-max levels: 10% = 0.345, 1% = 0.393\n", + "\n", + "Alias check: f = 1.8059613 c/d (P = 0.55372174 d), statistic 0.699628\n", + " Rayleigh 1/T = 0.0009352 c/d; verdict: clean - no non-harmonic competitor reaches 0.70\n", + " window peaks: 1.00006 c/d (1.00), 0.591169 c/d (0.57), 2.09766 c/d (0.51), 3.29254 c/d (0.48), 1.56962 c/d (0.47)\n", + " score predicted matched sep/R relation\n", + " 0.54 2.80602 2.80611 0.10 solar-day-alias m=+1 (f_w=1.0001/d)\n", + " 0.51 0.805902 0.805996 0.10 solar-day-alias m=-1 (f_w=1.0001/d)\n", + " 0.30 1.21479 1.2147 0.10 window-alias m=-1 (f_w=0.59117/d)\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "pg = cup.periodogram(mb, \"GLS\", settings=cup.GLSSettings(\n", + " maximum_frequency=3.0, mb_fap_bootstrap=200, mb_fap_seed=0))\n", + "top = pg.best_periods(1)[0]\n", + "print(f\"peak power {top.power:.3f} bootstrap FAP = {top.extra['fap']:.4f}\"\n", + " f\" (floor for {pg.meta['fap_n_bootstrap']} resamples: \"\n", + " f\"{1 / (pg.meta['fap_n_bootstrap'] + 1):.4f})\")\n", + "print(f\"null-max levels: 10% = {pg.meta['fap_level_10pct']:.3f}, \"\n", + " f\"1% = {pg.meta['fap_level_1pct']:.3f}\\n\")\n", + "print(cup.alias_diagnostics(pg, data=mb).summary(max_rows=3))\n", + "\n", + "COLOR = {\"u\": \"#6a3d9a\", \"g\": \"#1f78b4\", \"r\": \"#33a02c\",\n", + " \"i\": \"#ff7f00\", \"z\": \"#e31a1c\", \"y\": \"#8c2d04\"}\n", + "fig, ax = plt.subplots(figsize=(7.5, 4.0))\n", + "for b, lc in mb.bands.items(): # subtracting each band's mean is what \"offsets\" fits\n", + " ax.errorbar((lc.time / top.period) % 1.0, lc.value - lc.value.mean(), lc.error,\n", + " fmt=\"o\", ms=5, lw=.7, alpha=.85, color=COLOR[b], label=b)\n", + "ax.invert_yaxis()\n", + "ax.set(xlabel=\"phase\", ylabel=\"magnitude - band mean\",\n", + " title=f\"six sparse bands, folded together on {top.period:.5f} d\")\n", + "ax.legend(ncol=6, fontsize=9, loc=\"lower center\")\n", + "fig.tight_layout(); plt.show()" + ] + }, { "cell_type": "markdown", "id": "e40ca843", diff --git a/pyproject.toml b/pyproject.toml index fab52ef..5865307 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "cuperiod" -version = "1.1.0" +version = "1.2.0" description = "Optimized, GPU-accelerated periodograms for astronomy" readme = "README.md" requires-python = ">=3.11" @@ -16,6 +16,9 @@ keywords = [ "lomb-scargle", "box-least-squares", "variable-stars", + "asteroseismology", + "pulsations", + "pre-whitening", "time-series", "gpu", "cuda", @@ -64,9 +67,18 @@ gpu = [ "nvidia-cusolver-cu12", ] pandas = ["pandas>=2.0"] -# Multicore CPU acceleration for the box search: a numba-parallel BLS that beats -# astropy's compiled BoxLeastSquares by ~20x and is auto-selected on the CPU when -# present (otherwise BLS falls back to astropy). +# LINCC-stack interoperability (cuperiod.interop): run periodograms directly on +# nested-pandas ``NestedFrame`` light curves, one row per object. The nested extension +# arrays this adapter reads (list offsets / struct fields) need a newer pyarrow than +# the core floor, so the bound is raised here only. +nested = ["nested-pandas>=0.6.10", "pyarrow>=16"] +# The same adapter against an lsdb HATS catalog (lazy, dask-partitioned). lsdb pins +# nested-pandas itself; the [nested] extra keeps the floor consistent. +lsdb = ["cuperiod[nested]", "lsdb>=0.10.0"] +# Multicore CPU acceleration: numba-parallel kernels for BLS, PDM, CE, String-Length, +# MHAOV, TLS and SuperSmoother, auto-selected as the "cpu"/"auto" backend when present +# (otherwise those methods fall back to numpy / astropy's BoxLeastSquares). GLS is +# unaffected — its CPU path is finufft. fast = ["numba>=0.59"] # Portable accelerator reaching AMD (ROCm), Intel (XPU), Apple (MPS), and a fast CPU # path. Install the wheel matching your accelerator from https://pytorch.org/ — the @@ -96,6 +108,15 @@ dev = [ "pandas>=2.0", "hypothesis>=6", "numba>=0.59", + # Exercise the LINCC interoperability adapter (tests/test_interop.py) in CI + # against the current nested-pandas line; the adapter itself stays + # 0.6.10-compatible for the lsdb (pandas-2) world. + "nested-pandas>=0.7", + # SuperSmoother reference implementations (BSD-2-Clause), test-only: the native + # kernel is pinned against them exactly (tests/test_supersmoother.py). gatspy + # ships no install_requires; its scipy/astropy needs are core deps here anyway. + "supersmoother>=0.4", + "gatspy>=0.3", # Exercise the portable torch-CPU path in CI (GPU devices auto-skip). "torch>=2.2", # Drive the Qt GUI headlessly (QT_QPA_PLATFORM=offscreen) in tests. @@ -115,6 +136,12 @@ Repository = "https://github.com/tjayasinghe/cuPeriod" Issues = "https://github.com/tjayasinghe/cuPeriod/issues" Changelog = "https://github.com/tjayasinghe/cuPeriod/blob/main/CHANGELOG.md" +# The [lsdb] extra transitively pins nested-pandas <0.7 (the pandas-2 world), +# while [dev] tests against current nested-pandas (pandas 3). Declaring them +# conflicting lets uv fork the lock instead of downgrading pandas for everyone. +[tool.uv] +conflicts = [[{ extra = "lsdb" }, { extra = "dev" }]] + [tool.hatch.build.targets.wheel] packages = ["src/cuperiod"] @@ -138,9 +165,6 @@ src = ["src", "tests"] [tool.ruff.lint] select = ["E", "F", "I", "UP", "B", "SIM", "NPY"] -# UP038 (use `X | Y` in isinstance) is deprecated upstream: the tuple form -# `isinstance(x, (A, B))` is faster at runtime, so we keep it. -ignore = ["UP038"] [tool.ruff.lint.per-file-ignores] # typer's API requires function calls (Option/Argument) in parameter defaults. @@ -173,15 +197,22 @@ module = [ "torch.*", "array_api_compat", "array_api_compat.*", + # LINCC stack (cuperiod.interop): neither ships type stubs. + "nested_pandas", + "nested_pandas.*", + "lsdb", + "lsdb.*", ] ignore_missing_imports = true -# numba >=0.66 ships py.typed, but its jit/prange decorators leave the wrapped -# callables untyped (prange trips no-untyped-call / attr-defined in a typed -# context). Skip following into it so the whole module stays Any, as before. +# numba: whether or not the installed release ships py.typed (0.66 added it), its +# jit/prange decorators leave the wrapped callables untyped (prange trips +# no-untyped-call / attr-defined in a typed context). Skip following into it and +# accept it stub-less so the module stays Any on every numba version. [[tool.mypy.overrides]] module = ["numba", "numba.*"] follow_imports = "skip" +ignore_missing_imports = true # pyarrow ships py.typed but leaves read_table/write_table untyped; skip it. [[tool.mypy.overrides]] diff --git a/src/cuperiod/__init__.py b/src/cuperiod/__init__.py index 98e8fc8..ea43f55 100644 --- a/src/cuperiod/__init__.py +++ b/src/cuperiod/__init__.py @@ -29,7 +29,10 @@ GLSSettings, MHAOVSettings, PDMSettings, + PreWhitenSettings, + SpacingSettings, StringLengthSettings, + SuperSmootherSettings, TLSSettings, ) from cuperiod.core.device import GpuInfo, free_gpu_memory, gpu_info, suggest_gpu_workers @@ -43,14 +46,45 @@ from cuperiod.core.grid import GridSpec, log_period_grid, uniform_frequency_grid from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve from cuperiod.core.result import MultiResult, Peak, Periodogram +from cuperiod.diagnostics import ( + AliasCandidate, + AliasReport, + WindowPeak, + alias_diagnostics, +) from cuperiod.methods.base import MethodInfo, get_method, list_methods, method_names +from cuperiod.multiband.fap_mb import MultibandFAP, multiband_fap +from cuperiod.prewhiten import ( + AmplitudeSpectrum, + Combination, + MultiSineFit, + PeriodSpacingSeries, + PreWhitenResult, + Sinusoid, + SpacingSpectrum, + SpectrumEngine, + amplitude_spectrum, + baluev_fap, + batch_prewhiten, + buoyancy_radius, + echelle, + find_period_spacing, + fit_multisine, + identify_combinations, + prewhiten, + spacing_spectrum, + spectral_window, +) try: __version__ = _version("cuperiod") except PackageNotFoundError: # pragma: no cover - source tree, no metadata - __version__ = "1.1.0" + __version__ = "1.2.0" __all__ = [ + "AliasCandidate", + "AliasReport", + "AmplitudeSpectrum", "BLSSettings", "BackendUnavailableError", "BatchSettings", @@ -58,6 +92,7 @@ "CESettings", "ColumnMap", "ColumnResolutionError", + "Combination", "CuPeriodError", "Domain", "GLSSettings", @@ -69,22 +104,46 @@ "MethodInfo", "MultiBandLightCurve", "MultiResult", + "MultiSineFit", + "MultibandFAP", "PDMSettings", "Peak", "Periodogram", + "PeriodSpacingSeries", + "PreWhitenResult", + "PreWhitenSettings", + "Sinusoid", + "SpacingSettings", + "SpacingSpectrum", + "SpectrumEngine", "StringLengthSettings", + "SuperSmootherSettings", "TLSSettings", "UnknownMethodError", + "WindowPeak", "__version__", + "alias_diagnostics", + "amplitude_spectrum", + "baluev_fap", "batch_periodograms", + "batch_prewhiten", "best_periods", + "buoyancy_radius", + "echelle", + "find_period_spacing", + "fit_multisine", "free_gpu_memory", "get_method", "gpu_info", + "identify_combinations", "list_methods", "log_period_grid", "method_names", + "multiband_fap", "periodogram", + "prewhiten", + "spacing_spectrum", + "spectral_window", "suggest_gpu_workers", "to_input", "uniform_frequency_grid", diff --git a/src/cuperiod/batch/io.py b/src/cuperiod/batch/io.py index 4e402af..5b74489 100644 --- a/src/cuperiod/batch/io.py +++ b/src/cuperiod/batch/io.py @@ -134,10 +134,20 @@ def load_source( *, columns: ColumnMap | None = None, domain: Domain | None = None, + band_column: str | None = None, ) -> LightCurve | MultiBandLightCurve: - """Materialize a source: return a light curve unchanged, or load it from a path.""" + """Materialize a source: return a light curve unchanged, or load it from a path. + + A file source loads as a :class:`MultiBandLightCurve` split on the band + column when ``band_column`` (or ``columns.band``) is set; otherwise as a + single-band :class:`LightCurve`. + """ if isinstance(source, (LightCurve, MultiBandLightCurve)): return source + if band_column is not None or (columns is not None and columns.band is not None): + return MultiBandLightCurve.from_file( + source, band_column=band_column, columns=columns, domain=domain + ) return LightCurve.from_file(source, columns=columns, domain=domain) diff --git a/src/cuperiod/batch/runner.py b/src/cuperiod/batch/runner.py index 65c5d98..bd8d64b 100644 --- a/src/cuperiod/batch/runner.py +++ b/src/cuperiod/batch/runner.py @@ -55,6 +55,7 @@ class _ChunkConfig: settings_map: Mapping[str, BaseSettings] columns: ColumnMap | None domain: Domain | None + band_column: str | None n_best: int store_raw: bool @@ -103,7 +104,7 @@ def _compute_one( if not method.supports_multiband: raise ValueError(f"{method.name} does not support multi-band input") grid = _multiband_grid(method, lc, settings) - return method.multiband_power(grid, lc, settings, backend) + return method.multiband_power(grid, lc, settings, backend, engine=engine) single = lc.in_domain(method.natural_domain) if method.natural_domain else lc grid = method.default_grid(single, settings) return method.power(grid, single, settings, backend, engine=engine) @@ -117,7 +118,12 @@ def _process_chunk( errors: list[tuple[str, str]] = [] for key, source in items: try: - lc = load_source(source, columns=cfg.columns, domain=cfg.domain) + lc = load_source( + source, + columns=cfg.columns, + domain=cfg.domain, + band_column=cfg.band_column, + ) for method_name in cfg.methods: method = get_method(method_name) engine = _WORKER_ENGINES.get(method.name) @@ -266,6 +272,7 @@ def batch_periodograms( settings_map=settings_map, columns=columns, domain=domain, + band_column=band_column, n_best=n_best, store_raw=store_raw, ) @@ -395,25 +402,27 @@ def _run_gpu_single( def _run_pool( chunks: list[list[InputItem]], pending: list[int], - cfg: _ChunkConfig, + cfg: Any, absorb: Any, max_workers: int, *, initializer: Any = None, initargs: tuple[Any, ...] = (), + worker: Any = None, ) -> None: # Always use "spawn". Linux's default "fork" copies the parent's already-built # native thread pools (numba / OpenBLAS / OpenMP, plus any CUDA context for the # GPU pool) into the child and deadlocks the workers. Spawn starts fresh, # thread-pinned workers (the Windows/macOS default) — see pin_worker_threads. + # ``worker`` lets a sibling batch driver (pre-whitening) reuse this pool with its + # own per-chunk function; it must be a module-level callable so spawn can pickle it. + task = worker or _process_chunk ctx = multiprocessing.get_context("spawn") with ProcessPoolExecutor( max_workers=max_workers, mp_context=ctx, initializer=initializer, initargs=initargs, ) as pool: - futures = { - pool.submit(_process_chunk, chunks[idx], cfg): idx for idx in pending - } + futures = {pool.submit(task, chunks[idx], cfg): idx for idx in pending} for future in as_completed(futures): idx = futures[future] rows, errs = future.result() diff --git a/src/cuperiod/cli/app.py b/src/cuperiod/cli/app.py index ddf7730..f78f44f 100644 --- a/src/cuperiod/cli/app.py +++ b/src/cuperiod/cli/app.py @@ -5,6 +5,8 @@ * ``run`` — one light curve, one or more methods; prints the N best periods. * ``batch`` — many light curves with CPU or GPU workers, written to Parquet/CSV. +* ``prewhiten`` — automated iterative frequency extraction for a pulsator. +* ``batch-prewhiten`` — the same over many light curves, written to Parquet/CSV. * ``methods`` — list registered methods and their backends. * ``gpu-info`` — show the CUDA GPU and suggested worker counts. * ``doctor`` — diagnose available backends, torch devices, and the precision each uses. @@ -20,15 +22,18 @@ import numpy as np import typer +from pydantic import ValidationError from cuperiod.api import periodogram from cuperiod.batch.runner import batch_periodograms from cuperiod.core.columns import ColumnMap, Domain +from cuperiod.core.config import PreWhitenSettings from cuperiod.core.device import gpu_info as _gpu_info from cuperiod.core.device import suggest_gpu_workers -from cuperiod.core.lightcurve import LightCurve +from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve from cuperiod.core.result import MultiResult, Periodogram from cuperiod.methods.base import get_method, list_methods +from cuperiod.prewhiten.result import PreWhitenResult app = typer.Typer( add_completion=False, @@ -92,7 +97,13 @@ def run( ) -> None: """Compute periodogram(s) for a single light curve and print the best periods.""" columns = _column_map(time, value, error, band) - lc = LightCurve.from_file(path, columns=columns, domain=_domain(domain)) + lc: LightCurve | MultiBandLightCurve + if band is not None: + lc = MultiBandLightCurve.from_file( + path, band_column=band, columns=columns, domain=_domain(domain) + ) + else: + lc = LightCurve.from_file(path, columns=columns, domain=_domain(domain)) result = periodogram(lc, _parse_methods(method), backend=backend) results = ( result.results if isinstance(result, MultiResult) else {result.method: result} @@ -168,6 +179,209 @@ def batch( typer.echo(f" ! {key}: {msg}") +def _prewhiten_settings( + *, + max_frequencies: int, + snr: float, + stop: str, + minimum_frequency: float | None, + maximum_frequency: float | None, + uncertainty: str, + combinations: bool, + backend: str, + store_spectra: bool = True, +) -> PreWhitenSettings: + """Build a :class:`PreWhitenSettings` from CLI options (validated by pydantic).""" + criteria = tuple(c.strip().lower() for c in stop.split(",") if c.strip()) + try: + return PreWhitenSettings( + max_frequencies=max_frequencies, + snr_threshold=snr, + stop_criteria=criteria, # type: ignore[arg-type] + minimum_frequency=minimum_frequency, + maximum_frequency=maximum_frequency, + uncertainty=uncertainty, # type: ignore[arg-type] + combinations=combinations, + backend=backend, # type: ignore[arg-type] + store_spectra=store_spectra, + ) + except ValidationError as exc: + raise typer.BadParameter(str(exc)) from exc + + +@app.command() +def prewhiten( + path: Path = typer.Argument(..., help="Light-curve file (CSV/ECSV/FITS/Parquet)."), + backend: str = typer.Option("auto", help="auto | cpu | gpu | concrete backend."), + max_frequencies: int = typer.Option( + 30, "--max-frequencies", "-n", help="Cap on extracted components." + ), + snr: float = typer.Option(4.0, "--snr", help="Breger signal-to-noise threshold."), + stop: str = typer.Option( + "snr", "--stop", help="Stopping criteria (comma-sep): snr,fap,bic,amplitude." + ), + minimum_frequency: float | None = typer.Option( + None, "--fmin", help="Lowest trial frequency (cycles/day)." + ), + maximum_frequency: float | None = typer.Option( + None, "--fmax", help="Highest trial frequency (cycles/day)." + ), + uncertainty: str = typer.Option( + "covariance", help="covariance | analytic | bootstrap." + ), + combinations: bool = typer.Option( + True, + "--combinations/--no-combinations", + help="Identify combination frequencies.", + ), + spacing: bool = typer.Option( + False, "--spacing", help="Also search for a g-mode period-spacing pattern." + ), + time: str | None = typer.Option(None, help="Time column name override."), + value: str | None = typer.Option(None, help="Value column name override."), + error: str | None = typer.Option(None, help="Error column name override."), + domain: str | None = typer.Option(None, help="magnitude | flux."), + out: Path | None = typer.Option(None, help="Write the full solution as JSON here."), + csv_out: Path | None = typer.Option( + None, "--csv", help="Write the component table as CSV here." + ), + save_spectrum: Path | None = typer.Option( + None, "--save-spectrum", help="Write the amplitude spectra to this .npz." + ), +) -> None: + """Extract a pulsator's frequency solution by automated iterative pre-whitening.""" + from cuperiod.prewhiten import find_period_spacing + from cuperiod.prewhiten import prewhiten as _prewhiten + + columns = _column_map(time, value, error, None) + lc = LightCurve.from_file(path, columns=columns, domain=_domain(domain)) + settings = _prewhiten_settings( + max_frequencies=max_frequencies, + snr=snr, + stop=stop, + minimum_frequency=minimum_frequency, + maximum_frequency=maximum_frequency, + uncertainty=uncertainty, + combinations=combinations, + backend=backend, + ) + result = _prewhiten(lc, settings=settings) + typer.echo(result.summary()) + + if spacing: + independent = result.independent() + series = ( + find_period_spacing( + np.asarray([c.period for c in independent], dtype=np.float64), + np.asarray([c.amplitude for c in independent], dtype=np.float64), + ) + if len(independent) >= 4 + else None + ) + typer.echo("") + typer.echo( + series.summary() + if series is not None + else "Period spacing: no regular series found." + ) + + if out is not None: + out.write_text( + json.dumps(_json_safe(result.to_dict()), indent=2, allow_nan=False), + encoding="utf-8", + ) + typer.echo(f"\nWrote {out}") + if csv_out is not None: + _write_component_csv(result, csv_out) + typer.echo(f"Wrote {csv_out}") + if save_spectrum is not None: + arrays: dict[str, np.ndarray] = {} + if result.spectrum is not None: + arrays["frequency"] = result.spectrum.frequency + arrays["amplitude"] = result.spectrum.amplitude + if result.residual_spectrum is not None: + arrays["residual_amplitude"] = result.residual_spectrum.amplitude + if result.window is not None: + arrays["window_amplitude"] = result.window.amplitude + np.savez_compressed(save_spectrum, **arrays) # type: ignore[arg-type] + typer.echo(f"Wrote {save_spectrum}") + + +def _write_component_csv(result: PreWhitenResult, path: Path) -> None: + """Write one row per extracted component (the frequency-solution table).""" + import csv + + rows = result.to_table() + fields = list(rows[0]) if rows else ["rank", "label", "frequency", "amplitude"] + with path.open("w", newline="", encoding="utf-8") as fh: + writer = csv.DictWriter(fh, fieldnames=fields) + writer.writeheader() + writer.writerows(rows) + + +@app.command(name="batch-prewhiten") +def batch_prewhiten_cmd( + inputs: str = typer.Argument(..., help="Glob, directory, or file of light curves."), + out: Path = typer.Option(..., "--out", help="Output .parquet/.csv file or dir."), + device: str = typer.Option("cpu", help="cpu | gpu."), + backend: str = typer.Option("auto", help="auto | cpu | gpu | concrete backend."), + workers: int | None = typer.Option(None, help="Worker count (None = auto)."), + max_frequencies: int = typer.Option( + 30, "--max-frequencies", "-n", help="Cap on extracted components." + ), + snr: float = typer.Option(4.0, "--snr", help="Breger signal-to-noise threshold."), + stop: str = typer.Option("snr", "--stop", help="Stopping criteria (comma-sep)."), + minimum_frequency: float | None = typer.Option( + None, "--fmin", help="Lowest trial frequency (cycles/day)." + ), + maximum_frequency: float | None = typer.Option( + None, "--fmax", help="Highest trial frequency (cycles/day)." + ), + uncertainty: str = typer.Option( + "covariance", help="covariance | analytic | bootstrap." + ), + combinations: bool = typer.Option( + True, "--combinations/--no-combinations", help="Identify combinations." + ), + time: str | None = typer.Option(None, help="Time column name override."), + value: str | None = typer.Option(None, help="Value column name override."), + error: str | None = typer.Option(None, help="Error column name override."), + domain: str | None = typer.Option(None, help="magnitude | flux."), + resume: bool = typer.Option(True, "--resume/--no-resume", help="Skip done chunks."), +) -> None: + """Pre-whiten many light curves; writes one row per extracted component.""" + from cuperiod.prewhiten import batch_prewhiten as _batch_prewhiten + + settings = _prewhiten_settings( + max_frequencies=max_frequencies, + snr=snr, + stop=stop, + minimum_frequency=minimum_frequency, + maximum_frequency=maximum_frequency, + uncertainty=uncertainty, + combinations=combinations, + backend=backend, + store_spectra=False, + ) + summary = _batch_prewhiten( + inputs, + settings=settings, + backend=backend, + device=device, + workers=workers, + columns=_column_map(time, value, error, None), + domain=_domain(domain), + sink=out, + resume=resume, + ) + typer.echo( + f"Wrote {summary.n_done} component rows from {summary.n_inputs} inputs " + f"({summary.n_skipped} skipped, {summary.n_failed} failed) -> {summary.sink}" + ) + for key, msg in summary.errors[:10]: + typer.echo(f" ! {key}: {msg}") + + @app.command() def methods() -> None: """List registered periodogram methods and their backends.""" diff --git a/src/cuperiod/core/config.py b/src/cuperiod/core/config.py index 135d7ea..93a702a 100644 --- a/src/cuperiod/core/config.py +++ b/src/cuperiod/core/config.py @@ -57,6 +57,15 @@ def _check_bounds(self) -> Self: self.minimum_frequency, self.maximum_frequency, "minimum_frequency", "maximum_frequency", ) + if ( + self.mb_model == "flex" + and self.mb_nterms_base == 0 + and self.mb_nterms_band == 0 + ): + raise ValueError( + "flex multi-band model: at least one of mb_nterms_base and " + "mb_nterms_band must be greater than 0" + ) return self minimum_frequency: float | None = Field( @@ -76,6 +85,44 @@ def _check_bounds(self) -> Self: fit_mean: bool = Field( default=True, description="Floating-mean (generalized) Lomb-Scargle." ) + mb_model: Literal["offsets", "perband", "flex"] = Field( + default="offsets", + description=( + "Multi-band model: a shared sinusoid with per-band offsets " + "('offsets', the VanderPlas & Ivezić shared-phase (1,0) model), " + "independent per-band sinusoids combined with chi2_0 weights " + "('perband', their multi-phase (0,1) model, eq. 23), or the " + "flexible regularized model with per-band harmonics ('flex')." + ), + ) + mb_nterms_base: int = Field( + default=1, ge=0, description="Flex model: shared (base) harmonic terms." + ) + mb_nterms_band: int = Field( + default=1, ge=0, description="Flex model: per-band harmonic terms." + ) + mb_reg_base: float | None = Field( + default=None, description="Flex model: ridge on the base terms (None = 0)." + ) + mb_reg_band: float | None = Field( + default=1e-6, description="Flex model: ridge on the per-band terms." + ) + mb_regularize_by_trace: bool = Field( + default=True, + description="Flex model: scale the ridge by the normal-matrix trace.", + ) + mb_fap_bootstrap: int = Field( + default=0, + ge=0, + description=( + "Within-band bootstrap resamples for multi-band false-alarm " + "probabilities (0 disables; the smallest resolvable FAP is " + "1/(n+1))." + ), + ) + mb_fap_seed: int = Field( + default=0, description="Seed for the multi-band FAP bootstrap." + ) n_peaks: int = Field(default=10, ge=1, description="Default stored peak count.") peak_separation_rayleigh: float = Field( default=3.0, gt=0.0, description="Min peak separation in Rayleigh widths." @@ -224,6 +271,92 @@ def _check_bounds(self) -> Self: ) +class SuperSmootherSettings(_DeviceSettings): + """Settings for the SuperSmoother (Friedman variable-span) periodogram.""" + + model_config = SettingsConfigDict( + env_prefix="CUPERIOD_SUPERSMOOTHER_", extra="forbid" + ) + + @model_validator(mode="after") + def _check_bounds(self) -> Self: + _require_lt( + self.minimum_frequency, self.maximum_frequency, + "minimum_frequency", "maximum_frequency", + ) + spans = tuple(self.primary_spans) + if any(not (0.0 < s <= 1.0) for s in spans): + raise ValueError(f"primary_spans must lie in (0, 1], got {spans}") + if any(b <= a for a, b in zip(spans, spans[1:], strict=False)): + raise ValueError(f"primary_spans must be strictly increasing, got {spans}") + return self + + minimum_frequency: float | None = Field( + default=None, + description="Lowest trial frequency (cycles/day); None -> 1/baseline.", + ) + maximum_frequency: float | None = Field( + default=None, + description="Highest trial frequency (cycles/day); None -> pseudo-Nyquist.", + ) + nyquist_factor: int = Field( + default=5, ge=1, description="Pseudo-Nyquist multiple when max is None." + ) + samples_per_peak: int = Field( + default=5, ge=1, description="Frequency oversampling factor." + ) + primary_spans: tuple[float, ...] = Field( + default=(0.05, 0.2, 0.5), + min_length=1, + description=( + "Candidate span fractions (Friedman's tweeter/midrange/woofer); the " + "best span is chosen per phase point by cross-validation." + ), + ) + middle_span: float = Field( + default=0.2, + gt=0.0, + le=1.0, + description="Span used to smooth the CV residuals and the chosen spans.", + ) + final_span: float = Field( + default=0.05, + gt=0.0, + le=1.0, + description="Span of the final smoothing pass over the blended curve.", + ) + bass_enhancement: float | None = Field( + default=None, + ge=0.0, + le=10.0, + description=( + "Friedman's alpha: pull chosen spans toward the largest primary span " + "(0 = none, 10 = always the largest). None disables the adjustment." + ), + ) + n_peaks: int = Field(default=10, ge=1, description="Default stored peak count.") + peak_separation_rayleigh: float = Field( + default=3.0, gt=0.0, description="Min peak separation in Rayleigh widths." + ) + min_detections: int = Field( + default=20, ge=3, description="Skip if fewer finite points." + ) + backend: Literal[ + "auto", "cpu", "gpu", "numba", "numpy", "cupy", "torch" + ] = Field(default="auto", description="Compute backend.") + batch_periods: int = Field( + default=0, + ge=0, + description=( + "Trial periods per vectorized batch; 0 auto-sizes the batch from a " + "transient-memory budget (much larger on device backends)." + ), + ) + downsample_points: int = Field( + default=2000, ge=2, description="Stored downsampled-spectrum size." + ) + + class MHAOVSettings(_DeviceSettings): """Settings for the multiharmonic Analysis of Variance (MHAOV) periodogram.""" @@ -265,7 +398,12 @@ def _check_bounds(self) -> Self: "auto", "cpu", "gpu", "numba", "numpy", "cupy", "torch" ] = Field(default="auto", description="Compute backend.") batch_periods: int = Field( - default=512, ge=1, description="Trial frequencies per vectorized batch." + default=0, + ge=0, + description=( + "Trial frequencies per vectorized batch; 0 auto-sizes the batch from " + "a transient-memory budget (much larger on device backends)." + ), ) downsample_points: int = Field( default=2000, ge=2, description="Stored downsampled-spectrum size." @@ -436,6 +574,232 @@ def _check_bounds(self) -> Self: ) +class PreWhitenSettings(_DeviceSettings): + """Settings for automated iterative pre-whitening of a pulsator. + + The defaults are the conservative, widely-cited choices: a search band from ``1/T`` + to the pseudo-Nyquist frequency — floored at 50 cycles/day so short-period + pulsators stay in band on sparse ground-based sampling — oversampled ten times, + extraction until a component fails the Breger et al. (1993) signal-to-noise 4.0 + criterion, a Loumos & Deeming (1978) resolution guard of 1.5 Rayleigh widths + between components, and least-squares covariance uncertainties inflated by the + Schwarzenberg-Czerny correlation factor. + """ + + model_config = SettingsConfigDict(env_prefix="CUPERIOD_PREWHITEN_", extra="forbid") + + @model_validator(mode="after") + def _check_bounds(self) -> Self: + _require_lt( + self.minimum_frequency, self.maximum_frequency, + "minimum_frequency", "maximum_frequency", + ) + return self + + # -- search grid ------------------------------------------------------------- + minimum_frequency: float | None = Field( + default=None, + description="Lowest trial frequency (cycles/day); None -> 1/baseline.", + ) + maximum_frequency: float | None = Field( + default=None, + description=( + "Highest trial frequency (cycles/day); " + "None -> pseudo-Nyquist, floored at 50." + ), + ) + nyquist_factor: int = Field( + default=5, + ge=1, + description="Pseudo-Nyquist multiple when max is None (as the periodograms).", + ) + samples_per_peak: int = Field( + default=10, ge=1, description="Frequency oversampling factor." + ) + normalization: Literal["lsq", "dft"] = Field( + default="lsq", + description="Amplitude convention: least-squares, or classical Deeming DFT.", + ) + + # -- extraction -------------------------------------------------------------- + max_frequencies: int = Field( + default=30, ge=0, description="Hard cap on extracted components." + ) + min_separation_rayleigh: float = Field( + default=1.5, + ge=0.0, + description="Resolution guard between components, in Rayleigh widths.", + ) + refine_bound_rayleigh: float = Field( + default=1.0, + gt=0.0, + description="How far a frequency may move when refined, in Rayleigh widths.", + ) + fit_mean: bool = Field( + default=True, description="Fit a free constant term alongside the sinusoids." + ) + + # -- stopping criteria ------------------------------------------------------- + stop_criteria: tuple[Literal["snr", "fap", "bic", "amplitude"], ...] = Field( + default=("snr",), + description="Criteria a new component must pass; failing one stops the run.", + ) + snr_threshold: float = Field( + default=4.0, gt=0.0, description="Minimum Breger signal-to-noise to accept." + ) + snr_window: float = Field( + default=1.0, + gt=0.0, + description="Half-width (cycles/day) of the residual noise box.", + ) + noise_estimator: Literal["mean", "median"] = Field( + default="mean", + description="Box noise statistic; 'mean' matches the classical S/N scale.", + ) + fap_threshold: float = Field( + default=1e-3, gt=0.0, le=1.0, description="Maximum accepted false-alarm prob." + ) + min_delta_bic: float = Field( + default=10.0, + ge=0.0, + description="Minimum BIC improvement required of a new component.", + ) + min_amplitude: float | None = Field( + default=None, description="Absolute amplitude floor; None disables the check." + ) + prune: bool = Field( + default=True, + description=( + "Re-check significance after the final fit and drop failures; the re-check " + "is the S/N test, so it runs only when 'snr' is among stop_criteria." + ), + ) + blend_tolerance: float = Field( + default=2.0, + gt=1.0, + description=( + "Flag a component as blended when its fitted amplitude and the spectrum's " + "own reading differ by more than this factor either way." + ), + ) + + # -- fitting ----------------------------------------------------------------- + refine: Literal["none", "last", "cyclic", "simultaneous"] = Field( + default="last", description="Per-iteration frequency-refinement policy." + ) + sweeps: int = Field( + default=1, ge=1, description="Cyclic sweeps per iteration and per final polish." + ) + final_refine: bool = Field( + default=True, + description="Polish the accepted solution with a simultaneous (or cyclic) fit.", + ) + max_simultaneous: int = Field( + default=60, + ge=1, + description="Largest component count given a simultaneous final polish.", + ) + max_nfev: int = Field( + default=200, ge=1, description="Optimiser evaluation cap per non-linear solve." + ) + + # -- uncertainties ----------------------------------------------------------- + uncertainty: Literal["covariance", "analytic", "bootstrap"] = Field( + default="covariance", description="Uncertainty estimator." + ) + correlation_correction: bool = Field( + default=True, + description=( + "Inflate errors by sqrt(D) for correlated residuals " + "(not applied to the bootstrap estimator)." + ), + ) + n_resamples: int = Field( + default=200, + ge=2, + description="Bootstrap replicates when uncertainty='bootstrap'.", + ) + seed: int = Field(default=0, description="Seed for the bootstrap resampling.") + + # -- combination frequencies ------------------------------------------------- + combinations: bool = Field( + default=True, description="Identify combination frequencies and harmonics." + ) + combination_max_order: int = Field( + default=2, ge=1, description="Largest sum|n_i| considered." + ) + combination_parents: int = Field( + default=5, ge=1, description="Highest-amplitude components usable as parents." + ) + combination_tolerance_rayleigh: float = Field( + default=0.25, ge=0.0, description="Tolerance floor in Rayleigh widths." + ) + combination_sigma: float = Field( + default=3.0, ge=0.0, description="Tolerance in propagated sigma_f units." + ) + + # -- execution --------------------------------------------------------------- + min_detections: int = Field( + default=20, ge=4, description="Skip if fewer finite points." + ) + backend: Literal[ + "auto", "cpu", "gpu", "finufft", "cufinufft", "torch", "numpy" + ] = Field(default="auto", description="Amplitude-spectrum backend.") + nufft_eps: float = Field( + default=1e-9, gt=0.0, description="NUFFT relative tolerance." + ) + direct_freq_batch: int = Field( + default=4096, ge=1, description="Frequency chunk for the direct (torch) path." + ) + store_spectra: bool = Field( + default=True, + description="Keep the full initial and residual spectra in the result.", + ) + downsample_points: int = Field( + default=2000, ge=2, description="Stored downsampled-spectrum size." + ) + + +class SpacingSettings(BaseSettings): + """Settings for the g-mode period-spacing tools.""" + + model_config = SettingsConfigDict(env_prefix="CUPERIOD_SPACING_", extra="forbid") + + minimum_spacing: float | None = Field( + default=None, + description="Shortest trial spacing (days); None -> half the smallest gap.", + ) + maximum_spacing: float | None = Field( + default=None, + description="Longest trial spacing (days); None -> the full period range.", + ) + oversample: int = Field( + default=20, ge=1, description="Oversampling of the spacing search grid." + ) + amplitude_weighted: bool = Field( + default=True, description="Weight the comb response by mode amplitude." + ) + max_gap: int = Field( + default=3, + ge=1, + description=( + "Largest number of radial orders one observed step may span " + "(1 = consecutive; N bridges up to N-1 missing modes)." + ), + ) + tolerance: float = Field( + default=0.25, + gt=0.0, + description="Series membership tolerance as a fraction of the local spacing.", + ) + min_length: int = Field( + default=4, ge=3, description="Shortest reported period-spacing series." + ) + ell: int = Field( + default=1, ge=1, description="Spherical degree assumed for the buoyancy radius." + ) + + class BatchSettings(BaseSettings): """Settings for batch processing of many light curves.""" @@ -465,6 +829,9 @@ class BatchSettings(BaseSettings): "GLSSettings", "MHAOVSettings", "PDMSettings", + "PreWhitenSettings", + "SpacingSettings", "StringLengthSettings", + "SuperSmootherSettings", "TLSSettings", ] diff --git a/src/cuperiod/core/lightcurve.py b/src/cuperiod/core/lightcurve.py index 6b7df96..019ae57 100644 --- a/src/cuperiod/core/lightcurve.py +++ b/src/cuperiod/core/lightcurve.py @@ -15,7 +15,7 @@ from __future__ import annotations from collections.abc import Callable, Mapping -from dataclasses import dataclass, field +from dataclasses import dataclass, field, replace from pathlib import Path from typing import TYPE_CHECKING, Any @@ -305,6 +305,8 @@ def from_dataframe( """ names, _ = _adapt_table(df) cmap = columns or ColumnMap(band=band_column) + if band_column is not None and cmap.band is None: + cmap = replace(cmap, band=band_column) resolved = cmap.resolve(names, domain=domain) if resolved.band is None: raise ColumnResolutionError( @@ -319,6 +321,58 @@ def from_dataframe( ) return cls(bands=bands, meta=dict(meta or {})) + @classmethod + def from_file( + cls, + path: str | Path, + *, + band_column: str | None = None, + columns: ColumnMap | None = None, + domain: Domain | None = None, + meta: Mapping[str, Any] | None = None, + ) -> MultiBandLightCurve: + """Build from one long-format table file split on a band column. + + Parameters + ---------- + path : str or Path + CSV/ECSV/FITS/Parquet/ASCII file with a band/filter column and shared + time/value/error columns. + band_column : str, optional + Band column name; auto-detected from the standard filter-column names + if ``None``. + columns, domain, meta + As for :meth:`LightCurve.from_file`. + + Raises + ------ + ColumnResolutionError + If no band column can be resolved. + """ + table = _read_table_object(Path(path)) + names, _ = _adapt_table(table) + cmap = columns or ColumnMap(band=band_column) + if band_column is not None and cmap.band is None: + cmap = replace(cmap, band=band_column) + resolved = cmap.resolve(names, domain=domain) + if resolved.band is None: + raise ColumnResolutionError( + "could not resolve a band column; pass band_column=... " + f"or ColumnMap(band=...). Available columns: {names}" + ) + labels = np.array( + [_band_label(v) for v in _raw_column(table, resolved.band)], dtype=object + ) + bands: dict[str, LightCurve] = {} + for label in dict.fromkeys(labels): # first-appearance order + sub = _row_subset(table, labels == label) + names_s, getter_s = _adapt_table(sub) + bands[str(label)] = LightCurve._from_table( + names_s, getter_s, columns, resolved.domain, {"band": str(label)} + ) + base_meta = {"source": str(path), **dict(meta or {})} + return cls(bands=bands, meta=base_meta) + def finite(self) -> MultiBandLightCurve: """Return a copy with each band's non-finite points removed.""" return MultiBandLightCurve( @@ -391,26 +445,57 @@ def _adapt_table(obj: Any) -> tuple[list[str], Callable[[str], FloatArray]]: raise TypeError(f"unsupported table type: {type(obj)!r}") -def _read_table_file(path: Path) -> tuple[list[str], Callable[[str], FloatArray]]: - """Read a tabular file into ``(column_names, getter)`` by extension.""" +def _read_table_object(path: Path) -> Any: + """Read a tabular file into a table object (pyarrow or astropy) by extension.""" suffix = path.suffix.lower() if suffix in {".parquet", ".pq"}: import pyarrow.parquet as pq - return _adapt_table(pq.read_table(path)) + return pq.read_table(path) from astropy.table import Table if suffix in {".fits", ".fit", ".fz"}: - return _adapt_table(Table.read(path)) + return Table.read(path) if suffix in {".csv"}: - return _adapt_table(Table.read(path, format="ascii.csv")) + return Table.read(path, format="ascii.csv") if suffix in {".ecsv"}: - return _adapt_table(Table.read(path, format="ascii.ecsv")) + return Table.read(path, format="ascii.ecsv") if suffix in {".tsv", ".tab"}: - return _adapt_table(Table.read(path, format="ascii.tab")) + return Table.read(path, format="ascii.tab") # .dat/.txt and unknowns: let astropy guess the ASCII flavor. - return _adapt_table(Table.read(path, format="ascii")) + return Table.read(path, format="ascii") + + +def _read_table_file(path: Path) -> tuple[list[str], Callable[[str], FloatArray]]: + """Read a tabular file into ``(column_names, getter)`` by extension.""" + return _adapt_table(_read_table_object(path)) + + +def _raw_column(obj: Any, name: str) -> np.ndarray: + """A table column as-is (labels stay strings — no float coercion).""" + if hasattr(obj, "column_names") and hasattr(obj, "column"): # pyarrow + return np.asarray(obj.column(name).to_numpy(zero_copy_only=False)) + values = obj[name] + if hasattr(values, "filled"): + values = values.filled() # type: ignore[attr-defined] + return np.asarray(values) + + +def _row_subset(obj: Any, mask: np.ndarray) -> Any: + """The rows of a table object selected by a boolean ``mask``.""" + if hasattr(obj, "column_names") and hasattr(obj, "column"): # pyarrow + import pyarrow as pa + + return obj.filter(pa.array(mask)) + return obj[mask] + + +def _band_label(value: Any) -> str: + """A band cell as a clean string (FITS byte strings decoded).""" + if isinstance(value, bytes): + return value.decode("utf-8", errors="replace").strip() + return str(value).strip() __all__ = ["LightCurve", "MultiBandLightCurve"] diff --git a/src/cuperiod/diagnostics.py b/src/cuperiod/diagnostics.py new file mode 100644 index 0000000..1637908 --- /dev/null +++ b/src/cuperiod/diagnostics.py @@ -0,0 +1,643 @@ +"""Alias diagnostics: is the best peak the true frequency, or a window sidelobe? + +Ground-based sampling is not a free choice. A survey observes at night, from one +longitude, when the target is up and the moon is down, which imprints a comb of strong +peaks on the *spectral window* :math:`W(f) = \\sum_j w_j e^{2\\pi i f t_j}` — one per +sidereal day, per synodic month, per year. Because irregular sampling convolves the +true spectrum with that window, a single sinusoid at ``f_true`` appears in the +periodogram as a whole family of peaks at + +.. math:: + + f = f_{\\rm true} \\pm m f_{\\rm w}, + +and nothing in the periodogram itself says which member of the family is the star. +Choosing the tallest is a convention, not a measurement: for sparse cadences the +1 cycle/day alias routinely comes within a few percent of the true peak, and a period +quoted without an alias check is a period a referee will ask about. + +This module runs that check. It measures the window of *this* light curve's sampling +(no assumed cadence — :func:`cuperiod.spectral_window` on the actual timestamps), reads +off its strongest peaks, predicts where each would place an alias of the frequency being +examined, and reports how well the periodogram actually supports each prediction. The +output is one :class:`AliasReport`, whose :meth:`~AliasReport.summary` prints the +competitor list a period-search paper is expected to show. + +Two conventions make the report readable at a glance: + +**One score, both objective senses.** Every candidate carries a ``score`` normalized so +that ``1.0`` means "the periodogram likes this frequency exactly as much as the one +being diagnosed" and ``0.0`` means "as bad as the grid gets" — for maximized statistics +(GLS/BLS/MHAOV) and minimized ones (PDM/CE/string-length) alike. See +:class:`AliasCandidate`. + +**Harmonics are not ambiguity.** ``2 f_true`` is present in the periodogram of any +non-sinusoidal signal and is expected structure, so harmonics and subharmonics are +reported but never set :attr:`AliasReport.ambiguous`. + +Examples +-------- +>>> pg = cup.periodogram((t, mag, err), "GLS") # doctest: +SKIP +>>> report = cup.alias_diagnostics(pg, (t, mag, err)) # doctest: +SKIP +>>> print(report.summary()) # doctest: +SKIP +>>> report.ambiguous # doctest: +SKIP +True +""" + +from __future__ import annotations + +from collections.abc import Callable, Sequence +from dataclasses import dataclass +from typing import Any, Final + +import numpy as np + +from cuperiod.core._typing import FloatArray +from cuperiod.core.grid import uniform_frequency_grid +from cuperiod.core.lightcurve import MultiBandLightCurve +from cuperiod.core.peaks import local_maxima, select_top_peaks +from cuperiod.core.result import Periodogram + +#: Sidereal day (cycles/day) — the true spacing of the nightly observing comb. +SIDEREAL_DAY_CPD: Final = 1.00273790935 + +#: Solar day (cycles/day) — the spacing an evenly-scheduled queue imprints. +SOLAR_DAY_CPD: Final = 1.0 + +#: Synodic (lunar) month in cycles/day — moon-avoidance scheduling. +SYNODIC_MONTH_CPD: Final = 1.0 / 29.530589 + +#: Sidereal year in cycles/day — the seasonal visibility window. +YEAR_CPD: Final = 1.0 / 365.25636 + +#: The classic ground-based window frequencies, used as ``(label, frequency)`` pairs +#: both to name measured window peaks and as the fallback suspects when no light curve +#: is supplied to :func:`alias_diagnostics`. +CLASSIC_WINDOW_FREQUENCIES: Final[tuple[tuple[str, float], ...]] = ( + ("sidereal-day", SIDEREAL_DAY_CPD), + ("solar-day", SOLAR_DAY_CPD), + ("synodic-month", SYNODIC_MONTH_CPD), + ("year", YEAR_CPD), +) + +#: Oversampling of the spectral-window grid (samples per Rayleigh width). +_WINDOW_SAMPLES_PER_PEAK: Final = 10 + +#: Window samples below this many Rayleigh widths belong to the DC peak at ``f -> 0``. +_DC_RAYLEIGH: Final = 2.0 + +#: How far a predicted alias may sit from a periodogram optimum and still count as +#: matched, in Rayleigh widths. +_MATCH_RAYLEIGH: Final = 3.0 + + +@dataclass(frozen=True) +class WindowPeak: + """One peak of the spectral window of the sampling. + + Attributes + ---------- + frequency : float + Peak frequency in cycles/day. This is an alias *spacing*, not a candidate + period: it is the offset by which the window replicates every real signal. + amplitude : float + ``|W(f)|`` at the peak (dimensionless, ``<= 1``; ``|W| -> 1`` at ``f = 0``). + NaN for the classic suspects used when no light curve was supplied. + amplitude_ratio : float + ``amplitude`` divided by that of the strongest non-DC window peak, so the + leading peak is ``1.0``. NaN when the amplitudes are unknown. + """ + + frequency: float + amplitude: float + amplitude_ratio: float + + +@dataclass(frozen=True) +class AliasCandidate: + """A frequency the sampling could confuse with the one being diagnosed. + + Attributes + ---------- + kind : str + What relation this candidate has to the examined frequency ``f0``, e.g. + ``"sidereal-day-alias m=+1 (f_w=1.0027/d)"``, ``"window-alias m=-2 + (f_w=0.033849/d)"``, ``"harmonic n=2"``, ``"subharmonic n=3"``. + frequency : float + The *predicted* frequency (cycles/day) — where this relation says a competing + peak should be. + matched_frequency : float + Frequency of the nearest local optimum of the periodogram within + ``3/baseline`` of ``frequency``, or NaN when the periodogram has no optimum + there (which is itself the informative outcome: the alias is not populated). + power : float + The periodogram statistic at ``matched_frequency`` (NaN when unmatched). + score : float + The competitor's strength on a scale where ``1.0`` is "as good as the examined + peak" and ``0.0`` is "as bad as this periodogram gets"; ``0.0`` exactly when + unmatched. For ``objective_sense="max"`` it is ``power / best_power``; for + ``objective_sense="min"``, where a *smaller* statistic is better, it is + ``(worst - power) / (worst - best_power)`` with ``worst`` the largest finite + value on the grid. Scores above ``1.0`` are possible and mean the competitor + beats the frequency being diagnosed. + separation_rayleigh : float + ``|matched_frequency - frequency|`` in Rayleigh widths ``1/baseline`` (NaN when + unmatched). Much above ~1 means the match is loose. + """ + + kind: str + frequency: float + matched_frequency: float + power: float + score: float + separation_rayleigh: float + + @property + def matched(self) -> bool: + """Whether a periodogram optimum was found near the predicted frequency.""" + return bool(np.isfinite(self.matched_frequency)) + + @property + def is_harmonic(self) -> bool: + """Whether this is a harmonic/subharmonic rather than a sampling alias.""" + return self.kind.startswith(("harmonic", "subharmonic")) + + +@dataclass(frozen=True) +class AliasReport: + """The alias verdict for one periodogram peak. + + Attributes + ---------- + best_frequency : float + The frequency that was diagnosed (cycles/day). + best_power : float + The periodogram statistic there; the reference every score is measured against. + rayleigh : float + Frequency resolution ``1/baseline`` (cycles/day). + window_peaks : tuple of WindowPeak + The strongest peaks of the sampling's spectral window, descending in amplitude + (the classic suspects when no light curve was supplied). + candidates : tuple of AliasCandidate + Every predicted competitor, sorted by :attr:`AliasCandidate.score` descending. + ambiguous : bool + True when some *non-harmonic* candidate scores at least ``threshold`` — i.e. + the sampling admits another frequency the data support about as well, and the + period should not be quoted without a caveat. + threshold : float + The score at which a competitor is called serious. + """ + + best_frequency: float + best_power: float + rayleigh: float + window_peaks: tuple[WindowPeak, ...] + candidates: tuple[AliasCandidate, ...] + ambiguous: bool + threshold: float + + @property + def best_period(self) -> float: + """The diagnosed frequency as a period in days.""" + return 1.0 / self.best_frequency if self.best_frequency != 0.0 else float("inf") + + def summary(self, *, max_rows: int = 5) -> str: + """A short human-readable report, one competitor per line. + + Parameters + ---------- + max_rows : int, default 5 + Maximum number of candidates listed. + + Returns + ------- + str + Multi-line text suitable for ``print()``. + """ + verdict = ( + f"AMBIGUOUS - a non-harmonic competitor scores >= {self.threshold:.2f}" + if self.ambiguous + else f"clean - no non-harmonic competitor reaches {self.threshold:.2f}" + ) + lines = [ + f"Alias check: f = {self.best_frequency:.8g} c/d " + f"(P = {self.best_period:.8g} d), statistic {self.best_power:.6g}", + f" Rayleigh 1/T = {self.rayleigh:.4g} c/d; verdict: {verdict}", + f" window peaks: {_format_window_peaks(self.window_peaks)}", + ] + if not self.candidates: + lines.append(" competitors: none in range") + return "\n".join(lines) + lines.append( + f" {'score':>6} {'predicted':>12} {'matched':>12} {'sep/R':>7} relation" + ) + for candidate in self.candidates[:max_rows]: + matched = ( + f"{candidate.matched_frequency:>12.6g}" + if candidate.matched + else f"{'-':>12}" + ) + separation = ( + f"{candidate.separation_rayleigh:>7.2f}" + if candidate.matched + else f"{'-':>7}" + ) + lines.append( + f" {candidate.score:>6.2f} {candidate.frequency:>12.6g} " + f"{matched} {separation} {candidate.kind}" + ) + return "\n".join(lines) + + +def _format_window_peaks(peaks: Sequence[WindowPeak]) -> str: + """One-line rendering of the window peaks for :meth:`AliasReport.summary`.""" + if not peaks: + return "none" + parts = [] + for peak in peaks: + ratio = ( + f" ({peak.amplitude_ratio:.2f})" + if np.isfinite(peak.amplitude_ratio) + else "" + ) + parts.append(f"{peak.frequency:.6g} c/d{ratio}") + return ", ".join(parts) + + +def _sampling(data: Any) -> tuple[FloatArray, FloatArray | None]: + """``(time, error)`` of any accepted light-curve input, bands stacked.""" + from cuperiod.api import to_input + + lc = to_input(data) + if isinstance(lc, MultiBandLightCurve): + time, _value, error, _band = lc.finite().stacked() + return time, error + finite = lc.finite() + return finite.time, finite.error + + +def _measured_window_peaks( + data: Any, + *, + max_window_peaks: int, + window_max_frequency: float, + backend: str, +) -> tuple[WindowPeak, ...]: + """Peaks of the spectral window of ``data``'s sampling, strongest first. + + The window is evaluated from one Rayleigh-tenth up to ``window_max_frequency`` at + ten samples per Rayleigh width, so the daily comb is resolved rather than sampled. + Everything below :data:`_DC_RAYLEIGH` Rayleigh widths is the DC peak at ``f -> 0`` + (``|W(0)| = 1`` by construction, and it is not an alias spacing) and is dropped. + Reported peaks are additionally required to be two Rayleigh widths apart so that + the fine structure of one lobe cannot fill the list. + """ + from cuperiod.prewhiten.spectrum import spectral_window + + time, error = _sampling(data) + baseline = float(time.max() - time.min()) if time.size else 0.0 + grid = uniform_frequency_grid( + baseline, + maximum_frequency=window_max_frequency, + samples_per_peak=_WINDOW_SAMPLES_PER_PEAK, + ) + window = spectral_window(time, error, grid=grid, backend=backend) + separation = _DC_RAYLEIGH * window.rayleigh + candidates = local_maxima(window.amplitude) + if candidates.size: + keep = np.isfinite(window.amplitude[candidates]) & ( + window.frequency[candidates] >= separation + ) + candidates = candidates[keep] + if candidates.size == 0 or max_window_peaks <= 0: + return () + chosen = select_top_peaks( + window.frequency, window.amplitude, candidates, max_window_peaks, separation + ) + if chosen.size == 0: + return () + strongest = float(window.amplitude[chosen[0]]) + return tuple( + WindowPeak( + frequency=float(window.frequency[i]), + amplitude=float(window.amplitude[i]), + amplitude_ratio=( + float(window.amplitude[i]) / strongest + if strongest > 0.0 + else float("nan") + ), + ) + for i in chosen + ) + + +def _classic_window_peaks(max_window_peaks: int) -> tuple[WindowPeak, ...]: + """The textbook ground-based alias spacings, amplitudes unknown.""" + if max_window_peaks <= 0: + return () + return tuple( + WindowPeak(frequency=f, amplitude=float("nan"), amplitude_ratio=float("nan")) + for _label, f in CLASSIC_WINDOW_FREQUENCIES[:max_window_peaks] + ) + + +def _window_label(frequency: float, rayleigh: float) -> str: + """Name a window peak after the nearest classic suspect it is consistent with. + + A measured peak can only be attributed to (say) the sidereal rather than the solar + day when the baseline actually resolves the two, so the match must fall inside one + Rayleigh width; otherwise the peak is reported as a plain ``"window"`` frequency. + """ + if not np.isfinite(frequency): + return "window" + best_label = "window" + best_gap = rayleigh if np.isfinite(rayleigh) else 0.0 + for label, classic in CLASSIC_WINDOW_FREQUENCIES: + gap = abs(frequency - classic) + if gap <= best_gap: + best_label, best_gap = label, gap + return best_label + + +def _predicted_candidates( + f0: float, + window_peaks: Sequence[WindowPeak], + harmonics: Sequence[int], + rayleigh: float, + bounds: tuple[float, float], +) -> list[tuple[str, float]]: + """``(kind, frequency)`` predictions, deduped at one Rayleigh width. + + Aliases come first so that a frequency which is simultaneously an alias and a + harmonic is reported as the alias — the conservative reading, since only aliases + can make a period ambiguous. Predictions outside the periodogram's grid, at or + below zero, or within one Rayleigh width of ``f0`` or of an already-accepted + prediction are dropped. + """ + low, high = bounds + out: list[tuple[str, float]] = [] + + def add(kind: str, frequency: float) -> None: + if not np.isfinite(frequency) or frequency <= 0.0: + return + if frequency < low or frequency > high: + return + if abs(frequency - f0) < rayleigh: + return + if any(abs(frequency - taken) < rayleigh for _kind, taken in out): + return + out.append((kind, frequency)) + + for peak in window_peaks: + label = _window_label(peak.frequency, rayleigh) + tag = f"(f_w={peak.frequency:.5g}/d)" + for m in (1, 2): + offset = m * peak.frequency + add(f"{label}-alias m=+{m} {tag}", f0 + offset) + add(f"{label}-alias m=-{m} {tag}", abs(f0 - offset)) + for n in harmonics: + order = int(n) + if order < 2: + continue + add(f"harmonic n={order}", order * f0) + add(f"subharmonic n={order}", f0 / order) + return out + + +def _nearest_index(values: FloatArray, target: float) -> int: + """Index of the sample of ascending ``values`` closest to ``target``.""" + right = int(np.clip(np.searchsorted(values, target), 0, values.size - 1)) + left = max(right - 1, 0) + if abs(values[left] - target) <= abs(values[right] - target): + return left + return right + + +def _reference( + pg: Periodogram, frequency: float | None, rayleigh: float +) -> tuple[float, float]: + """``(frequency, power)`` of the peak being diagnosed. + + With no explicit frequency this is the periodogram's own best peak (which already + accounts for the objective sense). With one, the reference statistic is the best + value within a Rayleigh width of the request, so a frequency quoted to more digits + than the grid still gets its peak's power rather than a flank sample. + """ + if frequency is None: + peaks = pg.best_periods(1) + if not peaks: + raise ValueError( + "alias_diagnostics: the periodogram has no finite samples to diagnose" + ) + return float(peaks[0].frequency), float(peaks[0].power) + f0 = float(frequency) + score = _score_array(pg) + low = int(np.searchsorted(pg.frequency, f0 - rayleigh, side="left")) + high = int(np.searchsorted(pg.frequency, f0 + rayleigh, side="right")) + if high <= low: + return f0, float(pg.power[_nearest_index(pg.frequency, f0)]) + local = np.where(np.isfinite(score[low:high]), score[low:high], -np.inf) + return f0, float(pg.power[low + int(np.argmax(local))]) + + +def _score_array(pg: Periodogram) -> FloatArray: + """The periodogram statistic as a quantity to maximize.""" + return pg.power if pg.objective_sense == "max" else -pg.power + + +def _scorer(pg: Periodogram, best_power: float) -> Callable[[float], float]: + """Map a matched statistic onto the competitor score of :class:`AliasCandidate`.""" + if pg.objective_sense == "max": + reference = best_power + + def maximized(power: float) -> float: + if not np.isfinite(power) or not np.isfinite(reference) or reference <= 0.0: + return float("nan") + return power / reference + + return maximized + + finite = pg.power[np.isfinite(pg.power)] + worst = float(finite.max()) if finite.size else float("nan") + span = worst - best_power + + def minimized(power: float) -> float: + if not np.isfinite(power) or not np.isfinite(span) or span <= 0.0: + return float("nan") + return (worst - power) / span + + return minimized + + +def _optima(pg: Periodogram) -> tuple[FloatArray, FloatArray]: + """``(frequency, power)`` of every interior local optimum of the periodogram.""" + score = _score_array(pg) + indices = local_maxima(score) + if indices.size: + indices = indices[np.isfinite(score[indices])] + return pg.frequency[indices], pg.power[indices] + + +def alias_diagnostics( + pg: Periodogram, + data: Any = None, + *, + frequency: float | None = None, + threshold: float = 0.7, + max_window_peaks: int = 5, + harmonics: Sequence[int] = (2, 3), + window_max_frequency: float = 5.5, + backend: str = "auto", +) -> AliasReport: + """Check whether a periodogram peak could be a sampling alias. + + The frequency under examination is compared with the family of frequencies the + sampling cannot distinguish it from: ``f0 +/- m*f_w`` for the strongest peaks + ``f_w`` of the spectral window (``m = 1, 2``), plus harmonics and subharmonics. + Each prediction is looked up in the periodogram and scored against the examined + peak, so the result is not a list of suspicions but a ranked list of how well the + data actually support each competing frequency. + + Parameters + ---------- + pg : Periodogram + Any method's periodogram; both objective senses are handled. + data : light curve, optional + The light curve behind ``pg``, in any form :func:`cuperiod.to_input` accepts + (including a :class:`~cuperiod.MultiBandLightCurve`, whose bands are stacked + into one sampling). When given, the alias spacings are *measured* from this + sampling's spectral window. When omitted, the classic ground-based suspects + (sidereal day, solar day, synodic month, year) stand in and window amplitudes + are reported as NaN. + frequency : float, optional + Frequency to diagnose in cycles/day. Defaults to the periodogram's best peak. + threshold : float, default 0.7 + Score at or above which a non-harmonic competitor makes the result + :attr:`~AliasReport.ambiguous`. + max_window_peaks : int, default 5 + How many window peaks to use (strongest first). + harmonics : sequence of int, default (2, 3) + Harmonic orders ``n``: both ``n*f0`` and ``f0/n`` are tested. Orders below 2 + are ignored. + window_max_frequency : float, default 5.5 + Upper limit of the spectral-window grid in cycles/day. The default covers the + daily comb through its fifth multiple. + backend : str, default "auto" + Backend for the spectral window (see + :func:`~cuperiod.prewhiten.spectrum.resolve_spectrum_backend`). Unused when + ``data`` is None. + + Returns + ------- + AliasReport + + Raises + ------ + ValueError + If the periodogram is empty or holds no finite samples. + + Notes + ----- + Candidates falling outside the periodogram's frequency grid are dropped silently: + an alias that was never searched cannot compete. Likewise a prediction landing + within one Rayleigh width of the examined frequency (typically the yearly + sidelobes of a short baseline) is not a distinguishable alternative and is dropped. + + Examples + -------- + >>> report = alias_diagnostics(pg, (t, mag, err)) # doctest: +SKIP + >>> report.ambiguous # doctest: +SKIP + True + >>> report.candidates[0].kind # doctest: +SKIP + 'solar-day-alias m=-1 (f_w=1/d)' + """ + if pg.size == 0: + raise ValueError("alias_diagnostics: the periodogram is empty") + rayleigh = 1.0 / pg.baseline if pg.baseline > 0.0 else float("inf") + f0, best_power = _reference(pg, frequency, rayleigh) + + window_peaks = ( + _classic_window_peaks(max_window_peaks) + if data is None + else _measured_window_peaks( + data, + max_window_peaks=max_window_peaks, + window_max_frequency=window_max_frequency, + backend=backend, + ) + ) + + bounds = (float(pg.frequency[0]), float(pg.frequency[-1])) + predictions = _predicted_candidates(f0, window_peaks, harmonics, rayleigh, bounds) + optimum_frequency, optimum_power = _optima(pg) + score_of = _scorer(pg, best_power) + tolerance = _MATCH_RAYLEIGH * rayleigh + + candidates: list[AliasCandidate] = [] + for kind, predicted in predictions: + index = ( + _nearest_index(optimum_frequency, predicted) + if optimum_frequency.size + else None + ) + gap = ( + abs(float(optimum_frequency[index]) - predicted) + if index is not None + else float("inf") + ) + if index is None or gap > tolerance: + candidates.append( + AliasCandidate( + kind=kind, + frequency=predicted, + matched_frequency=float("nan"), + power=float("nan"), + score=0.0, + separation_rayleigh=float("nan"), + ) + ) + continue + power = float(optimum_power[index]) + candidates.append( + AliasCandidate( + kind=kind, + frequency=predicted, + matched_frequency=float(optimum_frequency[index]), + power=power, + score=score_of(power), + separation_rayleigh=gap / rayleigh, + ) + ) + + candidates.sort( + key=lambda c: ( + -(c.score if np.isfinite(c.score) else -np.inf), + c.frequency, + ) + ) + ambiguous = any( + not c.is_harmonic and np.isfinite(c.score) and c.score >= threshold + for c in candidates + ) + return AliasReport( + best_frequency=f0, + best_power=best_power, + rayleigh=rayleigh, + window_peaks=window_peaks, + candidates=tuple(candidates), + ambiguous=ambiguous, + threshold=float(threshold), + ) + + +__all__ = [ + "CLASSIC_WINDOW_FREQUENCIES", + "SIDEREAL_DAY_CPD", + "SOLAR_DAY_CPD", + "SYNODIC_MONTH_CPD", + "YEAR_CPD", + "AliasCandidate", + "AliasReport", + "WindowPeak", + "alias_diagnostics", +] diff --git a/src/cuperiod/gui/compute.py b/src/cuperiod/gui/compute.py index 129260e..5ccd97c 100644 --- a/src/cuperiod/gui/compute.py +++ b/src/cuperiod/gui/compute.py @@ -1,31 +1,36 @@ -"""Off-thread periodogram computation. +"""Off-thread periodogram and pre-whitening computation. -:func:`cuperiod.periodogram` is CPU/GPU-bound and can take seconds, so it must never -run on the GUI thread. :class:`PeriodogramTask` runs it on a worker and reports back -via plain signals carrying only the immutable -:class:`~cuperiod.core.result.Periodogram`; no Qt object is built off the GUI thread. +:func:`cuperiod.periodogram` is CPU/GPU-bound and can take seconds, and +:func:`cuperiod.prewhiten` runs a whole iterative extraction, so neither may run on the +GUI thread. :class:`PeriodogramTask` and :class:`PreWhitenTask` run them on a worker and +report back via plain signals carrying only the immutable result object; no Qt object is +built off the GUI thread. Superseding uses *generation gating*: the manager bumps a counter per submit and a task no-ops if the counter changed before it ran. A single-worker pool gives cheap -"latest wins"; the controller also re-checks the returned key before applying it. +"latest wins"; the controller also re-checks the returned key before applying it. Both +task kinds share the counter, so switching analysis mode mid-run supersedes cleanly. """ from __future__ import annotations import time +from typing import Any from pydantic_settings import BaseSettings +from cuperiod.core.config import PreWhitenSettings from cuperiod.core.result import Periodogram from cuperiod.gui.models import LoadedCurve, ResultKey from cuperiod.gui.qt import QObject, QtCore, Signal class _TaskSignals(QObject): - """Signals emitted by a :class:`PeriodogramTask` (owned by the manager).""" + """Signals emitted by the compute tasks (owned by the manager).""" started = Signal(object) # ResultKey finished = Signal(object, object, float) # ResultKey, Periodogram, elapsed_ms + solution_ready = Signal(object, object, float) # key, PreWhitenResult, elapsed_ms failed = Signal(object, str) # ResultKey, message @@ -78,6 +83,47 @@ def run(self) -> None: self._signals.finished.emit(self._key, result, elapsed_ms) +class PreWhitenTask(QtCore.QRunnable): + """Run one pre-whitening extraction on a worker thread and emit the solution.""" + + def __init__( + self, + key: ResultKey, + lc: LoadedCurve, + settings: PreWhitenSettings, + backend: str, + generation: int, + manager: ComputeManager, + signals: _TaskSignals, + ) -> None: + super().__init__() + self._key = key + self._lc = lc + self._settings = settings + self._backend = backend + self._generation = generation + self._manager = manager + self._signals = signals + self.setAutoDelete(True) + + def run(self) -> None: + if self._generation != self._manager.generation: + return # superseded before we started — skip the heavy compute + self._signals.started.emit(self._key) + start = time.perf_counter() + try: + from cuperiod.prewhiten import prewhiten + + result: Any = prewhiten( + self._lc, settings=self._settings, backend=self._backend + ) + except Exception as exc: # noqa: BLE001 - surfaced to the UI as a failure + self._signals.failed.emit(self._key, f"{type(exc).__name__}: {exc}") + return + elapsed_ms = (time.perf_counter() - start) * 1000.0 + self._signals.solution_ready.emit(self._key, result, elapsed_ms) + + class ComputeManager(QObject): """Worker pool + generation counter; delivers results onto the GUI thread.""" @@ -108,6 +154,20 @@ def submit( ) self._pool.start(task) + def submit_prewhiten( + self, + key: ResultKey, + lc: LoadedCurve, + settings: PreWhitenSettings, + backend: str, + ) -> None: + """Queue a pre-whitening run, superseding any pending/in-flight compute.""" + self._generation += 1 + task = PreWhitenTask( + key, lc, settings, backend, self._generation, self, self.signals + ) + self._pool.start(task) + def cancel_all(self) -> None: """Supersede all pending/in-flight tasks (they no-op on completion).""" self._generation += 1 @@ -117,4 +177,4 @@ def wait_for_done(self, timeout_ms: int = -1) -> bool: return self._pool.waitForDone(timeout_ms) -__all__ = ["ComputeManager", "PeriodogramTask"] +__all__ = ["ComputeManager", "PeriodogramTask", "PreWhitenTask"] diff --git a/src/cuperiod/gui/main_window.py b/src/cuperiod/gui/main_window.py index 21db2bf..1a46992 100644 --- a/src/cuperiod/gui/main_window.py +++ b/src/cuperiod/gui/main_window.py @@ -3,15 +3,23 @@ Assembles the controller and all panels and wires them together through the controller's signals: controls → run, results → spectrum/phased/peaks, source browser → batch scroll. The chosen theme is remembered across sessions via ``QSettings``. + +Two analyses share the shell. Switching the controls panel's **Analysis** picker swaps +which docks are on show — *Peaks* for a periodogram, *Frequencies* and *Period spacing* +for pre-whitening — while the spectrum, phased and raw views, the source browser, and +every load path stay exactly as they were. The docks are tabbed together, so the swap +never changes the window layout the user has arranged. """ from __future__ import annotations from pathlib import Path +import numpy as np from pydantic_settings import BaseSettings from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve +from cuperiod.core.result import Peak, Periodogram from cuperiod.gui.appinfo import version_label from cuperiod.gui.loaders import ( demo_sources, @@ -29,8 +37,11 @@ from cuperiod.gui.widgets.phased_view import PhasedView from cuperiod.gui.widgets.preview_dialog import PreviewDialog from cuperiod.gui.widgets.rawlc_view import RawLightCurveView +from cuperiod.gui.widgets.solution_panel import SolutionPanel from cuperiod.gui.widgets.source_panel import SourceBrowser -from cuperiod.gui.widgets.spectrum_view import SpectrumView +from cuperiod.gui.widgets.spacing_panel import SpacingPanel +from cuperiod.gui.widgets.spectrum_view import PREWHITEN_METHOD, SpectrumView +from cuperiod.prewhiten.result import PreWhitenResult _FILE_FILTER = ( "Light curves (*.csv *.ecsv *.fits *.fit *.fz *.parquet *.pq " @@ -69,7 +80,7 @@ def __init__( apply_theme(app, self._theme) self.setWindowIcon(app_icon()) - self.setWindowTitle("cuPeriod — periodogram explorer") + self.setWindowTitle("cuPeriod — periodogram & pre-whitening explorer") self.resize(1360, 860) # default size; overridden below if a geometry was saved self.setMinimumSize(1024, 680) self.setAcceptDrops(True) @@ -81,6 +92,8 @@ def __init__( self._phased = PhasedView(self._theme) self._raw = RawLightCurveView(self._theme) self._peaks_table = PeaksTable() + self._solution_panel = SolutionPanel() + self._spacing_panel = SpacingPanel(self._theme) self._source_browser = SourceBrowser() self._banner_timer = QtCore.QTimer(self) @@ -89,11 +102,12 @@ def __init__( self._build_toolbar() self._build_central() - self._build_peaks_dock() + self._build_result_docks() self._build_sources_dock() self._build_shortcuts() self._connect() self._restore_window_state() + self._apply_analysis("periodogram") self._show_status("Open a light curve or load a demo to begin.") # -- construction ------------------------------------------------------------ @@ -211,10 +225,28 @@ def _build_plot_area(self) -> QtWidgets.QWidget: plot_split.setSizes([520, 340]) return plot_split - def _build_peaks_dock(self) -> None: - dock = QtWidgets.QDockWidget("Peaks", self) - dock.setObjectName("peaks_dock") # required for saveState() - dock.setWidget(self._peaks_table) + def _build_result_docks(self) -> None: + """The three result docks, tabbed together on the right. + + Only the docks belonging to the active analysis are shown, but all three live in + the same tab group, so switching analysis never rearranges the window. + """ + self._peaks_dock = self._make_dock("Peaks", "peaks_dock", self._peaks_table) + self._solution_dock = self._make_dock( + "Frequencies", "solution_dock", self._solution_panel + ) + self._spacing_dock = self._make_dock( + "Period spacing", "spacing_dock", self._spacing_panel + ) + self.tabifyDockWidget(self._peaks_dock, self._solution_dock) + self.tabifyDockWidget(self._solution_dock, self._spacing_dock) + + def _make_dock( + self, title: str, object_name: str, widget: QtWidgets.QWidget + ) -> QtWidgets.QDockWidget: + dock = QtWidgets.QDockWidget(title, self) + dock.setObjectName(object_name) # required for saveState() + dock.setWidget(widget) feature = QtWidgets.QDockWidget.DockWidgetFeature dock.setFeatures( feature.DockWidgetMovable @@ -222,6 +254,7 @@ def _build_peaks_dock(self) -> None: | feature.DockWidgetClosable ) self.addDockWidget(Qt.DockWidgetArea.RightDockWidgetArea, dock) + return dock def _build_sources_dock(self) -> None: self._sources_dock = QtWidgets.QDockWidget("Sources", self) @@ -262,7 +295,11 @@ def _restore_window_state(self) -> None: def _connect(self) -> None: self._controls.run_requested.connect(self._on_run_requested) + self._controls.prewhiten_requested.connect(self._on_prewhiten_requested) + self._controls.analysis_changed.connect(self._on_analysis_changed) ctl = self._controller + ctl.solution_ready.connect(self._on_solution_ready) + self._solution_panel.component_selected.connect(ctl.select_component) ctl.lc_loaded.connect(self._on_lc_loaded) ctl.compute_started.connect(self._on_compute_started) ctl.busy_changed.connect(self._info.set_busy) @@ -372,12 +409,51 @@ def _on_run_requested( method, backend, settings, n_peaks, band=self._controls.current_band() ) + def _on_prewhiten_requested(self, backend: str, settings: object) -> None: + from cuperiod.core.config import PreWhitenSettings + + assert isinstance(settings, PreWhitenSettings) + self._controller.run_prewhiten( + backend, settings, band=self._controls.current_band() + ) + + # -- analysis switching ------------------------------------------------------ + def _on_analysis_changed(self, analysis: str) -> None: + self._controller.set_analysis(analysis) # type: ignore[arg-type] + self._apply_analysis(analysis) + self._spectrum.clear() + self._peaks_table.clear() + self._solution_panel.clear() + self._spacing_panel.clear() + # Only the *results* are stale — the light curve is unchanged, so drop the fold + # rather than the curve itself (clear() would leave the phased panel empty until + # the next load). + self._phased.clear_fold() + self._info.set_idle() + self._stack.setCurrentIndex(0) + self._show_status( + "Pre-whitening selected — press “Run pre-whitening”." + if analysis == "prewhiten" + else "Periodogram selected — press “Compute periodogram”." + ) + + def _apply_analysis(self, analysis: str) -> None: + """Show the docks that belong to ``analysis`` and raise the leading one.""" + prewhiten = analysis == "prewhiten" + self._peaks_dock.setVisible(not prewhiten) + self._solution_dock.setVisible(prewhiten) + self._spacing_dock.setVisible(prewhiten) + leading = self._solution_dock if prewhiten else self._peaks_dock + leading.raise_() + # -- controller signals ------------------------------------------------------ def _on_lc_loaded(self, lc: object) -> None: # Clear the previous source's results until the new spectrum is computed. self._spectrum.clear() self._phased.clear() self._peaks_table.clear() + self._solution_panel.clear() + self._spacing_panel.clear() self._stack.setCurrentIndex(0) self._info.set_idle() @@ -429,6 +505,88 @@ def _on_periodogram_ready(self, pg: object) -> None: f"{pg.best_period():.6g} d — {timing}" ) + def _on_solution_ready(self, result: object) -> None: + assert isinstance(result, PreWhitenResult) + self._hide_banner() + self._show_solution_spectrum(result) + self._solution_panel.set_solution(result) + self._spacing_panel.set_solution(result) + self._stack.setCurrentIndex(1) + timing = self._timing_text() + self._info.set_timing(timing) + strongest = ( + f"strongest {result.components[0].frequency:.6g} /d" + if result.components + else "no significant frequency" + ) + self._show_status( + f"Pre-whitening via {result.backend} — {result.n_components} components, " + f"{strongest} — {timing}" + ) + + def _show_solution_spectrum(self, result: PreWhitenResult) -> None: + """Draw the amplitude spectrum, its overlays, and the components. + + The pre-whitening result is wrapped in a :class:`Periodogram` so it flows + through the existing spectrum view unchanged — full-resolution rendering, the + draggable selection band, log axes, the crosshair readout, and CSV/PNG export + all come for free, and the components arrive as ordinary peak markers. + """ + spectrum = result.spectrum + if spectrum is None: # pragma: no cover - the GUI always keeps spectra + self._spectrum.clear() + return + wrapped = Periodogram.from_spectrum( + method=PREWHITEN_METHOD, + backend=result.backend, + frequency=spectrum.frequency, + power=spectrum.amplitude, + objective_sense="max", + n_samples=result.n_samples, + baseline=result.baseline, + ) + self._spectrum.set_periodogram(wrapped) + self._info.set_result(wrapped) + if result.residual_spectrum is not None: + self._spectrum.set_overlay( + result.residual_spectrum.frequency, result.residual_spectrum.amplitude + ) + if result.window is not None: + # Scaled to the tallest peak, Period04-style: |W| itself tops out at 1. + scale = ( + float(spectrum.amplitude.max()) if spectrum.amplitude.size else 1.0 + ) + self._spectrum.set_window( + result.window.frequency, result.window.amplitude, scale=scale + ) + # Markers annotate the *curve*, so their height is the plotted spectrum at the + # component's frequency — not its fitted amplitude. The two are equal for a + # well-separated mode but diverge whenever components are correlated (a HADS + # harmonic and its yearly alias sidelobes trade amplitude in the joint fit), + # and a marker floating above the curve claims a peak that is not there. The + # fitted amplitude stays on the hover readout and in the Frequencies dock, + # where their disagreement is reported as the blend ratio. + heights = spectrum.amplitude_at( + np.asarray([c.frequency for c in result.components], dtype=np.float64) + ) + peaks = [ + Peak( + period=component.period, + frequency=component.frequency, + power=float(heights[i]), + rank=component.rank, + extra={ + "snr": component.snr, + "amplitude": component.amplitude, + "blended": float(component.blended), + }, + ) + for i, component in enumerate(result.components) + ] + self._spectrum.set_peaks(peaks) + if peaks: + self._spectrum.set_selected_period(peaks[0].period) + def _timing_text(self) -> str: state = self._controller.state if state.last_from_cache: @@ -443,6 +601,8 @@ def _on_compute_failed(self, message: str) -> None: # -- helpers ----------------------------------------------------------------- def _controls_method(self) -> str: + if self._controller.state.analysis == "prewhiten": + return PREWHITEN_METHOD return self._controller.state.method def _show_status(self, message: str) -> None: @@ -470,6 +630,7 @@ def _toggle_theme(self) -> None: self._spectrum.apply_theme(pal) self._phased.apply_theme(pal) self._raw.apply_theme(pal) + self._spacing_panel.apply_theme(pal) QtCore.QSettings().setValue("theme", self._theme) def _compute_via_shortcut(self) -> None: diff --git a/src/cuperiod/gui/meta.py b/src/cuperiod/gui/meta.py index 555077f..f89f8bd 100644 --- a/src/cuperiod/gui/meta.py +++ b/src/cuperiod/gui/meta.py @@ -12,6 +12,7 @@ from cuperiod.core._typing import FloatArray from cuperiod.core.columns import Domain +from cuperiod.core.config import GLSSettings, MHAOVSettings, PreWhitenSettings from cuperiod.core.errors import BackendUnavailableError from cuperiod.core.grid import pseudo_nyquist_frequency from cuperiod.methods.base import get_method, method_names @@ -19,9 +20,28 @@ #: Box/transit methods where alias-diverse peak selection is the sensible default. _ALIAS_DIVERSE_METHODS = frozenset({"BLS", "TLS"}) -#: The GUI's auto grid reaches at least this short a period (days) for freq methods. +#: The GUI's auto grid reaches at least this short a period (days) for the fold-based +#: methods (PDM, CE, string-length), which pay a full fold of the light curve per +#: trial frequency. The frequency-domain analyses reach shorter periods — see +#: :func:`reaches_short_periods`. MIN_PERIOD_FLOOR_DAYS = 0.1 +#: Analyses whose cost per trial frequency is a trig sum / one NUFFT, so a wide band +#: is cheap and the auto grid can afford the same δ Scuti / HADS floor pre-whitening +#: uses (50 cycles/day — the bundled ASAS-SN HADS at P = 0.0898 d is the star the old +#: 10 c/d ceiling silently aliased). +_SHORT_PERIOD_SETTINGS: tuple[type[BaseSettings], ...] = ( + GLSSettings, + MHAOVSettings, + PreWhitenSettings, +) + + +def reaches_short_periods(settings: BaseSettings | type[BaseSettings]) -> bool: + """Whether this analysis' auto band uses the short-period (50 c/d) floor.""" + cls = settings if isinstance(settings, type) else type(settings) + return issubclass(cls, _SHORT_PERIOD_SETTINGS) + def method_display_names() -> list[str]: """All registered method names (canonical, sorted).""" @@ -29,7 +49,7 @@ def method_display_names() -> list[str]: def multiband_method_names() -> list[str]: - """Only the methods that support multiband input (GLS, BLS, MHAOV).""" + """Only the methods that support multiband input (everything but TLS).""" return [name for name in method_names() if supports_multiband(name)] @@ -69,6 +89,40 @@ def auto_max_frequency(time: FloatArray, nyquist_factor: int = 5) -> float: return float(max(pseudo_nyquist_frequency(time, nyquist_factor), floor)) +def prewhiten_backend_options() -> list[str]: + """Backends the amplitude spectrum can actually run on this machine. + + Mirrors :func:`backend_options` for the pre-whitening analysis, which is not a + registry method: each candidate is test-resolved so only usable entries are offered. + """ + from cuperiod.prewhiten.spectrum import SPECTRUM_BACKENDS, resolve_spectrum_backend + + options: list[str] = [] + for backend in ("auto", "cpu", "gpu", "torch", *SPECTRUM_BACKENDS): + if backend in options: + continue + try: + resolve_spectrum_backend(backend) + except BackendUnavailableError: + continue + options.append(backend) + return options + + +def resolved_prewhiten_backend(backend: str) -> tuple[str, bool] | None: + """``(concrete_backend, is_gpu)`` for a pre-whitening backend request, or None.""" + from cuperiod.prewhiten.spectrum import resolve_spectrum_backend + + try: + resolved = resolve_spectrum_backend(backend) + except BackendUnavailableError: + return None + is_gpu = resolved == "cufinufft" or ( + resolved.startswith("torch") and resolved != "torch:cpu" + ) + return resolved, is_gpu + + def resolved_backend(name: str, backend: str) -> tuple[str, bool] | None: """The concrete backend ``backend`` resolves to for ``name`` and whether it's a GPU. @@ -114,7 +168,10 @@ def backend_options(name: str) -> list[str]: "multiband_method_names", "natural_domain", "objective_sense", + "prewhiten_backend_options", + "reaches_short_periods", "resolved_backend", + "resolved_prewhiten_backend", "settings_class", "supports_multiband", ] diff --git a/src/cuperiod/gui/models.py b/src/cuperiod/gui/models.py index a86d4ee..f30ec43 100644 --- a/src/cuperiod/gui/models.py +++ b/src/cuperiod/gui/models.py @@ -1,11 +1,13 @@ """Plain data models for the GUI: cache keys, the result cache, and source items. None of these touch Qt — they are pure Python so they unit-test headlessly. A -:class:`ResultKey` identifies a spectrum by *(source, method, settings, backend)*; the +:class:`ResultKey` identifies a result by *(source, analysis, settings, backend)*; the :class:`ResultCache` (a small LRU) returns a previously computed -:class:`~cuperiod.core.result.Periodogram` instantly when the user revisits an unchanged -setup. A :class:`SourceItem` is one entry in single/batch mode: a label and a lazy -``loader`` so a folder of thousands of light curves is not all read up front. +:class:`~cuperiod.core.result.Periodogram` — or a +:class:`~cuperiod.prewhiten.PreWhitenResult`, since the cache is generic over its value +type — instantly when the user revisits an unchanged setup. A :class:`SourceItem` is one +entry in single/batch mode: a label and a lazy ``loader`` so a folder of thousands of +light curves is not all read up front. """ from __future__ import annotations @@ -15,16 +17,17 @@ from collections import OrderedDict from collections.abc import Callable, Mapping from dataclasses import dataclass, field -from typing import Any +from typing import Any, Generic, TypeVar from pydantic_settings import BaseSettings from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve -from cuperiod.core.result import Periodogram #: A loaded source is either a single- or multi-band light curve. LoadedCurve = LightCurve | MultiBandLightCurve +_ResultT = TypeVar("_ResultT") + def settings_hash(settings: BaseSettings) -> str: """A short, order-independent hash of a settings object. @@ -40,10 +43,12 @@ def settings_hash(settings: BaseSettings) -> str: @dataclass(frozen=True) class ResultKey: - """Identity of a computed spectrum, used as the cache key. + """Identity of a computed result, used as the cache key. - ``backend`` is the *requested* backend (``"auto"``/``"cpu"``/``"gpu"``/...), kept - distinct so a CPU and a GPU run of the same configuration cache separately. + ``method`` is the periodogram method for a spectrum run and ``"PREWHITEN"`` for a + frequency-solution run, so the two analyses can never collide. ``backend`` is the + *requested* backend (``"auto"``/``"cpu"``/``"gpu"``/...), kept distinct so a CPU and + a GPU run of the same configuration cache separately. """ source_id: str @@ -52,25 +57,29 @@ class ResultKey: backend: str -class ResultCache: - """A bounded LRU cache of periodograms keyed by :class:`ResultKey`.""" +class ResultCache(Generic[_ResultT]): + """A bounded LRU cache of results keyed by :class:`ResultKey`. + + Generic over the value type: the app keeps one instance for periodograms and one for + pre-whitening solutions, so switching analysis mode back and forth is instant. + """ def __init__(self, maxsize: int = 64) -> None: if maxsize < 1: raise ValueError("maxsize must be >= 1") self._maxsize = maxsize - self._items: OrderedDict[ResultKey, Periodogram] = OrderedDict() + self._items: OrderedDict[ResultKey, _ResultT] = OrderedDict() - def get(self, key: ResultKey) -> Periodogram | None: - """Cached periodogram for ``key`` (marks it recently used), else None.""" - pg = self._items.get(key) - if pg is not None: + def get(self, key: ResultKey) -> _ResultT | None: + """Cached result for ``key`` (marks it recently used), else None.""" + item = self._items.get(key) + if item is not None: self._items.move_to_end(key) - return pg + return item - def put(self, key: ResultKey, pg: Periodogram) -> None: + def put(self, key: ResultKey, value: _ResultT) -> None: """Insert/refresh ``key``; evict the LRU entry if over capacity.""" - self._items[key] = pg + self._items[key] = value self._items.move_to_end(key) while len(self._items) > self._maxsize: self._items.popitem(last=False) diff --git a/src/cuperiod/gui/state.py b/src/cuperiod/gui/state.py index f59529c..8d1f614 100644 --- a/src/cuperiod/gui/state.py +++ b/src/cuperiod/gui/state.py @@ -3,9 +3,14 @@ :class:`AppState` is a plain dataclass snapshot of what the app is showing. The :class:`AppController` is the single hub: widgets call its setters and listen to its signals; it owns the :class:`~cuperiod.gui.compute.ComputeManager` and the -:class:`~cuperiod.gui.models.ResultCache`, runs (or cache-hits) periodograms, derives -peaks, and tracks the selected period that drives the phased view. Views never talk to -each other — only to the controller — so the data flow stays one-directional. +:class:`~cuperiod.gui.models.ResultCache`, runs (or cache-hits) periodograms *and* +pre-whitening solutions, derives peaks, and tracks the selected period that drives the +phased view. Views never talk to each other — only to the controller — so the data flow +stays one-directional. + +The two analyses share every input path (the loaded curve, the source browser, the +folded view) and differ only in what they compute and which result signal they emit, so +switching costs nothing and neither can disturb the other's cached results. """ from __future__ import annotations @@ -17,6 +22,7 @@ from pydantic_settings import BaseSettings from cuperiod.core._typing import FloatArray +from cuperiod.core.config import PreWhitenSettings from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve from cuperiod.core.result import Peak, Periodogram from cuperiod.gui.compute import ComputeManager @@ -24,6 +30,7 @@ from cuperiod.gui.meta import ( alias_diverse_default, auto_max_frequency, + reaches_short_periods, supports_multiband, ) from cuperiod.gui.models import ( @@ -34,9 +41,17 @@ settings_hash, ) from cuperiod.gui.qt import QObject, Signal +from cuperiod.prewhiten.engine import default_maximum_frequency +from cuperiod.prewhiten.result import PreWhitenResult, Sinusoid Mode = Literal["single", "batch"] +#: Which analysis the app is running. +Analysis = Literal["periodogram", "prewhiten"] + +#: Registry-style key under which pre-whitening runs are cached. +PREWHITEN_KEY = "PREWHITEN" + #: Denser default frequency oversampling for smoother, better-resolved periodograms #: (helps the jagged look on a period axis at long periods). Applied only when the user #: leaves ``samples_per_peak`` at the model default. @@ -49,6 +64,7 @@ class AppState: theme: str = "dark" mode: Mode = "single" + analysis: Analysis = "periodogram" method: str = "GLS" backend: str = "auto" n_peaks: int = 10 @@ -57,6 +73,7 @@ class AppState: source_id: str = "" current_lc: LoadedCurve | None = None current_pg: Periodogram | None = None + current_solution: PreWhitenResult | None = None selected_peak: Peak | None = None selected_period: float | None = None sources: list[SourceItem] | None = None @@ -71,6 +88,7 @@ class AppController(QObject): lc_loaded = Signal(object) # LoadedCurve compute_started = Signal() periodogram_ready = Signal(object) # Periodogram + solution_ready = Signal(object) # PreWhitenResult compute_failed = Signal(str) peaks_ready = Signal(object) # list[Peak] period_changed = Signal(float) # drives the spectrum line @@ -79,14 +97,17 @@ class AppController(QObject): busy_changed = Signal(bool) sources_changed = Signal(object) # list[str] labels (batch mode) source_selected = Signal(int) + analysis_changed = Signal(str) # "periodogram" | "prewhiten" def __init__(self, parent: QObject | None = None) -> None: super().__init__(parent) self.state = AppState() - self._cache = ResultCache() + self._cache: ResultCache[Periodogram] = ResultCache() + self._solutions: ResultCache[PreWhitenResult] = ResultCache(maxsize=32) self._compute = ComputeManager(self) self._pending_key: ResultKey | None = None self._compute.signals.finished.connect(self._on_finished) + self._compute.signals.solution_ready.connect(self._on_solution) self._compute.signals.failed.connect(self._on_failed) # -- inputs ------------------------------------------------------------------ @@ -95,10 +116,27 @@ def set_light_curve(self, lc: LoadedCurve, source_id: str) -> None: self.state.current_lc = lc self.state.source_id = source_id self.state.current_pg = None + self.state.current_solution = None self.state.selected_peak = None self.state.selected_period = None self.lc_loaded.emit(lc) + def set_analysis(self, analysis: Analysis) -> None: + """Switch between the periodogram and pre-whitening analyses. + + Only the *pending* run is superseded; both caches survive, so flipping back to a + previously computed analysis of the same source redisplays it instantly. + """ + if analysis == self.state.analysis: + return + self.state.analysis = analysis + self._pending_key = None + # Dropping the pending key means no completion handler will ever fire for the + # in-flight run, so the busy state has to be released here or the Compute button + # stays disabled for the rest of the session. + self.busy_changed.emit(False) + self.analysis_changed.emit(analysis) + # -- batch mode -------------------------------------------------------------- def load_sources(self, items: list[SourceItem]) -> None: """Enter batch mode with ``items`` (labels via ``sources_changed``).""" @@ -164,6 +202,40 @@ def run( self.compute_started.emit() self._compute.submit(key, lc_input, method, settings, backend) + def run_prewhiten( + self, backend: str, settings: PreWhitenSettings, band: str = "" + ) -> None: + """Extract (or cache-hit) the frequency solution for the active light curve. + + Pre-whitening is single-band by definition, so a multiband curve is reduced the + same way a single-band method does: the selected band, or all bands stacked. + """ + lc = self.state.current_lc + if lc is None: + return + if isinstance(lc, MultiBandLightCurve): + lc_input: LightCurve = ( + lc.bands[band] if band in lc.bands else self._stack_centred(lc) + ) + else: + lc_input = lc + tuned = self._tune_auto_grid(lc_input, settings) + assert isinstance(tuned, PreWhitenSettings) + settings = tuned + self.state.backend = backend + self.state.band = band + self.state.method = PREWHITEN_KEY + source_id = self.state.source_id + (f"::{band}" if band else "") + key = ResultKey(source_id, PREWHITEN_KEY, settings_hash(settings), backend) + self._pending_key = key + cached = self._solutions.get(key) + if cached is not None: + self._apply_solution(cached, 0.0, from_cache=True) + return + self.busy_changed.emit(True) + self.compute_started.emit() + self._compute.submit_prewhiten(key, lc_input, settings, backend) + def _resolve_input(self, method: str, band: str) -> LoadedCurve | None: """Pick the curve to analyse from the (possibly multiband) active curve.""" lc = self.state.current_lc @@ -182,11 +254,35 @@ def _stack(mblc: MultiBandLightCurve) -> LightCurve: domain = next(iter(mblc.bands.values())).domain return LightCurve.from_arrays(time, value, error, domain=domain) + @staticmethod + def _stack_centred(mblc: MultiBandLightCurve) -> LightCurve: + """Merge all bands after removing each band's own mean. + + Pre-whitening fits a *single* constant for the whole curve, so a raw stack of + bands at different zero points buries the pulsation under an inter-band offset + of a magnitude or more. Centring each band first is the least the merge can do + to stay usable; a per-band amplitude solution would need a multi-band model. + """ + finite = mblc.finite() + centred = { + name: LightCurve.from_arrays( + band.time, + band.value - float(np.mean(band.value)) if band.n else band.value, + band.error, + domain=band.domain, + ) + for name, band in finite.bands.items() + } + return AppController._stack(MultiBandLightCurve.from_light_curves(centred)) + def _tune_auto_grid(self, lc: LoadedCurve, settings: BaseSettings) -> BaseSettings: """Improve the default frequency grid for frequency-grid methods. (a) Raises an auto max-frequency so sub-day periods aren't missed on sparse data - (see :func:`cuperiod.gui.meta.auto_max_frequency`) and (b) densifies the default + (see :func:`cuperiod.gui.meta.auto_max_frequency`; the frequency-domain + analyses — GLS, MHAOV, pre-whitening — use the engine's + :func:`~cuperiod.prewhiten.default_maximum_frequency`, whose higher floor keeps + δ Scuti / HADS frequencies in band) and (b) densifies the default ``samples_per_peak`` for smoother, better-resolved periodograms (notably at long periods). Explicitly-changed values are left as-is. """ @@ -199,7 +295,12 @@ def _tune_auto_grid(self, lc: LoadedCurve, settings: BaseSettings) -> BaseSettin and time.size >= 2 ): nyquist_factor = int(getattr(settings, "nyquist_factor", 5)) - updates["maximum_frequency"] = auto_max_frequency(time, nyquist_factor) + auto = ( + default_maximum_frequency(time, nyquist_factor) + if reaches_short_periods(settings) + else auto_max_frequency(time, nyquist_factor) + ) + updates["maximum_frequency"] = auto if "samples_per_peak" in fields: current = getattr(settings, "samples_per_peak", None) if current is not None and current == fields["samples_per_peak"].default: @@ -226,11 +327,39 @@ def _on_finished(self, key: ResultKey, pg: Periodogram, elapsed_ms: float) -> No if key == self._pending_key: self._apply_result(key, pg, elapsed_ms, from_cache=False) + def _on_solution( + self, key: ResultKey, result: PreWhitenResult, elapsed_ms: float + ) -> None: + self._solutions.put(key, result) + if key == self._pending_key: + self._apply_solution(result, elapsed_ms, from_cache=False) + def _on_failed(self, key: ResultKey, message: str) -> None: if key == self._pending_key: self.busy_changed.emit(False) self.compute_failed.emit(message) + def _apply_solution( + self, result: PreWhitenResult, elapsed_ms: float, *, from_cache: bool + ) -> None: + self.state.current_solution = result + self.state.current_pg = None + self.state.last_compute_ms = elapsed_ms + self.state.last_from_cache = from_cache + self.busy_changed.emit(False) + self.solution_ready.emit(result) + if result.components: + self.select_component(result.components[0]) + else: + self.state.selected_peak = None + self.state.selected_period = None + self.selection_cleared.emit() + + def select_component(self, component: Sinusoid) -> None: + """Select an extracted sinusoid as the active period (drives the fold).""" + self.state.selected_peak = None + self.select_period(component.period) + def _apply_result( self, key: ResultKey, pg: Periodogram, elapsed_ms: float, *, from_cache: bool ) -> None: @@ -286,4 +415,4 @@ def _lc_time(self) -> FloatArray: return self._time_of(self.state.current_lc) -__all__ = ["AppController", "AppState", "Mode"] +__all__ = ["PREWHITEN_KEY", "Analysis", "AppController", "AppState", "Mode"] diff --git a/src/cuperiod/gui/widgets/controls_panel.py b/src/cuperiod/gui/widgets/controls_panel.py index f0ffbf1..234382b 100644 --- a/src/cuperiod/gui/widgets/controls_panel.py +++ b/src/cuperiod/gui/widgets/controls_panel.py @@ -1,10 +1,16 @@ -"""The left-hand controls: method/backend pickers, the options form, and Compute. - -The method picker drives a dynamically rebuilt :class:`PydanticSettingsForm` (so every -option of the chosen method is exposed) and a backend picker limited to usable backends. -Settings are cached per method, so switching back restores your values. -``Compute`` validates and emits :attr:`run_requested`; invalid input is shown inline -instead of starting a run. +"""The left-hand controls: analysis/method/backend pickers, options form, and Compute. + +The panel drives both analyses from one layout. In **Periodogram** mode the method +picker selects one of the registered methods; in **Pre-whitening** mode the method and +peak-count rows are hidden and the same machinery serves +:class:`~cuperiod.PreWhitenSettings` instead. Either way the options form is a +dynamically rebuilt :class:`PydanticSettingsForm` — every field of the chosen settings +model is exposed automatically, so the pre-whitening controls needed no bespoke +widgets — and the backend picker is limited to backends that actually resolve here. + +Settings are cached per analysis/method, so switching back restores your values. +``Compute`` validates and emits :attr:`run_requested` or :attr:`prewhiten_requested`; +invalid input is shown inline instead of starting a run. """ from __future__ import annotations @@ -15,6 +21,7 @@ from pydantic_settings import BaseSettings from cuperiod.core._typing import FloatArray +from cuperiod.core.config import PreWhitenSettings from cuperiod.gui.meta import ( auto_max_frequency, backend_options, @@ -22,15 +29,26 @@ multiband_method_names, natural_domain, objective_sense, + prewhiten_backend_options, + reaches_short_periods, resolved_backend, + resolved_prewhiten_backend, settings_class, supports_multiband, ) from cuperiod.gui.qt import Qt, QtWidgets, Signal from cuperiod.gui.settingsform import PydanticSettingsForm +from cuperiod.prewhiten.engine import default_maximum_frequency _DEFAULT_METHOD = "GLS" +#: Display labels for the analysis picker, in order. +_PERIODOGRAM_LABEL = "Periodogram" +_PREWHITEN_LABEL = "Pre-whitening" + +#: Cache key for the pre-whitening settings form (methods use their own names). +_PREWHITEN_CACHE_KEY = "__prewhiten__" + #: Item-data sentinels for the synthetic "all bands" combo entries, distinguishing them #: from a real band that happens to be named "combined" or "stacked". _COMBINED_SENTINEL = "__combined__" @@ -51,8 +69,12 @@ def _first_error_message(exc: ValidationError) -> str: class ControlsPanel(QtWidgets.QWidget): """Method/backend pickers, the auto-generated options form, and Compute.""" - # Emitted on Compute: (method, backend, settings, n_peaks). + # Emitted on Compute in periodogram mode: (method, backend, settings, n_peaks). run_requested = Signal(str, str, object, int) + # Emitted on Compute in pre-whitening mode: (backend, PreWhitenSettings). + prewhiten_requested = Signal(str, object) + # Emitted when the analysis picker changes: "periodogram" | "prewhiten". + analysis_changed = Signal(str) def __init__(self, parent: QtWidgets.QWidget | None = None) -> None: super().__init__(parent) @@ -62,6 +84,7 @@ def __init__(self, parent: QtWidgets.QWidget | None = None) -> None: self._curve_time: FloatArray | None = None self._has_curve = False self._busy = False + self._prewhiten = False root = QtWidgets.QVBoxLayout(self) root.setContentsMargins(12, 12, 12, 12) @@ -73,6 +96,13 @@ def __init__(self, parent: QtWidgets.QWidget | None = None) -> None: self._top = QtWidgets.QFormLayout() self._top.setLabelAlignment(Qt.AlignmentFlag.AlignRight) + self._analysis_combo = QtWidgets.QComboBox() + self._analysis_combo.addItems([_PERIODOGRAM_LABEL, _PREWHITEN_LABEL]) + self._analysis_combo.setToolTip( + "Periodogram: one period-search statistic over a trial grid.\n" + "Pre-whitening: iterative sinusoid extraction with uncertainties, " + "combination frequencies, and g-mode period spacings." + ) self._method_combo = QtWidgets.QComboBox() self._method_combo.addItems(method_display_names()) self._method_combo.setToolTip("Periodogram method to run") @@ -87,6 +117,7 @@ def __init__(self, parent: QtWidgets.QWidget | None = None) -> None: self._peaks_spin.setRange(1, 100) self._peaks_spin.setValue(10) self._peaks_spin.setToolTip("Number of significant peaks to find and list") + self._top.addRow("Analysis", self._analysis_combo) self._top.addRow("Method", self._method_combo) self._top.addRow("Band", self._band_combo) self._top.addRow("Backend", self._backend_combo) @@ -136,9 +167,56 @@ def __init__(self, parent: QtWidgets.QWidget | None = None) -> None: self._method_combo.setCurrentText(_DEFAULT_METHOD) self._method_combo.currentTextChanged.connect(self._on_method_changed) self._backend_combo.currentTextChanged.connect(self._update_backend_hint) + self._analysis_combo.currentTextChanged.connect(self._on_analysis_changed) self._on_method_changed(self._method_combo.currentText()) self.set_enabled(False) + # -- analysis switching ------------------------------------------------------ + @property + def analysis(self) -> str: + """``"periodogram"`` or ``"prewhiten"``.""" + return "prewhiten" if self._prewhiten else "periodogram" + + def set_analysis(self, analysis: str) -> None: + """Programmatically switch the analysis picker.""" + label = _PREWHITEN_LABEL if analysis == "prewhiten" else _PERIODOGRAM_LABEL + if self._analysis_combo.currentText() != label: + self._analysis_combo.setCurrentText(label) + + def _on_analysis_changed(self, label: str) -> None: + self._stash_current_settings() + self._prewhiten = label == _PREWHITEN_LABEL + self._top.setRowVisible(self._method_combo, not self._prewhiten) + self._top.setRowVisible(self._peaks_spin, not self._prewhiten) + self._compute_btn.setText( + "Run pre-whitening" if self._prewhiten else "Compute periodogram" + ) + self._compute_btn.setToolTip( + ("Extract the frequency solution" if self._prewhiten else + "Compute the periodogram") + " (Ctrl+Enter)" + ) + if self._prewhiten: + self._current_method = _PREWHITEN_CACHE_KEY + self._rebuild_backend_combo(None) + self._rebuild_band_combo(None) + self._rebuild_form(_PREWHITEN_CACHE_KEY, PreWhitenSettings) + self._note.setText( + "iterative extraction · single-band · amplitude spectrum" + ) + else: + self._current_method = None + self._on_method_changed(self._method_combo.currentText()) + self._update_backend_hint() + self._update_grid_hint() + self._clear_error() + self.analysis_changed.emit(self.analysis) + + def _stash_current_settings(self) -> None: + """Remember the current form's values under the key it was built for.""" + if self._current_method is not None and self._form is not None: + with contextlib.suppress(ValidationError): + self._settings_cache[self._current_method] = self._form.build() + # -- public ------------------------------------------------------------------ def set_enabled(self, enabled: bool) -> None: """Enable/disable the Compute action (a light curve must be loaded first).""" @@ -182,7 +260,13 @@ def set_multiband(self, is_multiband: bool) -> None: def set_bands(self, band_names: list[str] | None) -> None: """Show a band selector for multiband curves; hide it for single-band ones.""" self._band_names = list(band_names) if band_names else None - self._rebuild_band_combo(self._method_combo.currentText()) + # ``None`` means pre-whitening, which is single-band by definition. Passing + # the (hidden) method combo's text would offer "combined (all bands)" and + # select it, so loading a multiband curve *after* switching analysis would + # silently analyse a raw all-band stack instead of one band. + self._rebuild_band_combo( + None if self._prewhiten else self._method_combo.currentText() + ) def set_curve_time(self, time: FloatArray) -> None: """Provide the active curve's times so the auto grid range can be shown.""" @@ -202,26 +286,27 @@ def current_band(self) -> str: # -- method switching -------------------------------------------------------- def _on_method_changed(self, method: str) -> None: - if self._current_method is not None and self._form is not None: - with contextlib.suppress(ValidationError): - self._settings_cache[self._current_method] = self._form.build() + if self._prewhiten: + return + self._stash_current_settings() self._current_method = method self._rebuild_backend_combo(method) self._rebuild_band_combo(method) - self._rebuild_form(method) + self._rebuild_form(method, settings_class(method)) self._update_note(method) self._update_backend_hint() self._update_grid_hint() self._clear_error() - def _rebuild_band_combo(self, method: str) -> None: + def _rebuild_band_combo(self, method: str | None) -> None: + """Rebuild the band picker; ``method=None`` means the pre-whitening analysis.""" if self._band_names is None: self._top.setRowVisible(self._band_combo, False) return self._top.setRowVisible(self._band_combo, True) self._band_combo.blockSignals(True) self._band_combo.clear() - if supports_multiband(method): + if method is not None and supports_multiband(method): # combined multiband analysis is the default for capable methods self._band_combo.addItem("combined (all bands)", _COMBINED_SENTINEL) for name in self._band_names: @@ -234,16 +319,21 @@ def _rebuild_band_combo(self, method: str) -> None: self._band_combo.setCurrentIndex(0) self._band_combo.blockSignals(False) - def _rebuild_backend_combo(self, method: str) -> None: + def _rebuild_backend_combo(self, method: str | None) -> None: + """Rebuild the backend picker; ``method=None`` means pre-whitening.""" + options = ( + prewhiten_backend_options() if method is None else backend_options(method) + ) self._backend_combo.blockSignals(True) self._backend_combo.clear() - self._backend_combo.addItems(backend_options(method)) + self._backend_combo.addItems(options) self._backend_combo.setCurrentText("auto") self._backend_combo.blockSignals(False) - def _rebuild_form(self, method: str) -> None: + def _rebuild_form(self, cache_key: str, model: type[BaseSettings]) -> None: + cached = self._settings_cache.get(cache_key) form = PydanticSettingsForm( - settings_class(method), initial=self._settings_cache.get(method) + model, initial=cached if isinstance(cached, model) else None ) form.changed.connect(self._clear_error) form.changed.connect(self._update_grid_hint) @@ -264,7 +354,11 @@ def _update_note(self, method: str) -> None: def _update_backend_hint(self) -> None: chosen = self._backend_combo.currentText() - info = resolved_backend(self._method_combo.currentText(), chosen) + info = ( + resolved_prewhiten_backend(chosen) + if self._prewhiten + else resolved_backend(self._method_combo.currentText(), chosen) + ) if info is None: self._backend_hint.setText("") return @@ -273,12 +367,17 @@ def _update_backend_hint(self) -> None: prefix = "" if resolved == chosen else f"{chosen} → " self._backend_hint.setText(f"runs on: {prefix}{resolved} ({where})") + def _settings_model(self) -> type[BaseSettings]: + """The settings model backing the current form.""" + if self._prewhiten: + return PreWhitenSettings + return settings_class(self._method_combo.currentText()) + def _update_grid_hint(self) -> None: - method = self._method_combo.currentText() if ( self._curve_time is None or self._form is None - or "maximum_frequency" not in settings_class(method).model_fields + or "maximum_frequency" not in self._settings_model().model_fields ): self._grid_hint.setText("") return @@ -286,7 +385,14 @@ def _update_grid_hint(self) -> None: baseline = float(time.max() - time.min()) nyquist_factor = int(self._form.value_of("nyquist_factor") or 5) auto_min = 1.0 / baseline if baseline > 0.0 else 0.0 - auto_max = auto_max_frequency(time, nyquist_factor) + # Frequency-domain analyses floor their auto band higher (delta Scuti / HADS + # coverage); mirror the controller exactly so the greyed value is the one + # that will run. + auto_max = ( + default_maximum_frequency(time, nyquist_factor) + if reaches_short_periods(self._settings_model()) + else auto_max_frequency(time, nyquist_factor) + ) # fill the greyed 'auto' spin boxes with the values that will actually be used self._form.set_auto_value("minimum_frequency", auto_min) self._form.set_auto_value("maximum_frequency", auto_max) @@ -311,6 +417,9 @@ def _on_compute(self) -> None: self._show_error(_first_error_message(exc)) return self._clear_error() + if self._prewhiten: + self.prewhiten_requested.emit(self._backend_combo.currentText(), settings) + return self.run_requested.emit( self._method_combo.currentText(), self._backend_combo.currentText(), diff --git a/src/cuperiod/gui/widgets/solution_panel.py b/src/cuperiod/gui/widgets/solution_panel.py new file mode 100644 index 0000000..ca3ac8a --- /dev/null +++ b/src/cuperiod/gui/widgets/solution_panel.py @@ -0,0 +1,277 @@ +"""The frequency-solution panel: the extracted components and how the run ended. + +The pre-whitening counterpart of the peaks table. Every row is one extracted sinusoid +with its uncertainty, signal-to-noise, false-alarm probability, and — where one was +identified — the combination that explains it. Selecting a row makes that component the +active period, so the phased view folds on it exactly as it does for a periodogram peak. + +The ``A/Asp`` column is the reliability check the plot cannot show: the fitted amplitude +against the spectrum's own reading at that frequency. A row marked ✱ has an amplitude +entangled with a correlated neighbour, so it means something only alongside it. + +The header line carries the part of the result that is easy to lose in a table: *why the +extraction stopped*, the residual scatter, and which uncertainty estimator produced the +error bars. +""" + +from __future__ import annotations + +import csv +import math + +from cuperiod.gui.qt import Qt, QtCore, QtGui, QtWidgets, Signal +from cuperiod.prewhiten.result import PreWhitenResult, Sinusoid + +#: Column definitions: (header, tooltip, attribute, format). +_COLUMNS: tuple[tuple[str, str, str, str], ...] = ( + ("ID", "Extraction order (F1 was the strongest peak of the original data)", + "label", "s"), + ("frequency", "Frequency in cycles/day", "frequency", "g"), + ("± f", "1-sigma frequency uncertainty (cycles/day)", "frequency_error", "e"), + ("period (d)", "Period in days", "period", "g"), + ("amplitude", "Amplitude in the light curve's units", "amplitude", "g"), + ("± A", "1-sigma amplitude uncertainty", "amplitude_error", "e"), + ("A/Asp", + "Fitted amplitude over the spectrum's own reading at this frequency. 1.0 means " + "they agree. Far from 1 (marked ✱) means this amplitude is entangled with a " + "correlated neighbour — often the mode's own alias sidelobe — and should be " + "quoted together with it, not alone. It is not a significance test.", + "amplitude_ratio", "f"), + ("phase", "Phase in radians at the solution's reference epoch", "phase", "f"), + ("± ph", "1-sigma phase uncertainty (radians)", "phase_error", "e"), + ("S/N", "Amplitude over the local noise of the residual spectrum (Breger)", + "snr", "f"), + ("FAP", "False-alarm probability of the peak when it was extracted", "fap", "e"), + ("combination", "Identification as a combination of stronger components", + "combination", "s"), +) + +#: Minimum width so the frequency and its uncertainty are readable without resizing. +_MIN_TABLE_WIDTH = 460 + + +def _format(value: object, kind: str) -> str: + if kind == "s": + return "" if value is None else str(value) + number = float(value) # type: ignore[arg-type] + if not math.isfinite(number): + return "—" + if kind == "e": + return f"{number:.3g}" + if kind == "f": + return f"{number:.4f}" + return f"{number:.9g}" + + +class _NumericItem(QtWidgets.QTableWidgetItem): + """A table item that sorts by its numeric value rather than its display text. + + The sort key is kept on the instance rather than written to ``EditRole``: + :class:`QTableWidgetItem` stores ``EditRole`` and ``DisplayRole`` in the same slot, + so a float written there silently replaces the formatted text with Qt's own + six-significant-digit rendering — which is not enough digits for a frequency and + too many for an uncertainty. + """ + + def __init__(self, value: float, text: str) -> None: + super().__init__(text) + self._value = float(value) + + def __lt__(self, other: QtWidgets.QTableWidgetItem) -> bool: + if isinstance(other, _NumericItem): + return self._value < other._value + return super().__lt__(other) + + +class SolutionPanel(QtWidgets.QWidget): + """Summary line plus the table of extracted sinusoids.""" + + component_selected = Signal(object) # Sinusoid + + def __init__(self, parent: QtWidgets.QWidget | None = None) -> None: + super().__init__(parent) + self._components: list[Sinusoid] = [] + self._result: PreWhitenResult | None = None + self.setMinimumWidth(_MIN_TABLE_WIDTH) + + layout = QtWidgets.QVBoxLayout(self) + layout.setContentsMargins(6, 6, 6, 6) + layout.setSpacing(6) + + self._summary = QtWidgets.QLabel("No frequency solution yet.") + self._summary.setObjectName("muted") + self._summary.setWordWrap(True) + self._summary.setToolTip( + "How the extraction ended, the residual scatter, and the error model" + ) + layout.addWidget(self._summary) + + self._table = QtWidgets.QTableWidget() + self._table.setMinimumWidth(_MIN_TABLE_WIDTH) + self._table.setSelectionBehavior( + QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows + ) + self._table.setSelectionMode( + QtWidgets.QAbstractItemView.SelectionMode.ExtendedSelection + ) + self._table.setEditTriggers( + QtWidgets.QAbstractItemView.EditTrigger.NoEditTriggers + ) + self._table.setSortingEnabled(True) + header = self._table.verticalHeader() + if header is not None: + header.setVisible(False) + self._table.itemSelectionChanged.connect(self._on_selection) + self._table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) + self._table.customContextMenuRequested.connect(self._on_context_menu) + copy_shortcut = QtGui.QShortcut( + QtGui.QKeySequence.StandardKey.Copy, self._table + ) + copy_shortcut.activated.connect(self._copy_selected) + layout.addWidget(self._table, 1) + + # -- data -------------------------------------------------------------------- + def set_solution(self, result: PreWhitenResult) -> None: + """Populate the summary and the component table from ``result``.""" + self._result = result + self._components = list(result.components) + self._summary.setText(self._summary_text(result)) + self._fill_table() + + @staticmethod + def _summary_text(result: PreWhitenResult) -> str: + pruned = ( + f" · {result.n_pruned} pruned" if result.n_pruned else "" + ) + combinations = ( + f" · {len(result.combinations)} combination" + f"{'' if len(result.combinations) == 1 else 's'}" + if result.combinations + else "" + ) + blended = ( + f" · {result.n_blended} blended ✱" if result.n_blended else "" + ) + return ( + f"{result.n_components} components{pruned}{combinations}" + f"{blended}
" + f"stopped: {result.stop_reason}
" + f"residual rms {result.rms:.4g} · reduced χ² {result.reduced_chi2:.3g}" + f" · D = {result.correlation_factor:.2f}" + f" · errors: {result.uncertainty_method}" + ) + + def _fill_table(self) -> None: + self._table.setSortingEnabled(False) + self._table.blockSignals(True) + self._table.clear() + self._table.setColumnCount(len(_COLUMNS)) + self._table.setHorizontalHeaderLabels([c[0] for c in _COLUMNS]) + self._table.setRowCount(len(self._components)) + for row, component in enumerate(self._components): + for column, (_, tooltip, attribute, kind) in enumerate(_COLUMNS): + value = getattr(component, attribute) + text = _format(value, kind) + if attribute == "amplitude_ratio" and component.blended: + text = f"{text} ✱" + if kind == "s": + item: QtWidgets.QTableWidgetItem = QtWidgets.QTableWidgetItem(text) + if attribute == "label": + item.setData(Qt.ItemDataRole.UserRole, component.rank) + else: + numeric = float(value) + item = _NumericItem( + numeric if math.isfinite(numeric) else float("inf"), text + ) + if component.blended and attribute in {"amplitude", "amplitude_ratio"}: + item.setToolTip(tooltip) + self._table.setItem(row, column, item) + h_header = self._table.horizontalHeader() + if h_header is not None: + h_header.setSectionResizeMode( + QtWidgets.QHeaderView.ResizeMode.ResizeToContents + ) + for column, spec in enumerate(_COLUMNS): + header_item = self._table.horizontalHeaderItem(column) + if header_item is not None: + header_item.setToolTip(spec[1]) + self._table.resizeColumnsToContents() + if self._components: + self._table.selectRow(0) + self._table.blockSignals(False) + self._table.setSortingEnabled(True) + + def clear(self) -> None: + """Empty the panel (a new curve is loading, or the analysis changed).""" + self._result = None + self._components = [] + self._summary.setText("No frequency solution yet.") + self._table.blockSignals(True) + self._table.clear() + self._table.setRowCount(0) + self._table.setColumnCount(len(_COLUMNS)) + self._table.setHorizontalHeaderLabels([c[0] for c in _COLUMNS]) + self._table.blockSignals(False) + + # -- selection --------------------------------------------------------------- + def _on_selection(self) -> None: + component = self._component_for_row(self._table.currentRow()) + if component is not None: + self.component_selected.emit(component) + + def _component_for_row(self, row: int) -> Sinusoid | None: + item = self._table.item(row, 0) + if item is None: + return None + rank = item.data(Qt.ItemDataRole.UserRole) + for component in self._components: + if component.rank == rank: + return component + return None + + # -- copy / export ----------------------------------------------------------- + def _on_context_menu(self, pos: QtCore.QPoint) -> None: + menu = QtWidgets.QMenu(self._table) + copy_action = menu.addAction("Copy selected rows") + copy_action.triggered.connect(self._copy_selected) + export_action = menu.addAction("Export CSV…") + export_action.triggered.connect(self._export_csv) + viewport = self._table.viewport() + anchor = viewport if viewport is not None else self._table + menu.exec(anchor.mapToGlobal(pos)) + + def _copy_selected(self) -> None: + rows = sorted({index.row() for index in self._table.selectedIndexes()}) + if not rows: + return + lines = ["\t".join(c[0] for c in _COLUMNS)] + lines += ["\t".join(self._row_text(row)) for row in rows] + clipboard = QtWidgets.QApplication.clipboard() + if clipboard is not None: + clipboard.setText("\n".join(lines)) + + def _row_text(self, row: int) -> list[str]: + cells = [] + for column in range(self._table.columnCount()): + item = self._table.item(row, column) + cells.append(item.text() if item is not None else "") + return cells + + def _export_csv(self) -> None: + path, _ = QtWidgets.QFileDialog.getSaveFileName( + self, "Export frequency solution", "frequencies.csv", "CSV files (*.csv)" + ) + if path: + self.export_csv(path) + + def export_csv(self, path: str) -> None: + """Write the full solution (all fields, full precision) to ``path`` as CSV.""" + rows = self._result.to_table() if self._result is not None else [] + fields = list(rows[0]) if rows else [c[2] for c in _COLUMNS] + with open(path, "w", newline="", encoding="utf-8") as fh: + writer = csv.DictWriter(fh, fieldnames=fields) + writer.writeheader() + writer.writerows(rows) + + +__all__ = ["SolutionPanel"] diff --git a/src/cuperiod/gui/widgets/spacing_panel.py b/src/cuperiod/gui/widgets/spacing_panel.py new file mode 100644 index 0000000..db9a054 --- /dev/null +++ b/src/cuperiod/gui/widgets/spacing_panel.py @@ -0,0 +1,262 @@ +"""The g-mode period-spacing explorer. + +Given a frequency solution, this panel answers the two questions a γ Dor or SPB analysis +asks next: *is there a regular spacing?* and *which modes belong to it?* The comb +spectrum on the left scans trial spacings; the échelle diagram on the right folds the +member periods on the spacing that was found, where a clean series shows up as a +near-vertical ridge and the tilt from rotation as a slant. + +It runs on demand rather than automatically — the search is only meaningful once the +extraction has finished, and only for g-mode pulsators — and always on the *independent* +components, so identified combination frequencies cannot pollute the pattern. +""" + +from __future__ import annotations + +import numpy as np + +from cuperiod.core.config import SpacingSettings +from cuperiod.gui.qt import QtWidgets, pg +from cuperiod.gui.theme import ThemePalette, apply_plot_theme, palette, plot_label_style +from cuperiod.prewhiten.result import PreWhitenResult +from cuperiod.prewhiten.spacing import ( + echelle, + find_period_spacing, + spacing_spectrum, +) + +#: Seconds per day, for reporting spacings in the units the literature uses. +_SECONDS_PER_DAY = 86400.0 + +#: Fewest independent modes worth running a comb search on. +_MIN_MODES = 4 + +#: How many multiples of the best spacing the comb plot frames after a search. +_COMB_VIEW_FACTOR = 6.0 + + +class SpacingPanel(QtWidgets.QWidget): + """Comb-spectrum scan, échelle diagram, and the fitted period-spacing series.""" + + def __init__( + self, theme: str = "dark", parent: QtWidgets.QWidget | None = None + ) -> None: + super().__init__(parent) + self._pal: ThemePalette = palette(theme) # type: ignore[arg-type] + self._result: PreWhitenResult | None = None + + root = QtWidgets.QVBoxLayout(self) + root.setContentsMargins(6, 6, 6, 6) + root.setSpacing(6) + root.addWidget(self._build_controls()) + + self._summary = QtWidgets.QLabel( + "Run pre-whitening, then search for a spacing." + ) + self._summary.setObjectName("muted") + self._summary.setWordWrap(True) + root.addWidget(self._summary) + + splitter = QtWidgets.QSplitter() + self._comb = pg.PlotWidget() + self._comb.setMenuEnabled(False) + self._comb.showGrid(x=True, y=True, alpha=0.18) + style = plot_label_style(self._pal) + self._comb.setLabel("bottom", "Trial spacing ΔP (s)", **style) + self._comb.setLabel("left", "Comb response", **style) + self._comb_curve = self._comb.plot( + [], [], pen=pg.mkPen(self._pal.curve, width=1) + ) + self._comb_marker = pg.InfiniteLine( + angle=90, pen=pg.mkPen(self._pal.qcolor(self._pal.accent, 200), width=2) + ) + self._comb_marker.setVisible(False) + self._comb.addItem(self._comb_marker) + splitter.addWidget(self._comb) + + self._echelle = pg.PlotWidget() + self._echelle.setMenuEnabled(False) + self._echelle.showGrid(x=True, y=True, alpha=0.18) + self._echelle.setLabel("bottom", "P mod ΔP (s)", **style) + self._echelle.setLabel("left", "Period (d)", **style) + self._echelle_points = pg.ScatterPlotItem(pxMode=True) + self._echelle.addItem(self._echelle_points) + splitter.addWidget(self._echelle) + splitter.setSizes([500, 400]) + root.addWidget(splitter, 1) + + for plot in (self._comb, self._echelle): + apply_plot_theme(plot, self._pal) + self._set_enabled(False) + + # -- construction ------------------------------------------------------------ + def _build_controls(self) -> QtWidgets.QWidget: + bar = QtWidgets.QWidget() + row = QtWidgets.QHBoxLayout(bar) + row.setContentsMargins(0, 0, 0, 0) + row.setSpacing(8) + + row.addWidget(QtWidgets.QLabel("ℓ:")) + self._ell_spin = QtWidgets.QSpinBox() + self._ell_spin.setRange(1, 4) + self._ell_spin.setValue(1) + self._ell_spin.setToolTip( + "Spherical degree assumed when converting the mean spacing to a " + "buoyancy radius Π₀ (dipole modes dominate γ Dor and SPB spectra)" + ) + row.addWidget(self._ell_spin) + + row.addWidget(QtWidgets.QLabel("tolerance:")) + self._tolerance_spin = QtWidgets.QDoubleSpinBox() + self._tolerance_spin.setRange(0.01, 1.0) + self._tolerance_spin.setSingleStep(0.05) + self._tolerance_spin.setValue(SpacingSettings().tolerance) + self._tolerance_spin.setToolTip( + "How far an observed spacing may sit from the tilted model, as a fraction " + "of the local spacing" + ) + row.addWidget(self._tolerance_spin) + + row.addWidget(QtWidgets.QLabel("max gap:")) + self._gap_spin = QtWidgets.QSpinBox() + self._gap_spin.setRange(1, 8) + self._gap_spin.setValue(SpacingSettings().max_gap) + self._gap_spin.setToolTip( + "Largest number of consecutive missing radial orders bridged in a series" + ) + row.addWidget(self._gap_spin) + + self._search_btn = QtWidgets.QPushButton("Find period spacing") + self._search_btn.setToolTip( + "Scan for a regular period spacing among the independent components" + ) # noqa: E501 + self._search_btn.clicked.connect(self.search) + row.addWidget(self._search_btn) + row.addStretch(1) + return bar + + def _set_enabled(self, enabled: bool) -> None: + for widget in ( + self._search_btn, + self._ell_spin, + self._tolerance_spin, + self._gap_spin, + ): + widget.setEnabled(enabled) + + # -- data -------------------------------------------------------------------- + def set_solution(self, result: PreWhitenResult) -> None: + """Attach a new frequency solution (does not search until asked).""" + self._result = result + n = len(result.independent()) + self._set_enabled(n >= _MIN_MODES) + self._clear_plots() + if n < _MIN_MODES: + self._summary.setText( + f"Only {n} independent component{'' if n == 1 else 's'} — a period-" + f"spacing search needs at least {_MIN_MODES}." + ) + else: + self._summary.setText( + f"{n} independent components ready — press “Find period spacing”." + ) + + def clear(self) -> None: + """Reset the panel (a new curve is loading, or the analysis changed).""" + self._result = None + self._set_enabled(False) + self._clear_plots() + self._summary.setText("Run pre-whitening, then search for a spacing.") + + def _clear_plots(self) -> None: + self._comb_curve.setData([], []) + self._comb_marker.setVisible(False) + self._echelle_points.clear() + + # -- search ------------------------------------------------------------------ + def search(self) -> None: + """Run the comb scan and the series extraction on the current solution.""" + result = self._result + if result is None: + return + components = result.independent() + if len(components) < _MIN_MODES: + return + periods = np.asarray([c.period for c in components], dtype=np.float64) + amplitudes = np.asarray([c.amplitude for c in components], dtype=np.float64) + settings = SpacingSettings( + tolerance=self._tolerance_spin.value(), + max_gap=self._gap_spin.value(), + ell=self._ell_spin.value(), + ) + try: + comb = spacing_spectrum( + periods, + weights=amplitudes, + minimum_spacing=settings.minimum_spacing, + maximum_spacing=settings.maximum_spacing, + oversample=settings.oversample, + ) + series = find_period_spacing(periods, amplitudes, settings=settings) + except ValueError as exc: + self._summary.setText(f"Could not search for a spacing: {exc}") + self._clear_plots() + return + + best_seconds = comb.best_spacing * _SECONDS_PER_DAY + self._comb_curve.setData(comb.spacing * _SECONDS_PER_DAY, comb.power) + self._comb_marker.setPos(best_seconds) + self._comb_marker.setVisible(True) + self._comb.enableAutoRange(axis="y") + # The trial range runs out to the full period span, which crushes the peak into + # the left edge; frame it instead, and leave panning/zooming to the user. + self._comb.setXRange(0.0, _COMB_VIEW_FACTOR * best_seconds, padding=0.02) + + if series is None: + self._summary.setText( + f"Comb peak at ΔP = {comb.best_spacing * _SECONDS_PER_DAY:.1f} s " + f"(response {comb.best_power:.2f}), but no chain of at least " + f"{settings.min_length} modes follows it — try a larger tolerance." + ) + self._echelle_points.clear() + return + + member = set(series.indices) + spacing = series.mean_spacing + x_all, y_all = echelle(periods, spacing) + spots = [ + { + "pos": (float(x * _SECONDS_PER_DAY), float(y)), + "size": 12 if i in member else 8, + "symbol": "o", + "brush": pg.mkBrush( + self._pal.best_peak if i in member else self._pal.muted + ), + "pen": pg.mkPen(self._pal.plot_bg, width=1), + } + for i, (x, y) in enumerate(zip(x_all, y_all, strict=True)) + ] + self._echelle_points.setData(spots) + self._echelle.enableAutoRange() + self._echelle.autoRange() + self._summary.setText( + f"{series.n_modes} of {len(components)} modes in one series · " + f"⟨ΔP⟩ = {spacing * _SECONDS_PER_DAY:.1f} s · " + f"slope {series.slope:+.4g} · " + f"rms {series.rms * _SECONDS_PER_DAY:.1f} s · " + f"Π₀(ℓ={series.ell}) = {series.buoyancy_radius:.0f} s" + ) + + # -- theme ------------------------------------------------------------------- + def apply_theme(self, theme_palette: ThemePalette) -> None: + """Re-pen the plots for a new theme (live re-skin).""" + self._pal = theme_palette + self._comb_curve.setPen(pg.mkPen(theme_palette.curve, width=1)) + self._comb_marker.setPen( + pg.mkPen(theme_palette.qcolor(theme_palette.accent, 200), width=2) + ) + for plot in (self._comb, self._echelle): + apply_plot_theme(plot, theme_palette) + + +__all__ = ["SpacingPanel"] diff --git a/src/cuperiod/gui/widgets/spectrum_view.py b/src/cuperiod/gui/widgets/spectrum_view.py index 1d279f6..42598aa 100644 --- a/src/cuperiod/gui/widgets/spectrum_view.py +++ b/src/cuperiod/gui/widgets/spectrum_view.py @@ -4,12 +4,24 @@ pan/zoom smooth on 10^5-10^6 points), overlays the significant peaks, and marks the selection with a **translucent shaded band** drawn behind the curve — so the peak stays visible — that is draggable and emits :attr:`period_selected` (snapped to the nearest -grid sample). A crosshair reads out frequency/period/power under the cursor. +grid sample). Markers and band form one layer that the *peaks* toggle shows or hides +together; the selection itself survives being hidden. A crosshair reads out +frequency/period/power under the cursor. The x-axis toggles frequency/period (arrays are reversed in period mode so x stays ascending, as pyqtgraph's clip/downsample require) and each axis toggles linear/log. -Display adapts to the objective sense: for minimise methods (PDM/CE/string-length) the -peaks are minima and the y-axis is labelled accordingly. +Double-clicking anywhere restores the default, auto-ranged view. Display adapts to the +objective sense: for minimise methods (PDM/CE/string-length) the peaks are minima and +the y-axis is labelled accordingly. + +The same view serves pre-whitening: the main curve becomes the amplitude spectrum of +the data, an optional **overlay** curve shows the spectrum of the residuals once every +extracted component has been subtracted, and the peak markers become the components. +That side-by-side is the whole point of the method — what was there, and what is left. +A third, dashed trace can show the **spectral window** of the sampling (scaled to the +tallest peak, Period04-style) so an alias lobe is recognisable at a glance. The dense +data curve draws over both, so it has its own toggle: hide it and the residual and +window become readable on their own. """ from __future__ import annotations @@ -31,6 +43,9 @@ _MIN_OBJECTIVE_LABEL = "dispersion (lower = better)" +#: Method name carried by the synthetic Periodogram that wraps an amplitude spectrum. +PREWHITEN_METHOD = "Pre-whitening" + class SpectrumView(QtWidgets.QWidget): """Full-resolution spectrum with peak markers, a selection band, and a crosshair.""" @@ -77,6 +92,26 @@ def __init__( self._curve.setClipToView(True) self._curve.setZValue(0) + # Optional second trace (the pre-whitened residual spectrum), drawn over the + # main curve so what is *left* stays readable against what was there. + self._overlay = self._plot.plot( + [], [], pen=pg.mkPen(self._pal.qcolor(self._pal.accent, 220), width=1) + ) + self._overlay.setDownsampling(auto=True, method="peak") + self._overlay.setClipToView(True) + self._overlay.setZValue(1) + self._overlay.setVisible(False) + self._overlay_xy: tuple[np.ndarray, np.ndarray] | None = None + + # The spectral window of the sampling (dashed, behind the data curve): the + # alias-lobe pattern every real peak is convolved with. + self._window_curve = self._plot.plot([], [], pen=self._window_pen()) + self._window_curve.setDownsampling(auto=True, method="peak") + self._window_curve.setClipToView(True) + self._window_curve.setZValue(-5) + self._window_curve.setVisible(False) + self._window_xy: tuple[np.ndarray, np.ndarray] | None = None + self._markers = pg.ScatterPlotItem(hoverable=True, pxMode=True) self._markers.setZValue(5) self._markers.sigClicked.connect(self._on_peak_clicked) @@ -95,6 +130,9 @@ def __init__( self._proxy = pg.SignalProxy( self._plot.scene().sigMouseMoved, rateLimit=60, slot=self._on_mouse_moved ) + # Double-click anywhere in the plot restores the default view, the shortcut + # every plotting tool has and pyqtgraph leaves unbound. + self._plot.scene().sigMouseClicked.connect(self._on_scene_clicked) self._plot.getPlotItem().vb.sigXRangeChanged.connect(self._on_xrange_changed) apply_plot_theme(self._plot, self._pal) @@ -103,12 +141,21 @@ def _build_toolbar(self) -> QtWidgets.QWidget: bar = QtWidgets.QWidget() row = QtWidgets.QHBoxLayout(bar) row.setContentsMargins(6, 2, 6, 2) - row.setSpacing(8) + # Tight spacing: with the pre-whitening toggles shown the row is the widest + # thing in the dock, and buttons must not get squeezed into ellipses. + row.setSpacing(6) row.addWidget(QtWidgets.QLabel("x:")) self._xaxis_combo = QtWidgets.QComboBox() self._xaxis_combo.addItems(["frequency", "period"]) self._xaxis_combo.setToolTip("Plot the x-axis as frequency or period") + # Never squeeze the combo into an elided "frequen…" when the row gets tight; + # shortage lands on the stretchable readout instead. The explicit minimum is + # needed because a combo's minimum size ignores its contents by default. + self._xaxis_combo.setSizeAdjustPolicy( + QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToContents + ) + self._xaxis_combo.setMinimumWidth(self._xaxis_combo.sizeHint().width()) self._xaxis_combo.currentTextChanged.connect(self._on_xaxis_changed) row.addWidget(self._xaxis_combo) @@ -123,11 +170,49 @@ def _build_toolbar(self) -> QtWidgets.QWidget: self._show_peaks = QtWidgets.QCheckBox("peaks") self._show_peaks.setChecked(True) + self._show_peaks.setToolTip( + "Mark the significant peaks, and shade the selected one. Turn it off for " + "an unobstructed view of the spectrum itself" + ) self._show_peaks.toggled.connect(self._on_peaks_toggled) row.addWidget(self._show_peaks) - reset = QtWidgets.QPushButton("Reset view") - reset.setToolTip("Auto-range the plot back to the full spectrum") + # Only offered once there is an overlay to read: hiding the data curve of a + # plain periodogram would just leave an empty plot. + self._show_data = QtWidgets.QCheckBox("data") + self._show_data.setChecked(True) + self._show_data.setToolTip( + "Show the amplitude spectrum of the data. Turn it off to read the " + "residual and window traces, which it otherwise draws over" + ) + self._show_data.setVisible(False) + self._show_data.toggled.connect(self._redraw_curve) + row.addWidget(self._show_data) + + self._show_residual = QtWidgets.QCheckBox("residual") + self._show_residual.setChecked(True) + self._show_residual.setToolTip( + "Overlay the amplitude spectrum of the residuals after pre-whitening" + ) + self._show_residual.setVisible(False) + self._show_residual.toggled.connect(self._redraw_overlay) + row.addWidget(self._show_residual) + + self._show_window = QtWidgets.QCheckBox("window") + self._show_window.setChecked(False) + self._show_window.setToolTip( + "Overlay the spectral window of the sampling (scaled to the tallest " + "peak): a peak sitting on another's window lobe is likely an alias" + ) + self._show_window.setVisible(False) + self._show_window.toggled.connect(self._redraw_window) + row.addWidget(self._show_window) + + reset = QtWidgets.QPushButton("Reset") + reset.setToolTip( + "Auto-range the plot back to the full spectrum " + "(or just double-click the plot)" + ) reset.clicked.connect(self._autorange) row.addWidget(reset) @@ -151,17 +236,74 @@ def _build_toolbar(self) -> QtWidgets.QWidget: # -- data -------------------------------------------------------------------- def set_periodogram(self, pg_result: Periodogram) -> None: - """Show a new spectrum (clears peaks and the selection band).""" + """Show a new spectrum (clears peaks, the overlay, and the selection band).""" self._pg = pg_result self._peaks = [] self._sel_period = None self._markers.clear() - self._sel_band.setVisible(False) + self._sync_band() + self._overlay_xy = None + self._show_residual.setVisible(False) + self._window_xy = None + self._show_window.setVisible(False) + self._window_curve.setVisible(False) + self._show_data.setVisible(False) + self._show_data.setChecked(True) self._default_axis_for(pg_result) self._redraw_curve() self._update_y_label() self._autorange() + def set_overlay(self, frequency: np.ndarray, values: np.ndarray) -> None: + """Add a second trace on the same grid (the pre-whitened residual spectrum).""" + self._overlay_xy = ( + np.asarray(frequency, dtype=np.float64), + np.asarray(values, dtype=np.float64), + ) + self._show_residual.setVisible(True) + self._show_data.setVisible(True) + self._redraw_overlay() + + def clear_overlay(self) -> None: + """Remove the second trace and hide its toggle.""" + self._overlay_xy = None + self._show_residual.setVisible(False) + self._overlay.setVisible(False) + self._overlay.setData([], []) + self._sync_data_toggle() + + def set_window( + self, frequency: np.ndarray, amplitude: np.ndarray, *, scale: float = 1.0 + ) -> None: + """Provide the sampling's spectral window ``|W(f)|``, scaled by ``scale``. + + ``|W|`` is dimensionless (1 at zero frequency); ``scale`` is normally the + tallest amplitude of the displayed spectrum, which is how Period04 overlays the + two. The trace stays hidden until the ``window`` toggle is checked. + """ + factor = float(scale) if np.isfinite(scale) and scale > 0.0 else 1.0 + self._window_xy = ( + np.asarray(frequency, dtype=np.float64), + np.asarray(amplitude, dtype=np.float64) * factor, + ) + self._show_window.setVisible(True) + self._show_data.setVisible(True) + self._redraw_window() + + def clear_window(self) -> None: + """Remove the spectral-window trace and hide its toggle.""" + self._window_xy = None + self._show_window.setVisible(False) + self._window_curve.setVisible(False) + self._window_curve.setData([], []) + self._sync_data_toggle() + + def _sync_data_toggle(self) -> None: + """Offer the data toggle only while an overlay could be read underneath it.""" + if self._overlay_xy is None and self._window_xy is None: + self._show_data.setVisible(False) + self._show_data.setChecked(True) # never leave the plot empty + def set_peaks(self, peaks: list[Peak]) -> None: """Overlay the significant peaks as markers.""" self._peaks = list(peaks) @@ -172,10 +314,22 @@ def set_selected_period(self, period: float) -> None: if self._pg is None or not np.isfinite(period) or period <= 0.0: return self._sel_period = period - self._sel_band.setVisible(True) + self._sync_band() self._update_band() self._redraw_markers() # re-place the selected-peak halo + def _sync_band(self) -> None: + """The band is shown iff something is selected *and* peaks are being marked. + + It shades a peak, so it belongs to the peak layer: leaving it behind when the + markers are hidden would keep the one piece of clutter the toggle is usually + turned off to be rid of. The selection itself survives, band and all, and + comes back with the markers. + """ + self._sel_band.setVisible( + self._sel_period is not None and self._show_peaks.isChecked() + ) + def clear(self) -> None: """Clear the spectrum, peaks, and selection (e.g. when a new curve loads).""" self._pg = None @@ -183,9 +337,11 @@ def clear(self) -> None: self._sel_period = None self._curve.setData([], []) self._markers.clear() - self._sel_band.setVisible(False) + self._sync_band() self._hover_text.setVisible(False) self._readout.setText("—") + self.clear_overlay() + self.clear_window() def clear_selection(self) -> None: """Hide the selection band (e.g. a compute finished with zero peaks). @@ -193,7 +349,7 @@ def clear_selection(self) -> None: Unlike :meth:`clear`, the spectrum curve/peaks themselves are left alone. """ self._sel_period = None - self._sel_band.setVisible(False) + self._sync_band() self._redraw_markers() # -- drawing ----------------------------------------------------------------- @@ -209,8 +365,39 @@ def _redraw_curve(self) -> None: return x, y = self._curve_xy() self._curve.setData(x, y) + self._curve.setVisible(self._show_data.isChecked()) + self._redraw_overlay() + self._redraw_window() self._apply_log() + def _trace_xy( + self, data: tuple[np.ndarray, np.ndarray] + ) -> tuple[np.ndarray, np.ndarray]: + """An auxiliary trace re-oriented for the current x mode.""" + frequency, values = data + if self._x_mode == "period": + with np.errstate(divide="ignore"): + return (1.0 / frequency)[::-1], values[::-1] + return frequency, values + + def _redraw_overlay(self) -> None: + """Re-place the second trace for the current x mode, or hide it.""" + if self._overlay_xy is None or not self._show_residual.isChecked(): + self._overlay.setVisible(False) + return + x, y = self._trace_xy(self._overlay_xy) + self._overlay.setData(x, y) + self._overlay.setVisible(True) + + def _redraw_window(self) -> None: + """Re-place the spectral-window trace for the current x mode, or hide it.""" + if self._window_xy is None or not self._show_window.isChecked(): + self._window_curve.setVisible(False) + return + x, y = self._trace_xy(self._window_xy) + self._window_curve.setData(x, y) + self._window_curve.setVisible(True) + def _selected_index(self) -> int | None: """Index into :attr:`_peaks` matching the current selection, if any.""" if self._sel_period is None or not self._peaks: @@ -222,6 +409,12 @@ def _selected_index(self) -> int | None: return None def _redraw_markers(self) -> None: + # The hover label is anchored to a marker in plot coordinates, so any redraw + # invalidates it: hiding the peaks would stranded it over an empty plot, a new + # result would leave the old one's numbers floating, and a log/axis switch + # would park it at coordinates that no longer mean anything. It reappears on + # the next hover event, which fires on every mouse move over a marker. + self._hover_text.setVisible(False) if self._pg is None or not self._show_peaks.isChecked(): self._markers.clear() return @@ -279,7 +472,9 @@ def _update_y_label(self) -> None: if self._pg is None: return style = plot_label_style(self._pal) - if self._pg.objective_sense == "min": + if self._pg.method == PREWHITEN_METHOD: + text = "Amplitude" + elif self._pg.objective_sense == "min": text = f"{self._pg.method} {_MIN_OBJECTIVE_LABEL}" else: text = f"{self._pg.method} power" @@ -325,15 +520,20 @@ def _apply_log(self) -> None: def _on_peaks_toggled(self, _checked: bool) -> None: self._redraw_markers() + self._sync_band() def _autorange(self) -> None: # Disable clip-to-view first: with it on, auto-ranging after a data-range change # fits only the previously-visible slice, so the view sticks (e.g. a BLS peak - # ends up off-screen). Re-enable it once the view spans the full data. - self._curve.setClipToView(False) + # ends up off-screen). Re-enable it once the view spans the full data. All three + # traces need it — with the data curve hidden, the overlays set the range. + traces = (self._curve, self._overlay, self._window_curve) + for trace in traces: + trace.setClipToView(False) self._plot.enableAutoRange() self._plot.autoRange() - self._curve.setClipToView(True) + for trace in traces: + trace.setClipToView(True) # -- selection band ---------------------------------------------------------- def _update_band(self) -> None: @@ -359,6 +559,12 @@ def _on_band_moved(self) -> None: def _on_xrange_changed(self, *_: Any) -> None: self._update_band() + def _on_scene_clicked(self, event: Any) -> None: + """Restore the default view on a double-click (same as the Reset button).""" + if event.double(): + self._autorange() + event.accept() + # -- conversions ------------------------------------------------------------- def _x_for_period(self, period: float) -> float: if self._x_mode == "period": @@ -413,15 +619,37 @@ def _on_peak_hovered(self, _item: Any, points: Any) -> None: return idx = pts[0].data() if idx is None or idx >= len(self._peaks): + # A glow halo carries no index; keeping the previous peak's label up while + # the cursor sits on a different one would simply be wrong. + self._hover_text.setVisible(False) return peak = self._peaks[int(idx)] x = peak.frequency if self._x_mode == "frequency" else peak.period self._hover_text.setText( - f"#{peak.rank} P={peak.period:.6g} d\npower={peak.power:.4g}" + f"#{peak.rank} P={peak.period:.6g} d\n{self._peak_detail(peak)}" ) self._hover_text.setPos(self._to_plot_x(x), self._to_plot_y(peak.power)) self._hover_text.setVisible(True) + @staticmethod + def _peak_detail(peak: Peak) -> str: + """The hover line under a marker: fitted amplitude and S/N when present. + + A pre-whitening marker is drawn at the height of the *spectrum*, so its fitted + amplitude — which can differ once components are correlated — has to be read + out here rather than inferred from where the marker sits. + """ + amplitude = peak.extra.get("amplitude") + if amplitude is None: + return f"power={peak.power:.4g}" + detail = f"A={amplitude:.4g}" + snr = peak.extra.get("snr") + if snr is not None and np.isfinite(snr): + detail += f" S/N={snr:.1f}" + if peak.extra.get("blended"): + detail += "\nblended — amplitude disagrees with the spectrum" + return detail + def _on_mouse_moved(self, event: Any) -> None: if self._pg is None: return @@ -486,10 +714,20 @@ def export_png(self, path: str) -> None: def _crosshair_pen(self) -> object: return pg.mkPen(self._pal.muted, width=1, style=Qt.PenStyle.DashLine) + def _window_pen(self) -> object: + return pg.mkPen( + self._pal.qcolor(self._pal.muted, 200), width=1, + style=Qt.PenStyle.DashLine, + ) + def apply_theme(self, theme_palette: ThemePalette) -> None: """Re-pen the plot items for a new theme (live re-skin).""" self._pal = theme_palette self._curve.setPen(pg.mkPen(theme_palette.curve, width=1)) + self._overlay.setPen( + pg.mkPen(theme_palette.qcolor(theme_palette.accent, 220), width=1) + ) + self._window_curve.setPen(self._window_pen()) band_brush = pg.mkBrush(theme_palette.qcolor(theme_palette.accent, 45)) self._sel_band.setBrush(band_brush) band_pen = pg.mkPen(theme_palette.qcolor(theme_palette.accent, 170), width=1) @@ -502,4 +740,4 @@ def apply_theme(self, theme_palette: ThemePalette) -> None: self._redraw_markers() -__all__ = ["SpectrumView"] +__all__ = ["PREWHITEN_METHOD", "SpectrumView"] diff --git a/src/cuperiod/interop/__init__.py b/src/cuperiod/interop/__init__.py new file mode 100644 index 0000000..dd6ceb9 --- /dev/null +++ b/src/cuperiod/interop/__init__.py @@ -0,0 +1,62 @@ +"""Interoperability with the LINCC Frameworks stack (nested-pandas / lsdb). + +LINCC's survey tables keep a star's light curve *inside* its object row: one row per +object, the per-epoch arrays in a nested column (nested-pandas ``NestedFrame``), and +``lsdb`` spreads that frame over the dask partitions of a HATS catalog. This package +runs cuPeriod directly on that layout — no flattening, no ``groupby``, no per-object +DataFrames — in two tiers that share their column handling and output columns: + +Tier 1, :func:`~cuperiod.interop.lincc.nested_periodogram` (row-wise) + Wraps ``map_rows``: one light curve per row, one periodogram per row, results + appended as ordinary base columns. The simple, composable default — right for a + CPU backend, a quick look, or a small catalog. + +Tier 2, :func:`~cuperiod.interop.lincc.partition_periodogram` (partition-wise) + Reads a whole partition's nested column once through its Arrow buffers, slices + each object out of the flat arrays, and evaluates the entire partition against + **one** method engine built per partition. GPU plan/kernel setup is amortized over + thousands of stars instead of paid per star — the throughput tier. + +Both accept an in-memory ``NestedFrame`` or a lazy lsdb ``Catalog`` (which stays lazy), +resolve their columns from the nest's schema alone (never by computing), and turn a +failed object into NaN result columns rather than an aborted run. + +This package is optional: ``pip install 'cuperiod[nested]'`` (add lsdb with +``'cuperiod[lsdb]'``). Importing :mod:`cuperiod` never pulls in nested-pandas, and +importing this package does not either — the dependency is checked on first use, so +even :data:`COLUMN_PRESETS` can be inspected without it. + +Examples +-------- +>>> from cuperiod.interop import nested_periodogram # doctest: +SKIP +>>> out = nested_periodogram(frame, "lc", preset="ztf_dr22") # doctest: +SKIP +""" + +from __future__ import annotations + +from cuperiod.interop.lincc import COLUMN_PRESETS as _COLUMN_PRESETS +from cuperiod.interop.lincc import ( + PRESET_KEYS, + NestedColumns, + nested_periodogram, + partition_periodogram, + require_nested_pandas, + resolve_nested_columns, +) + +#: Column presets for common survey layouts, keyed by preset name — currently +#: ``"ztf_dr22"``, ``"ztf_alerts"``, ``"rubin_dp1_object"``, and +#: ``"rubin_dp1_dia"``. Each value is the keyword mapping that +#: :func:`~cuperiod.interop.lincc.resolve_nested_columns` expands into a +#: :class:`~cuperiod.interop.lincc.NestedColumns`; pass the key as ``preset=``. +COLUMN_PRESETS = _COLUMN_PRESETS + +__all__ = [ + "COLUMN_PRESETS", + "PRESET_KEYS", + "NestedColumns", + "nested_periodogram", + "partition_periodogram", + "require_nested_pandas", + "resolve_nested_columns", +] diff --git a/src/cuperiod/interop/lincc.py b/src/cuperiod/interop/lincc.py new file mode 100644 index 0000000..4d39890 --- /dev/null +++ b/src/cuperiod/interop/lincc.py @@ -0,0 +1,891 @@ +"""Adapters for LINCC Frameworks light curves (nested-pandas / lsdb). + +The two public entry points are :func:`nested_periodogram` (row-wise) and +:func:`partition_periodogram` (partition-wise, engine-reusing). See the package +docstring of :mod:`cuperiod.interop` for the tier overview. + +Nothing here imports nested-pandas, pandas, lsdb, or dask at module scope: the module +is importable in a bare cuPeriod install, and the LINCC stack is touched only when a +function actually runs (:func:`require_nested_pandas`). +""" + +from __future__ import annotations + +from collections.abc import Iterable, Mapping +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, Any, Final + +import numpy as np +from pydantic_settings import BaseSettings + +from cuperiod.api import _multiband_grid +from cuperiod.core.columns import ColumnMap, Domain +from cuperiod.core.errors import ColumnResolutionError +from cuperiod.core.grid import GridSpec +from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve +from cuperiod.core.result import Periodogram +from cuperiod.methods.base import PeriodogramMethod, get_method + +if TYPE_CHECKING: # pragma: no cover - typing only + import pandas as pd + +#: Sentinel default for the ``nested`` parameter, so a preset can supply its own nest +#: name while an explicitly passed name always wins. +_DEFAULT_NEST: Final[str] = "lc" + +_NAN: Final[float] = float("nan") + +#: Per-process cache of ``(method, requested backend) -> concrete backend``. Backend +#: availability cannot change inside a run, and the row-wise tier would otherwise +#: re-probe the environment for every object. +_BACKEND_CACHE: dict[tuple[str, str], str] = {} + + +# --- optional-dependency guard ----------------------------------------------- + + +def require_nested_pandas() -> None: + """Raise a helpful :class:`ImportError` if nested-pandas is not installed. + + Raises + ------ + ImportError + With the ``pip install`` line for the ``[nested]`` extra. + """ + try: + import nested_pandas # noqa: F401 + except ImportError as exc: # pragma: no cover - exercised only without the extra + raise ImportError( + "cuperiod.interop needs nested-pandas. Install it with:\n" + " pip install 'cuperiod[nested]'\n" + "(or 'cuperiod[lsdb]' to also get lsdb for HATS catalogs)" + ) from exc + + +# --- survey column presets ---------------------------------------------------- + +#: Verified column layouts of the common LINCC-stack catalogs. Each entry carries +#: ``nested``, ``time``, ``value``, ``error``, ``band`` and ``domain``; sub-column names +#: are bare (they are prefixed with whichever nest name is in use). Pass one by name as +#: ``preset=`` to fill every column parameter you did not set yourself. +#: +#: * ``"ztf_dr22"`` — ZTF DR22 object table: nest ``lc`` with ``hmjd``/``mag``/ +#: ``magerr``/``catflags``. The band is *not* in the nest: DR22 has one row per +#: (object, filter) with the filter in the **base** column ``filterid`` +#: (1=g, 2=r, 3=i), so the preset sets ``band=None`` and each row is a single-band +#: search. A multi-band run needs a self-join that nests the per-filter rows of one +#: object into one row first (``NestedFrame.join_nested``). +#: * ``"ztf_alerts"`` — ALeRCE ZTF alert HATS catalogs: nest ``lc`` with +#: ``lc_mjd``/``lc_magpsf``/``lc_sigmapsf`` and the in-nest band ``lc_fid``. +#: * ``"rubin_dp1_object"`` / ``"rubin_dp1_dia"`` — Rubin DP1 forced photometry, +#: nest ``objectForcedSource`` / ``diaObjectForcedSource`` with ``midpointMjdTai``, +#: ``psfFlux`` (nJy), ``psfFluxErr`` and the in-nest band ``band`` (``ugrizy``). +#: Difference-imaging fluxes are legitimately negative, so both presets search in +#: :attr:`~cuperiod.Domain.FLUX` and never convert to magnitudes. +COLUMN_PRESETS: Final[dict[str, dict[str, Any]]] = { + "ztf_dr22": { + "nested": "lc", + "time": "hmjd", + "value": "mag", + "error": "magerr", + "band": None, + "domain": Domain.MAGNITUDE, + }, + "ztf_alerts": { + "nested": "lc", + "time": "lc_mjd", + "value": "lc_magpsf", + "error": "lc_sigmapsf", + "band": "lc_fid", + "domain": Domain.MAGNITUDE, + }, + "rubin_dp1_object": { + "nested": "objectForcedSource", + "time": "midpointMjdTai", + "value": "psfFlux", + "error": "psfFluxErr", + "band": "band", + "domain": Domain.FLUX, + }, + "rubin_dp1_dia": { + "nested": "diaObjectForcedSource", + "time": "midpointMjdTai", + "value": "psfFlux", + "error": "psfFluxErr", + "band": "band", + "domain": Domain.FLUX, + }, +} + +#: The keys every entry of :data:`COLUMN_PRESETS` defines. +PRESET_KEYS: Final[tuple[str, ...]] = ( + "nested", "time", "value", "error", "band", "domain", +) + + +# --- column resolution -------------------------------------------------------- + + +@dataclass(frozen=True) +class NestedColumns: + """Resolved, fully dotted column names for one nested light-curve column. + + Attributes + ---------- + nested : str + The nested column's name (e.g. ``"lc"``). + time, value : str + Dotted sub-column names (e.g. ``"lc.hmjd"``). + error, band : str or None + Dotted sub-column names, or ``None`` when absent/not requested. + domain : Domain + The brightness domain of ``value``. + """ + + nested: str + time: str + value: str + error: str | None + band: str | None + domain: Domain + + @property + def read_columns(self) -> list[str]: + """The dotted columns to request from ``map_rows``, in a stable order.""" + names = [self.time, self.value] + if self.error is not None: + names.append(self.error) + if self.band is not None: + names.append(self.band) + return names + + @property + def subcolumns(self) -> list[str]: + """The same columns as bare sub-column names.""" + return [name.split(".", 1)[1] for name in self.read_columns] + + +def _name_list(obj: Any) -> list[str] | None: + """Coerce a dtype attribute to a list of sub-column names, or ``None``.""" + if obj is None or callable(obj) or isinstance(obj, (str, bytes)): + return None + if isinstance(obj, Mapping): + return [str(k) for k in obj] + if isinstance(obj, Iterable): + return [str(k) for k in obj] + return None + + +def _subcolumn_names(dtype: Any) -> list[str]: + """Sub-column names of a ``NestedDtype``, without touching any data. + + nested-pandas renamed this attribute across releases: ``columns`` / + ``column_dtypes`` (0.7) and ``field_names`` / ``fields`` (0.6). Every spelling is + tried so one code path covers the lsdb-pinned 0.6.x line and 0.7.x. + """ + for attr in ("columns", "column_dtypes", "field_names", "fields"): + names = _name_list(getattr(dtype, attr, None)) + if names: + return names + raise TypeError( + f"{dtype!r} does not look like a nested-pandas NestedDtype: no sub-column " + "names found (tried .columns/.column_dtypes/.field_names/.fields)" + ) + + +def _nested_dtype(data: Any, nested: str) -> Any: + """The ``NestedDtype`` of column ``nested`` (lazy: reads the schema only).""" + dtypes = getattr(data, "dtypes", None) + if dtypes is None: + raise TypeError( + f"expected a nested-pandas NestedFrame or an lsdb Catalog, got " + f"{type(data).__name__}" + ) + available = [str(c) for c in getattr(dtypes, "index", dtypes)] + if nested not in available: + raise ColumnResolutionError( + f"no nested column {nested!r}; available columns: {available}" + ) + return dtypes[nested] + + +def _bare(name: str | None, nested: str, role: str) -> str | None: + """Normalize ``"lc.hmjd"`` / ``"hmjd"`` to the bare sub-column name.""" + if name is None: + return None + if "." not in name: + return name + prefix, rest = name.split(".", 1) + if prefix != nested: + raise ColumnResolutionError( + f"{role} column {name!r} is dotted but does not belong to the nested " + f"column {nested!r}; pass a sub-column of {nested!r} (bare or dotted)" + ) + return rest + + +def _preset_entry(preset: str | None) -> dict[str, Any]: + """Look up a preset by name (empty dict when ``preset`` is ``None``).""" + if preset is None: + return {} + try: + return COLUMN_PRESETS[preset] + except KeyError: + raise ValueError( + f"unknown preset {preset!r}; choose from {sorted(COLUMN_PRESETS)}" + ) from None + + +def resolve_nested_columns( + data: Any, + nested: str = _DEFAULT_NEST, + *, + time: str | None = None, + value: str | None = None, + error: str | None = None, + band: str | None = None, + domain: Domain | str | None = None, + preset: str | None = None, +) -> NestedColumns: + """Resolve the light-curve sub-columns of a nested column, without computing. + + Only the nested column's *schema* is read (the ``NestedDtype`` sub-column names), + so this is safe on a lazy lsdb ``Catalog``. Unset roles fall back to the preset (if + any) and then to cuPeriod's :class:`~cuperiod.ColumnMap` auto-detection. + + Parameters + ---------- + data : NestedFrame or lsdb Catalog + Anything exposing ``.dtypes``. + nested : str, default "lc" + Name of the nested column holding the light curves. A ``preset`` supplies its + own nest name unless you pass a different one here. + time, value, error : str, optional + Sub-column names, bare (``"hmjd"``) or dotted (``"lc.hmjd"``). Auto-detected + when ``None``. + band : str, optional + In-nest band/filter sub-column. Multi-band mode is used **only** when this + resolves; it is never auto-detected, so a nest that happens to carry a + ``band`` column is not silently reinterpreted. + domain : Domain or str, optional + Brightness domain override; inferred from the value column's name otherwise. + preset : str, optional + A key of :data:`COLUMN_PRESETS`. Preset ``time``/``value`` are required to + exist; preset ``error``/``band`` are dropped when the nest does not have them. + + Returns + ------- + NestedColumns + Dotted names plus the resolved :class:`~cuperiod.Domain`. + + Raises + ------ + ColumnResolutionError + If the nested column is missing, or time/value cannot be resolved. + + Examples + -------- + >>> resolve_nested_columns(frame, preset="rubin_dp1_object") # doctest: +SKIP + NestedColumns(nested='objectForcedSource', + time='objectForcedSource.midpointMjdTai', ...) + """ + entry = _preset_entry(preset) + if entry and nested == _DEFAULT_NEST: + nested = str(entry["nested"]) + subcols = _subcolumn_names(_nested_dtype(data, nested)) + lower = {c.lower(): c for c in subcols} + + def soft(name: str | None) -> str | None: + """Keep a preset-supplied name only when the nest actually has it.""" + return name if name is not None and name.lower() in lower else None + + time_name = _bare(time, nested, "time") or entry.get("time") + value_name = _bare(value, nested, "value") or entry.get("value") + if error is not None: + error_name = _bare(error, nested, "error") + else: + error_name = soft(entry.get("error")) + if band is not None: + band_name = _bare(band, nested, "band") + if band_name is not None and band_name.lower() not in lower: + raise ColumnResolutionError( + f"band column {band!r} is not a sub-column of {nested!r}; " + f"available: {subcols}" + ) + else: + band_name = soft(entry.get("band")) + + if domain is None and entry: + domain = entry.get("domain") + resolved = ColumnMap( + time=time_name, value=value_name, error=error_name + ).resolve(subcols, domain=None if domain is None else Domain(domain)) + band_actual = None if band_name is None else lower[band_name.lower()] + return NestedColumns( + nested=nested, + time=f"{nested}.{resolved.time}", + value=f"{nested}.{resolved.value}", + error=None if resolved.error is None else f"{nested}.{resolved.error}", + band=None if band_actual is None else f"{nested}.{band_actual}", + domain=resolved.domain, + ) + + +# --- shared kernel ------------------------------------------------------------ + + +def _unique_in_order(labels: np.ndarray) -> list[Any]: + """Distinct band labels, first-seen order (stable band ordering per object).""" + seen: dict[Any, None] = {} + for label in labels.tolist(): + seen.setdefault(label, None) + return list(seen) + + +def _resolved_backend(method: PeriodogramMethod, requested: str) -> str: + """``method.resolve_backend`` with a per-process cache.""" + key = (method.name, requested) + cached = _BACKEND_CACHE.get(key) + if cached is None: + cached = method.resolve_backend(requested) + _BACKEND_CACHE[key] = cached + return cached + + +@dataclass +class _Kernel: + """Column/method configuration shared by both tiers. + + Deliberately holds no engine and no light-curve data, so dask can pickle it to a + worker; the engine is built inside the worker by :class:`_PartitionKernel`. + """ + + columns: NestedColumns + method: str + settings: BaseSettings | None + backend: str + grid: GridSpec | None + n_best: int + prefix: str + _prepared: tuple[PeriodogramMethod, BaseSettings, str] | None = field( + default=None, repr=False, compare=False + ) + + @property + def out_columns(self) -> tuple[str, ...]: + """Names of the result columns this kernel produces.""" + p = self.prefix + names = [f"{p}best_period", f"{p}best_power", f"{p}fap"] + names += [f"{p}period_{i}" for i in range(2, max(self.n_best, 1) + 1)] + return tuple(names) + + def validate(self) -> PeriodogramMethod: + """Look the method up and reject a configuration no object can satisfy. + + A multi-band run with a single-band-only method cannot produce a result for + *any* row, and :meth:`evaluate` turns per-object failures into NaN rows — so + the combination has to raise here, before a single object is touched, or the + misconfiguration ships as a silently all-NaN frame. + """ + method = get_method(self.method) + if self.columns.band is not None and not method.supports_multiband: + raise ValueError(f"{method.name} does not support multi-band input") + return method + + def prepare(self) -> tuple[PeriodogramMethod, BaseSettings, str]: + """Resolve method, settings and backend once (raises on misconfiguration).""" + if self._prepared is None: + method = self.validate() + self._prepared = ( + method, + method.coerce_settings(self.settings), + _resolved_backend(method, self.backend), + ) + return self._prepared + + # -- per-object work ------------------------------------------------------ + def nan_row(self) -> dict[str, float]: + """An all-NaN result row (a failed or unusable object).""" + return dict.fromkeys(self.out_columns, _NAN) + + def light_curve( + self, + time: Any, + value: Any, + error: Any, + band: Any, + ) -> LightCurve | MultiBandLightCurve: + """Assemble one object's light curve from its per-epoch arrays.""" + t = np.asarray(time, dtype=np.float64) + v = np.asarray(value, dtype=np.float64) + e = None if error is None else np.asarray(error, dtype=np.float64) + if band is None: + return LightCurve.from_arrays(t, v, e, domain=self.columns.domain) + labels = np.asarray(band) + bands: dict[str, LightCurve] = {} + for label in _unique_in_order(labels): + mask = labels == label + bands[str(label)] = LightCurve.from_arrays( + t[mask], + v[mask], + None if e is None else e[mask], + domain=self.columns.domain, + meta={"band": str(label)}, + ) + return MultiBandLightCurve.from_light_curves(bands) + + def compute( + self, + method: PeriodogramMethod, + settings: BaseSettings, + backend: str, + lc: LightCurve | MultiBandLightCurve, + engine: object | None, + ) -> Periodogram: + """Run one light curve, reusing ``engine`` when the method has one.""" + if isinstance(lc, MultiBandLightCurve): + if not method.supports_multiband: + raise ValueError(f"{method.name} does not support multi-band input") + grid = self.grid or _multiband_grid(method, lc, settings) + return method.multiband_power(grid, lc, settings, backend, engine=engine) + single = lc.in_domain(method.natural_domain) if method.natural_domain else lc + grid = self.grid or method.default_grid(single, settings) + return method.power(grid, single, settings, backend, engine=engine) + + def peaks_row(self, pg: Periodogram) -> dict[str, float]: + """Flatten a periodogram to this kernel's result columns.""" + row = self.nan_row() + peaks = pg.best_periods(max(self.n_best, 1)) + if not peaks: + return row + best = peaks[0] + p = self.prefix + row[f"{p}best_period"] = float(best.period) + row[f"{p}best_power"] = float(best.power) + row[f"{p}fap"] = float(best.extra.get("fap", _NAN)) + for rank in range(2, max(self.n_best, 1) + 1): + if len(peaks) >= rank: + row[f"{p}period_{rank}"] = float(peaks[rank - 1].period) + return row + + def evaluate( + self, + prepared: tuple[PeriodogramMethod, BaseSettings, str], + time: Any, + value: Any, + error: Any, + band: Any, + engine: object | None = None, + ) -> dict[str, float]: + """One object, from raw arrays to result columns. Never raises. + + A per-object failure (too few detections, no baseline, a degenerate fit) must + not abort a survey-scale run, so it becomes an all-NaN row. + """ + method, settings, backend = prepared + try: + lc = self.light_curve(time, value, error, band) + return self.peaks_row(self.compute(method, settings, backend, lc, engine)) + except Exception: # a bad object must not kill the partition + return self.nan_row() + + +@dataclass +class _RowKernel(_Kernel): + """Tier 1: called by ``map_rows`` with one row's arrays as a dict.""" + + def __call__(self, row: Mapping[str, Any]) -> dict[str, float]: + cols = self.columns + prepared = self.prepare() + return self.evaluate( + prepared, + row[cols.time], + row[cols.value], + None if cols.error is None else row.get(cols.error), + None if cols.band is None else row.get(cols.band), + ) + + +@dataclass +class _PartitionKernel(_Kernel): + """Tier 2: called with a whole partition; one engine serves every object.""" + + def empty_result(self, index: Any = None) -> pd.DataFrame: + """A correctly-typed zero-row result (dask/lsdb meta, empty partitions).""" + import pandas as pd + + data = {name: pd.Series(dtype="float64") for name in self.out_columns} + return pd.DataFrame(data, index=index) + + def __call__(self, df: Any) -> pd.DataFrame: + import pandas as pd + + if len(df) == 0: + return self.empty_result(df.index[:0] if hasattr(df, "index") else None) + cols = self.columns + prepared = self.prepare() + method, settings, backend = prepared + starts, ends, flat = _flat_buffers(df[cols.nested], cols.subcolumns) + time = flat[cols.time.split(".", 1)[1]] + value = flat[cols.value.split(".", 1)[1]] + error = None if cols.error is None else flat[cols.error.split(".", 1)[1]] + band = None if cols.band is None else flat[cols.band.split(".", 1)[1]] + + engine = method.make_engine(backend, settings) + try: + rows = [ + self.evaluate( + prepared, + time[i:j], + value[i:j], + None if error is None else error[i:j], + None if band is None else band[i:j], + engine=engine, + ) + for i, j in zip(starts, ends, strict=True) + ] + finally: + if engine is not None: + del engine + from cuperiod.core.device import free_gpu_memory + + free_gpu_memory() + return pd.DataFrame(rows, index=df.index, columns=list(self.out_columns)) + + +def _flat_buffers( + series: Any, subcolumns: list[str] +) -> tuple[np.ndarray, np.ndarray, dict[str, np.ndarray]]: + """Read a nested column's Arrow buffers once: per-object slices + flat arrays. + + The nested extension array is CSR-like — one flat array per sub-column plus a + shared list-offset array — so a partition's whole light-curve payload comes out in + a handful of buffer reads instead of one materialized DataFrame per object. + + Returns + ------- + starts, ends : numpy.ndarray + Per-object slice bounds into the flat arrays. + flat : dict of str to numpy.ndarray + The concatenated per-epoch values, keyed by bare sub-column name. + """ + array = series.array + offsets = np.asarray(array.list_offsets, dtype=np.int64) + offsets = offsets - offsets[0] # a sliced partition may start mid-buffer + struct = array.struct_array + if hasattr(struct, "combine_chunks"): # a ChunkedArray in nested-pandas >= 0.7 + struct = struct.combine_chunks() + total = int(offsets[-1]) + flat: dict[str, np.ndarray] = {} + for name in subcolumns: + field_array = struct.field(name) + values = np.asarray(field_array.flatten().to_numpy(zero_copy_only=False)) + if values.size != total and hasattr(field_array, "values"): + # Nulls/slicing can make flatten() disagree with the raw offsets; the + # child array always indexes by them. + values = np.asarray( + field_array.values.to_numpy(zero_copy_only=False) + ) + flat[name] = values + return offsets[:-1], offsets[1:], flat + + +# --- lsdb detection ----------------------------------------------------------- + + +def _is_lsdb_catalog(data: Any) -> bool: + """Whether ``data`` is a lazy lsdb ``Catalog`` (no lsdb import needed). + + lsdb's ``Catalog.map_rows`` requires ``meta=`` and returns a lazy catalog, while + ``NestedFrame.map_rows`` computes eagerly and rejects ``meta`` — the two paths + differ only in that argument, so the class's defining module is enough to pick one. + """ + module = type(data).__module__ or "" + return module.startswith("lsdb") and hasattr(data, "map_rows") + + +def _catalog_meta(out_columns: tuple[str, ...]) -> dict[str, type]: + """The lsdb ``meta`` for the result columns (all float64). + + With ``append_columns=True`` lsdb wants *only* the added columns, which is exactly + what a kernel returns, so one mapping serves both modes. + """ + return dict.fromkeys(out_columns, float) + + +# --- tier 1: row-wise --------------------------------------------------------- + + +def nested_periodogram( + data: Any, + nested: str = _DEFAULT_NEST, + *, + time: str | None = None, + value: str | None = None, + error: str | None = None, + band: str | None = None, + preset: str | None = None, + method: str = "GLS", + settings: BaseSettings | None = None, + backend: str = "auto", + grid: GridSpec | None = None, + domain: Domain | str | None = None, + n_best: int = 1, + prefix: str = "", + append_columns: bool = True, + meta: Any = None, +) -> Any: + """Run a periodogram on every row of a nested light-curve table (Tier 1). + + One row = one object = one light curve = one periodogram. The nested column is + read through ``map_rows``, so this works identically on an in-memory + ``NestedFrame`` and on a lazy lsdb ``Catalog`` (which stays lazy — call + ``.compute()`` when you want the answer). + + Objects that cannot be searched (too few detections, no time baseline, a + degenerate fit) yield NaN result columns instead of raising: at survey scale a + single bad light curve must never abort the run. + + Parameters + ---------- + data : NestedFrame or lsdb Catalog + A table with one row per object and the light curves in a nested column. + nested : str, default "lc" + The nested column's name. A ``preset`` supplies its own unless set here. + time, value, error : str, optional + Sub-column names, bare (``"hmjd"``) or dotted (``"lc.hmjd"``). Auto-detected + from the nest's schema when ``None``. + band : str, optional + In-nest band sub-column (e.g. ``"lc.band"``). When given, each row is built as + a :class:`~cuperiod.MultiBandLightCurve` grouped on that column and the + method's multi-band model runs; otherwise every epoch is one band. + preset : str, optional + A key of :data:`COLUMN_PRESETS` (``"ztf_dr22"``, ``"ztf_alerts"``, + ``"rubin_dp1_object"``, ``"rubin_dp1_dia"``) filling every column parameter you + did not set. + method : str, default "GLS" + Any registered method name. + settings : settings model, optional + The method's settings (e.g. :class:`~cuperiod.GLSSettings`). + backend : str, default "auto" + ``"auto"``/``"cpu"``/``"gpu"`` or a concrete backend. + grid : GridSpec, optional + One explicit trial grid for every object; by default each object gets the + method's own grid from its baseline and sampling. + domain : Domain or str, optional + Brightness-domain override (``"flux"`` for difference-imaging fluxes, which + are legitimately negative and must not be converted to magnitudes). + n_best : int, default 1 + Peaks to report. ``> 1`` adds ``period_2 … period_n`` columns. + prefix : str, default "" + Prepended to every result-column name (e.g. ``"gls_"``). + append_columns : bool, default True + Keep the input columns and append the results; ``False`` returns only the + result columns. + meta : dict, optional + lsdb ``meta`` override. Built automatically (``{column: float}``) otherwise; + ignored for an in-memory ``NestedFrame``. + + Returns + ------- + NestedFrame or lsdb Catalog + The same kind of object that came in, with ``{prefix}best_period``, + ``{prefix}best_power``, ``{prefix}fap`` (NaN when the method reports none) and + any ``{prefix}period_i`` columns. + + Raises + ------ + ValueError + If ``band`` resolves but ``method`` has no multi-band model. Per-object + failures become NaN rows, so a configuration that can never work is rejected + up front instead. + + See Also + -------- + partition_periodogram : the batched, engine-reusing tier (GPU throughput). + + Notes + ----- + On dask (lsdb), run **one worker per GPU** — e.g. a + ``dask_cuda.LocalCUDACluster`` — and let each worker own its device. Kernels are + plain picklable configuration; compute engines are never pickled but built lazily + inside the worker, so a GPU context is created in the process that uses it. + + Examples + -------- + A ZTF DR22-style ``NestedFrame`` (single band per row: DR22 keeps the filter in + the base column ``filterid``): + + >>> from cuperiod.interop import nested_periodogram + >>> out = nested_periodogram(frame, "lc", preset="ztf_dr22") # doctest: +SKIP + >>> out[["best_period", "best_power", "fap"]].head() # doctest: +SKIP + + A lazy lsdb catalog of Rubin DP1 forced photometry, multi-band in flux: + + >>> import lsdb # doctest: +SKIP + >>> cat = lsdb.open_catalog("dp1_object") # doctest: +SKIP + >>> res = nested_periodogram( # doctest: +SKIP + ... cat, preset="rubin_dp1_object", method="GLS", n_best=3, prefix="gls_" + ... ) + >>> res[["gls_best_period", "gls_period_2"]].compute() # doctest: +SKIP + """ + require_nested_pandas() + columns = resolve_nested_columns( + data, + nested, + time=time, + value=value, + error=error, + band=band, + domain=domain, + preset=preset, + ) + kernel = _RowKernel( + columns=columns, + method=method, + settings=settings, + backend=backend, + grid=grid, + n_best=n_best, + prefix=prefix, + ) + kernel.validate() # fail now, not once per object as an all-NaN row + read = columns.read_columns + if _is_lsdb_catalog(data): + return data.map_rows( + kernel, + read, + meta=_catalog_meta(kernel.out_columns) if meta is None else meta, + infer_nesting=False, + append_columns=append_columns, + ) + return data.map_rows( + kernel, read, infer_nesting=False, append_columns=append_columns + ) + + +# --- tier 2: partition-wise --------------------------------------------------- + + +def partition_periodogram( + data: Any, + nested: str = _DEFAULT_NEST, + *, + time: str | None = None, + value: str | None = None, + error: str | None = None, + band: str | None = None, + preset: str | None = None, + method: str = "GLS", + settings: BaseSettings | None = None, + backend: str = "auto", + grid: GridSpec | None = None, + domain: Domain | str | None = None, + n_best: int = 1, + prefix: str = "", + meta: Any = None, +) -> Any: + """Run a periodogram on every object of a partition, batched (Tier 2). + + Same inputs and same result columns as :func:`nested_periodogram`, different + execution: a partition's nested column is read **once** through its Arrow buffers + (list offsets + struct fields), each object is a slice of those flat arrays, and + every object in the partition is evaluated against **one** method engine built + per partition (:meth:`~cuperiod.methods.base.PeriodogramMethod.make_engine`). + + That is the GPU differentiator: plan/kernel setup is amortized over a whole + partition of stars instead of paid per star. On a CPU backend (no engine) it is + still the cheaper path, because the per-object DataFrame round-trip is skipped. + + Parameters + ---------- + data : NestedFrame or lsdb Catalog + A ``NestedFrame`` is processed immediately; a ``Catalog`` is wired up with + ``map_partitions`` and stays lazy. + nested, time, value, error, band, preset : str, optional + Column selection, exactly as in :func:`nested_periodogram`. + method, settings, backend, grid, domain, n_best, prefix + As in :func:`nested_periodogram`. + meta : pandas.DataFrame, optional + lsdb ``meta`` override; an empty float-typed frame is built otherwise. + + Returns + ------- + pandas.DataFrame or lsdb Catalog + One row per object, indexed like the input, with the same result columns as + :func:`nested_periodogram` (result columns only — the input columns are not + copied). An empty input yields a correctly-typed empty frame, which is what + lets lsdb infer a schema by calling the kernel on an empty partition. + + Raises + ------ + ValueError + If ``band`` resolves but ``method`` has no multi-band model, exactly as in + :func:`nested_periodogram`. + + See Also + -------- + nested_periodogram : the row-wise tier. + + Notes + ----- + One worker per GPU (``dask_cuda.LocalCUDACluster``). The callable dask ships to + the workers holds only picklable configuration — column names, method name, + settings, grid — and the engine is created inside the worker on its own device, + then released when the partition finishes. Engines are never pickled. + + Examples + -------- + In memory, on a ``NestedFrame``: + + >>> from cuperiod.interop import partition_periodogram + >>> res = partition_periodogram(frame, "lc", method="GLS") # doctest: +SKIP + >>> res["best_period"].head() # doctest: +SKIP + + Over an lsdb catalog, one GPU worker per device: + + >>> from dask_cuda import LocalCUDACluster # doctest: +SKIP + >>> from dask.distributed import Client # doctest: +SKIP + >>> client = Client(LocalCUDACluster()) # doctest: +SKIP + >>> res = partition_periodogram( # doctest: +SKIP + ... cat, preset="ztf_alerts", method="GLS", backend="gpu" + ... ) + >>> res.compute() # doctest: +SKIP + """ + require_nested_pandas() + columns = resolve_nested_columns( + data, + nested, + time=time, + value=value, + error=error, + band=band, + domain=domain, + preset=preset, + ) + kernel = _PartitionKernel( + columns=columns, + method=method, + settings=settings, + backend=backend, + grid=grid, + n_best=n_best, + prefix=prefix, + ) + kernel.validate() # fail now, not once per object as an all-NaN row + if _is_lsdb_catalog(data): + return data.map_partitions( + kernel, meta=kernel.empty_result() if meta is None else meta + ) + return kernel(data) + + +__all__ = [ + "COLUMN_PRESETS", + "PRESET_KEYS", + "NestedColumns", + "nested_periodogram", + "partition_periodogram", + "require_nested_pandas", + "resolve_nested_columns", +] diff --git a/src/cuperiod/methods/__init__.py b/src/cuperiod/methods/__init__.py index 54eba17..8674a19 100644 --- a/src/cuperiod/methods/__init__.py +++ b/src/cuperiod/methods/__init__.py @@ -14,6 +14,7 @@ from cuperiod.methods import mhaov as mhaov # noqa: F401 from cuperiod.methods import pdm as pdm # noqa: F401 from cuperiod.methods import string_length as string_length # noqa: F401 +from cuperiod.methods import supersmoother as supersmoother # noqa: F401 from cuperiod.methods import tls as tls # noqa: F401 from cuperiod.methods.base import ( MethodInfo, diff --git a/src/cuperiod/methods/base.py b/src/cuperiod/methods/base.py index 64c98e2..7ad573d 100644 --- a/src/cuperiod/methods/base.py +++ b/src/cuperiod/methods/base.py @@ -203,8 +203,13 @@ def multiband_power( mblc: MultiBandLightCurve, settings: BaseSettings, backend: str, + engine: object | None = None, ) -> Periodogram: - """Compute a multi-band periodogram. Override in multi-band methods.""" + """Compute a multi-band periodogram. Override in multi-band methods. + + ``engine`` is the same reusable object :meth:`make_engine` builds for the + single-band path; methods without a reusable plan simply ignore it. + """ raise NotImplementedError(f"{self.name} does not support multi-band input") def make_engine(self, backend: str, settings: BaseSettings) -> object | None: diff --git a/src/cuperiod/methods/bls.py b/src/cuperiod/methods/bls.py index 18509c6..9dc8db0 100644 --- a/src/cuperiod/methods/bls.py +++ b/src/cuperiod/methods/bls.py @@ -235,6 +235,7 @@ def multiband_power( # type: ignore[override] mblc: MultiBandLightCurve, settings: BLSSettings, backend: str, + engine: object | None = None, ) -> Periodogram: from cuperiod.multiband.bls_mb import bls_multiband_power diff --git a/src/cuperiod/methods/conditional_entropy.py b/src/cuperiod/methods/conditional_entropy.py index c17612d..ad1b525 100644 --- a/src/cuperiod/methods/conditional_entropy.py +++ b/src/cuperiod/methods/conditional_entropy.py @@ -35,7 +35,7 @@ pseudo_nyquist_frequency, uniform_frequency_grid, ) -from cuperiod.core.lightcurve import LightCurve +from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve from cuperiod.core.result import Periodogram from cuperiod.methods.base import PeriodogramMethod, register @@ -342,7 +342,7 @@ class ConditionalEntropyMethod(PeriodogramMethod): name: ClassVar[str] = "CE" objective_sense: ClassVar[Literal["max", "min"]] = "min" - supports_multiband: ClassVar[bool] = False + supports_multiband: ClassVar[bool] = True settings_cls: ClassVar[type] = CESettings cpu_backend: ClassVar[str] = "numpy" fast_cpu_backend: ClassVar[str | None] = "numba" @@ -401,6 +401,20 @@ def power( # type: ignore[override] meta=finite.meta, ) + def multiband_power( # type: ignore[override] + self, + grid: GridSpec, + mblc: MultiBandLightCurve, + settings: CESettings, + backend: str, + engine: object | None = None, + ) -> Periodogram: + from cuperiod.multiband.conditional_entropy_mb import ce_multiband_entropy + + if backend == "torch" or backend.startswith("torch:"): + backend = f"torch:{resolve_torch_device(backend, settings.device)}" + return ce_multiband_entropy(grid, mblc, settings, backend) + def estimate_device_bytes(self, n_points: int) -> int: return 128 * 1024**2 + n_points * 8 * 8 diff --git a/src/cuperiod/methods/gls.py b/src/cuperiod/methods/gls.py index 452b62f..2ce3e52 100644 --- a/src/cuperiod/methods/gls.py +++ b/src/cuperiod/methods/gls.py @@ -324,6 +324,11 @@ class CufinufftGLS: to ``f0 + k*df``. One instance per GPU-owning process (not thread-safe). Results are identical to :func:`lombscargle_power` with ``backend="cufinufft"``. + The multi-band paths reuse the same plan cache through :meth:`trig_sums` — the + offsets model's ``K + 2`` transforms and the flex model's harmonic sums all run + on grids of the same mode count, so one bucketed plan pair serves every band, + every harmonic, and every star of a batch. + Parameters ---------- eps : float, default 1e-9 @@ -352,6 +357,30 @@ def _plan(self, nf: int, n_trans: int) -> Any: self._plans[(nf, n_trans)] = plan return plan + def trig_sums( + self, tau: Any, strengths: Any, f0: float, df: float, nf: int + ) -> Any: + """Plan-cached type-1 trig sums on ``f0 + df*arange(nf)``. + + The plan-reusing equivalent of :func:`_trig_sums` with + ``backend="cufinufft"``: ``tau`` and ``strengths`` (``(n_trans, N)``) are + cupy arrays and the ``(n_trans, nf)`` complex sums stay on device. The plan + is sized to the bucketed mode count and keyed by ``(modes, n_trans)``, so + transforms of the same shape — across bands, harmonics, and light curves — + share one plan. + """ + cp = self._cp + nf_plan = ((nf + self._bucket - 1) // self._bucket) * self._bucket + two_pi = 2.0 * np.pi + x = (two_pi * df) * tau + x = cp.mod(x + np.pi, two_pi) - np.pi + mod = cp.exp(2j * np.pi * (f0 + (nf_plan // 2) * df) * tau) + plan = self._plan(nf_plan, int(strengths.shape[0])) + plan.setpts(x) + out = plan.execute((strengths * mod[None, :]).astype(cp.complex128)) + out = out if out.ndim == 2 else out[None, :] + return out[:, :nf] + def power( self, t: FloatArray, @@ -375,23 +404,9 @@ def power( tau, w, y, y_mean, yy = _prep(t, y, dy) tau_g = cp.asarray(tau) base = cp.asarray(np.stack([w, w * y])) - nf_plan = ((nf + self._bucket - 1) // self._bucket) * self._bucket - two_pi = 2.0 * np.pi - - def sums(f0_: float, df_: float, strengths: Any) -> Any: - x = (two_pi * df_) * tau_g - x = cp.mod(x + np.pi, two_pi) - np.pi - mod = cp.exp(2j * np.pi * (f0_ + (nf_plan // 2) * df_) * tau_g) - plan = self._plan(nf_plan, int(strengths.shape[0])) - plan.setpts(x) - out = plan.execute((strengths * mod[None, :]).astype(cp.complex128)) - return out if out.ndim == 2 else out[None, :] - - pair = sums(f0, df, base) - sw2 = sums(2.0 * f0, 2.0 * df, base[:1]) - power = _assemble_power( - pair[0, :nf], pair[1, :nf], sw2[0, :nf], y_mean, yy, fit_mean - ) + pair = self.trig_sums(tau_g, base, f0, df, nf) + sw2 = self.trig_sums(tau_g, base[:1], 2.0 * f0, 2.0 * df, nf) + power = _assemble_power(pair[0], pair[1], sw2[0], y_mean, yy, fit_mean) return np.asarray(cp.asnumpy(power), dtype=np.float64) @@ -545,10 +560,11 @@ def multiband_power( # type: ignore[override] mblc: MultiBandLightCurve, settings: GLSSettings, backend: str, + engine: object | None = None, ) -> Periodogram: from cuperiod.multiband.gls_mb import gls_multiband_power - return gls_multiband_power(grid, mblc, settings) + return gls_multiband_power(grid, mblc, settings, backend, engine=engine) def make_engine(self, backend: str, settings: GLSSettings) -> object | None: # type: ignore[override] if backend == "cufinufft": diff --git a/src/cuperiod/methods/mhaov.py b/src/cuperiod/methods/mhaov.py index ff7849f..3d11d93 100644 --- a/src/cuperiod/methods/mhaov.py +++ b/src/cuperiod/methods/mhaov.py @@ -48,9 +48,31 @@ MHAOVBackend = Literal["numpy", "cupy"] -#: Trial frequencies per vectorized batch (bounds the (F, N, 2H+1) design tensor). +#: Trial frequencies per vectorized batch on host backends when ``batch`` is auto (0). DEFAULT_BATCH: Final = 512 +#: Transient byte budgets for auto-sized frequency chunks (``batch <= 0``): the chunk +#: adapts to the light-curve length, so long curves cannot blow memory. Device +#: backends get a far larger budget — their single-shot latency is dominated by +#: per-chunk dispatch (kernel launches plus the batched-solve sync), so fewer, +#: larger chunks are strictly faster at identical results. +_CHUNK_BYTES: Final = 1 << 27 +_DEVICE_CHUNK_BYTES: Final = 1 << 29 + +#: Rough number of (chunk, N)-sized float64 workspaces alive at once in +#: :func:`_model_ss_batch` (angle, cos/sin pairs, Chebyshev recurrence temps, the +#: weighted product), used to convert the byte budgets into a chunk length. +_WORKSPACES: Final = 12 + + +def _resolve_batch(batch: int, n_points: int, on_device: bool) -> int: + """Effective frequency-chunk length: ``batch`` verbatim, or auto when ``<= 0``.""" + if batch > 0: + return batch + budget = _DEVICE_CHUNK_BYTES if on_device else _CHUNK_BYTES + auto = max(1, budget // max(1, n_points * 8 * _WORKSPACES)) + return auto if on_device else min(DEFAULT_BATCH, auto) + #: Diagonal ridge that keeps the harmonic normal equations solvable at degenerate #: frequencies (f→0, where the cosine columns collapse onto the constant column). It is #: applied as ``_RIDGE_EPS · eps(dtype) · n_points``: scaling by the working precision's @@ -326,7 +348,7 @@ def _compute_model_ss( out = _model_ss_batch( array_namespace(freqs_cp), cp.asarray(tau), cp.asarray(y), freqs_cp, n_harmonics=n_harmonics, total_ss=total_ss, y_mean=y_mean, - n_points=n, batch=batch, + n_points=n, batch=_resolve_batch(batch, n, on_device=True), ) return np.asarray(cp.asnumpy(out), dtype=np.float64), total_ss, n if backend == "torch" or backend.startswith("torch:"): @@ -341,7 +363,7 @@ def _compute_model_ss( to_device_array(y, device=device, dtype=fdt), to_device_array(freqs, device=device, dtype=fdt), n_harmonics=n_harmonics, total_ss=total_ss, y_mean=y_mean, - n_points=n, batch=batch, + n_points=n, batch=_resolve_batch(batch, n, on_device=device != "cpu"), ) return to_host(out), total_ss, n if backend != "numpy": @@ -349,7 +371,7 @@ def _compute_model_ss( out = _model_ss_batch( np, tau, y, freqs, n_harmonics=n_harmonics, total_ss=total_ss, y_mean=y_mean, - n_points=n, batch=batch, + n_points=n, batch=_resolve_batch(batch, n, on_device=False), ) return np.asarray(out, dtype=np.float64), total_ss, n @@ -361,7 +383,7 @@ def aov_power( *, n_harmonics: int = 3, backend: str = "numpy", - batch: int = DEFAULT_BATCH, + batch: int = 0, precision: str = "auto", ) -> FloatArray: """Multiharmonic AOV statistic for each trial frequency. @@ -376,8 +398,11 @@ def aov_power( Harmonic order ``H`` (model has ``2H+1`` terms). backend : {"numpy", "cupy"}, default "numpy" CPU or GPU. - batch : int, default 512 - Trial frequencies per vectorized batch. + batch : int, default 0 + Trial frequencies per vectorized batch; 0 auto-sizes the batch from a + transient-memory budget (much larger on device backends, whose + single-shot latency is per-batch dispatch overhead, not arithmetic). + The batch does not affect the result. Returns ------- @@ -403,7 +428,7 @@ def aov_multiband_power( *, n_harmonics: int = 3, backend: str = "numpy", - batch: int = DEFAULT_BATCH, + batch: int = 0, precision: str = "auto", ) -> FloatArray: """Pooled multiband AOV F-statistic at a shared frequency, per-band amplitudes. @@ -525,6 +550,7 @@ def multiband_power( # type: ignore[override] mblc: MultiBandLightCurve, settings: MHAOVSettings, backend: str, + engine: object | None = None, ) -> Periodogram: from cuperiod.multiband.mhaov_mb import mhaov_multiband_power @@ -533,7 +559,7 @@ def multiband_power( # type: ignore[override] return mhaov_multiband_power(grid, mblc, settings, backend) def estimate_device_bytes(self, n_points: int) -> int: - return 128 * 1024**2 + n_points * 8 * 12 + return _DEVICE_CHUNK_BYTES + 64 * 1024**2 + n_points * 8 * 12 register(MHAOVMethod()) diff --git a/src/cuperiod/methods/pdm.py b/src/cuperiod/methods/pdm.py index c5c4fd6..5d5526e 100644 --- a/src/cuperiod/methods/pdm.py +++ b/src/cuperiod/methods/pdm.py @@ -41,7 +41,7 @@ pseudo_nyquist_frequency, uniform_frequency_grid, ) -from cuperiod.core.lightcurve import LightCurve +from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve from cuperiod.core.result import Periodogram from cuperiod.methods.base import PeriodogramMethod, register @@ -410,7 +410,7 @@ class PDMMethod(PeriodogramMethod): name: ClassVar[str] = "PDM" objective_sense: ClassVar[Literal["max", "min"]] = "min" - supports_multiband: ClassVar[bool] = False + supports_multiband: ClassVar[bool] = True settings_cls: ClassVar[type] = PDMSettings cpu_backend: ClassVar[str] = "numpy" fast_cpu_backend: ClassVar[str | None] = "numba" @@ -473,6 +473,20 @@ def power( # type: ignore[override] meta=finite.meta, ) + def multiband_power( # type: ignore[override] + self, + grid: GridSpec, + mblc: MultiBandLightCurve, + settings: PDMSettings, + backend: str, + engine: object | None = None, + ) -> Periodogram: + from cuperiod.multiband.pdm_mb import pdm_multiband_theta + + if backend == "torch" or backend.startswith("torch:"): + backend = f"torch:{resolve_torch_device(backend, settings.device)}" + return pdm_multiband_theta(grid, mblc, settings, backend) + def estimate_device_bytes(self, n_points: int) -> int: return 128 * 1024**2 + n_points * 8 * 8 diff --git a/src/cuperiod/methods/string_length.py b/src/cuperiod/methods/string_length.py index c72d359..b8430f7 100644 --- a/src/cuperiod/methods/string_length.py +++ b/src/cuperiod/methods/string_length.py @@ -35,7 +35,7 @@ pseudo_nyquist_frequency, uniform_frequency_grid, ) -from cuperiod.core.lightcurve import LightCurve +from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve from cuperiod.core.result import Periodogram from cuperiod.methods.base import PeriodogramMethod, register @@ -365,7 +365,7 @@ class StringLengthMethod(PeriodogramMethod): name: ClassVar[str] = "STRINGLENGTH" objective_sense: ClassVar[Literal["max", "min"]] = "min" - supports_multiband: ClassVar[bool] = False + supports_multiband: ClassVar[bool] = True settings_cls: ClassVar[type] = StringLengthSettings cpu_backend: ClassVar[str] = "numpy" fast_cpu_backend: ClassVar[str | None] = "numba" @@ -424,6 +424,20 @@ def power( # type: ignore[override] meta=finite.meta, ) + def multiband_power( # type: ignore[override] + self, + grid: GridSpec, + mblc: MultiBandLightCurve, + settings: StringLengthSettings, + backend: str, + engine: object | None = None, + ) -> Periodogram: + from cuperiod.multiband.string_length_mb import string_length_multiband + + if backend == "torch" or backend.startswith("torch:"): + backend = f"torch:{resolve_torch_device(backend, settings.device)}" + return string_length_multiband(grid, mblc, settings, backend) + def estimate_device_bytes(self, n_points: int) -> int: return 128 * 1024**2 + n_points * 8 * 8 diff --git a/src/cuperiod/methods/supersmoother.py b/src/cuperiod/methods/supersmoother.py new file mode 100644 index 0000000..f3eaecd --- /dev/null +++ b/src/cuperiod/methods/supersmoother.py @@ -0,0 +1,771 @@ +"""SuperSmoother periodogram (Friedman 1984; Reimann 1994). + +For each trial period the data are phase-folded and fit with Friedman's variable-span +smoother: three primary local-linear smooths (span fractions 0.05 / 0.2 / 0.5 of the +points), leave-one-out cross-validation to pick the best span at every phase point, +and a final smoothing pass over the blended curve. The periodogram statistic follows +gatspy's ``SuperSmoother``:: + + score = 1 - mean_i |y_i - model_i| / dy_i / mean_i |y_i - mu| / dy_i + +with ``mu`` the inverse-variance weighted mean — the fractional reduction in mean +absolute (error-standardized) deviation, *maximized* at the true period. Being fully +non-parametric, it fits any repeating shape without a harmonic budget; the price is +cost (a sort plus several smooths per trial period) and a soft spectrum. Values can +dip slightly below 0 when a fold fits worse than the constant model. Note that a +fold at an integer *multiple* of the true period is still a coherent repeating +curve, so ``2P``, ``3P``, ... score nearly as high as ``P`` itself: read the +shortest period of a high-score family as the candidate (or bound the search from +above), and let :func:`cuperiod.alias_diagnostics` arbitrate the family. + +Semantics follow ``supersmoother`` (VanderPlas), the reference implementation used by +gatspy, with three deliberate choices: + +* span windows are forced to odd point counts (``max(3, int(span*N))``, +1 if even), + matching the upstream fix for Friedman's odd-span assumption; +* folding is always periodic — windows wrap around phase 0/1 via period-shifted + padding, so the edge-window pathologies of the plain smoother cannot occur; +* degenerate windows (duplicate phases) fall back to the weighted mean instead of + raising, and the bass-enhancement factor is clamped to ``[0, 1]`` (the reference + can emit NaN for ``alpha`` between 9 and 10). + +All backends share one vectorized array-API kernel — ``numpy`` on the CPU, ``cupy`` +on NVIDIA, ``torch`` on any torch device — plus a numba-parallel CPU tier; every +window sum comes from prefix sums, so the cost per trial period is ``O(N log N)`` +for the sort plus ``O(N)`` per span. + +References: Friedman 1984, "A Variable Span Smoother" (LCS Tech. Rep. 5 / +SLAC-PUB-3477); Reimann 1994 (PhD thesis, UC Berkeley); VanderPlas & Ivezić 2015, +ApJ 812, 18 (gatspy). +""" + +from __future__ import annotations + +from types import ModuleType +from typing import Any, ClassVar, Final, Literal + +import numpy as np + +from cuperiod.core._arrayapi import ( + array_namespace, + device_ref, + resolve_precision, + resolve_torch_device, + to_device_array, + to_host, +) +from cuperiod.core._typing import FloatArray +from cuperiod.core.backend import ensure_cuda_dll_path +from cuperiod.core.config import SuperSmootherSettings +from cuperiod.core.errors import InsufficientDataError +from cuperiod.core.grid import ( + GridSpec, + pseudo_nyquist_frequency, + uniform_frequency_grid, +) +from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve +from cuperiod.core.result import Periodogram +from cuperiod.methods.base import PeriodogramMethod, register + +#: Trial periods per vectorized batch on host backends when ``batch`` is auto (0). +DEFAULT_BATCH: Final = 1024 + +#: Transient byte budgets per trial-period chunk; the chunk adapts to the +#: light-curve length, so long curves cannot blow memory. Device backends get a +#: far larger budget — their single-shot latency is dominated by per-chunk +#: dispatch overhead, so fewer, larger chunks are strictly faster at identical +#: results. +_CHUNK_BYTES: Final = 1 << 27 +_DEVICE_CHUNK_BYTES: Final = 1 << 29 + +#: Rough number of (chunk, N)-sized float64 workspaces alive at once. +_WORKSPACES: Final = 28 + + +def _resolve_chunk(batch: int, n: int, on_device: bool) -> int: + """Effective trial-period chunk length: explicit ``batch`` (byte-capped), or auto. + + An explicit ``batch > 0`` is honored up to the byte budget; ``batch <= 0`` + fills the device budget outright, or keeps the classic ``DEFAULT_BATCH`` on + host backends. The chunk length does not affect the result. + """ + per_row = max(1, n * 8 * _WORKSPACES) + cap = max(1, (_DEVICE_CHUNK_BYTES if on_device else _CHUNK_BYTES) // per_row) + if batch > 0: + return min(batch, cap) + return cap if on_device else min(DEFAULT_BATCH, cap) + + +def span_windows(spans: tuple[float, ...], n: int) -> tuple[int, ...]: + """Span fractions to odd window point counts: ``max(3, int(s*n))``, +1 if even.""" + out = [] + for s in spans: + j = max(3, int(s * n)) + out.append(j if j % 2 else j + 1) + return tuple(out) + + +def _baseline_error(y: FloatArray, w: FloatArray, inv_dy: FloatArray) -> float: + """Mean absolute standardized deviation about the weighted mean (gatspy).""" + mu = float(np.dot(w, y)) + return float(np.mean(np.abs(y - mu) * inv_dy)) + + +# --- vectorized array-API kernel --------------------------------------------- + + +def _cumsum0(xp: ModuleType, a: Any) -> Any: + """Prefix sums along the last axis with a leading zero column.""" + c = xp.cumulative_sum(a, axis=-1) + return xp.concat([xp.zeros_like(c[..., :1]), c], axis=-1) + + +def _take_rows(xp: ModuleType, a: Any, idx: Any) -> Any: + """Per-row gather of ``a`` (same shape as ``idx``) along the last axis.""" + if hasattr(xp, "take_along_axis"): + return xp.take_along_axis(a, idx, axis=-1) + import torch # pragma: no cover - older array-api-compat without the wrapper + + return torch.take_along_dim(a, idx, dim=-1) # pragma: no cover + + +def _pad_phase(xp: ModuleType, x: Any, h: int) -> Any: + """Circular phase padding: one wrapped copy each side, shifted by ∓1.""" + return xp.concat([x[:, -h:] - 1.0, x, x[:, :h] + 1.0], axis=-1) + + +def _pad_vals(xp: ModuleType, a: Any, h: int) -> Any: + """Circular value padding matching :func:`_pad_phase` (no shift).""" + return xp.concat([a[:, -h:], a, a[:, :h]], axis=-1) + + +def _window_sums(c: Any, m: int, h: int, n: int) -> Any: + """Window sums (halfwidth ``m``) at every center from a padded prefix array.""" + return c[:, h + m + 1 : h + m + 1 + n] - c[:, h - m : h - m + n] + + +def _line_values( + xp: ModuleType, + shared: tuple[Any, Any, Any], + c_wa: Any, + c_wxa: Any, + a: Any, + xs: Any, + ws: Any, + m: int, + h: int, + n: int, + cv: bool, +) -> Any: + """Windowed weighted linear fit evaluated at each center point. + + ``shared`` holds the prefix sums of ``w``, ``w*x``, ``w*x^2`` over the padded + row (span-independent); ``c_wa``/``c_wxa`` those of ``w*a`` and ``w*x*a``. With + ``cv=True`` each point's own contribution is subtracted from the five sums + before the fit — the exact leave-one-out value of the reference. Windows whose + abscissa spread cancels (duplicate phases) fall back to the window's weighted + mean instead of raising like the reference does. + """ + c_w, c_wx, c_wxx = shared + w_sum = _window_sums(c_w, m, h, n) + tw = _window_sums(c_wx, m, h, n) + ttw = _window_sums(c_wxx, m, h, n) + yw = _window_sums(c_wa, m, h, n) + tyw = _window_sums(c_wxa, m, h, n) + if cv: + w_sum = w_sum - ws + tw = tw - ws * xs + ttw = ttw - ws * xs * xs + yw = yw - ws * a + tyw = tyw - ws * xs * a + denom = w_sum * ttw - tw * tw + slope = tyw * w_sum - tw * yw + icept = ttw * yw - tyw * tw + eps = float(xp.finfo(xs.dtype).eps) + good = denom > (32.0 * eps) * w_sum * ttw + denom_safe = xp.where(good, denom, xp.ones_like(denom)) + w_safe = xp.where(w_sum > 0.0, w_sum, xp.ones_like(w_sum)) + return xp.where(good, (slope * xs + icept) / denom_safe, yw / w_safe) + + +def _chunk_scores( + xp: ModuleType, + xs: Any, + ys: Any, + ws: Any, + ids: Any, + span_fracs: tuple[float, ...], + windows: tuple[int, ...], + j_mid: int, + j_fin: int, + alpha: float | None, + baseline: float, +) -> Any: + """SuperSmoother scores for one chunk of already-folded, sorted rows. + + ``xs``/``ys``/``ws``/``ids`` are ``(chunk, N)``: normalized phase (sorted + ascending per row), band-mean-centered values, normalized inverse-variance + weights, and ``1/dy``, all gathered to the sorted order. + """ + n = int(xs.shape[-1]) + h = max(*windows, j_mid, j_fin) // 2 + x_p = _pad_phase(xp, xs, h) + w_p = _pad_vals(xp, ws, h) + shared = ( + _cumsum0(xp, w_p), + _cumsum0(xp, w_p * x_p), + _cumsum0(xp, w_p * x_p * x_p), + ) + + def smooth(a: Any, c_wa: Any, c_wxa: Any, j: int, cv: bool) -> Any: + return _line_values( + xp, shared, c_wa, c_wxa, a, xs, ws, j // 2, h, n, cv + ) + + def prefixes(a: Any) -> tuple[Any, Any]: + wa = w_p * _pad_vals(xp, a, h) + return _cumsum0(xp, wa), _cumsum0(xp, wa * x_p) + + c_wy, c_wxy = prefixes(ys) + curves = [smooth(ys, c_wy, c_wxy, j, cv=True) for j in windows] + + if len(curves) == 1: + raw = curves[0] + else: + sm_res = [] + for curve in curves: + resid = xp.abs(curve - ys) * ids + c_wr, c_wxr = prefixes(resid) + sm_res.append(smooth(resid, c_wr, c_wxr, j_mid, cv=False)) + stack = xp.stack(sm_res) + kmin = xp.argmin(stack, axis=0) + best = xp.zeros_like(ys) + span_fracs[0] + for k in range(1, len(span_fracs)): + best = xp.where(kmin == k, span_fracs[k], best) + if alpha is not None: + # Friedman's bass enhancement, with the reference's NaN hazard + # closed: the smoothed residuals can undershoot 0, so the ratio is + # clamped before the fractional power and the factor to [0, 1]. + eps = float(xp.finfo(xs.dtype).eps) + minres = xp.min(stack, axis=0) + last = sm_res[-1] + base = xp.clip(minres, 0.0, None) / xp.where( + last > eps, last, xp.full_like(last, eps) + ) + factor = xp.clip(base ** (10.0 - alpha), 0.0, 1.0) + best = best + factor * (span_fracs[-1] - best) + c_wb, c_wxb = prefixes(best) + sm_spans = smooth(best, c_wb, c_wxb, j_mid, cv=False) + q = xp.clip(sm_spans, span_fracs[0], span_fracs[-1]) + # Piecewise-linear blend of the primary curves at the smoothed span + # (the reference's ``multinterp``): every interval's line is anchored + # at its lower node, and the where-chain assigns q == node upward. + raw = curves[-2] + (q - span_fracs[-2]) * ( + curves[-1] - curves[-2] + ) / (span_fracs[-1] - span_fracs[-2]) + for k in range(len(span_fracs) - 2, 0, -1): + lin = curves[k - 1] + (q - span_fracs[k - 1]) * ( + curves[k] - curves[k - 1] + ) / (span_fracs[k] - span_fracs[k - 1]) + raw = xp.where(q < span_fracs[k], lin, raw) + + c_wm, c_wxm = prefixes(raw) + model = smooth(raw, c_wm, c_wxm, j_fin, cv=False) + err = xp.sum(xp.abs(ys - model) * ids, axis=-1) / float(n) + return 1.0 - err / baseline + + +def _score_batches( + xp: ModuleType, + tau: Any, + y: Any, + w: Any, + inv_dy: Any, + freqs: FloatArray, + *, + span_fracs: tuple[float, ...], + windows: tuple[int, ...], + j_mid: int, + j_fin: int, + alpha: float | None, + baseline: float, + chunk: int, +) -> FloatArray: + """Fold, sort, and score every trial frequency in ``chunk``-sized pieces. + + The scores accumulate on the compute device and cross to the host **once** + at the end — a per-chunk transfer would synchronize the stream every + iteration, which is what used to dominate single-shot GPU latency. + """ + nf = int(freqs.shape[0]) + fdtype = tau.dtype + dev = device_ref(tau) + freqs_dev = xp.asarray(freqs, dtype=fdtype, device=dev) + out = xp.empty(nf, dtype=fdtype, device=dev) + for start in range(0, nf, chunk): + stop = min(start + chunk, nf) + fc = freqs_dev[start:stop] + x = xp.remainder(tau[None, :] * fc[:, None], 1.0) + order = xp.argsort(x, axis=-1) + xs = _take_rows(xp, x, order) + out[start:stop] = _chunk_scores( + xp, xs, y[order], w[order], inv_dy[order], + span_fracs, windows, j_mid, j_fin, alpha, baseline, + ) + return to_host(out) + + +# --- numba fast CPU tier ------------------------------------------------------ + +_NUMBA_SS_KERNEL: Any = None + + +def _numba_ss_kernel() -> Any: + """Lazily compile (once) and cache the numba SuperSmoother kernel. + + The same chain as the vectorized path — sort, circular pad, prefix sums, + constant-span linear fits with exact leave-one-out, span selection, + interpolation, final smooth — one trial frequency per ``prange`` iteration. + """ + global _NUMBA_SS_KERNEL + if _NUMBA_SS_KERNEL is not None: + return _NUMBA_SS_KERNEL + from numba import njit, prange + + @njit(cache=True) # pragma: no cover - njit + def _line(cw, cwx, cwxx, cwa, cwxa, xs, ws, a, m, h, n, cv, out): # type: ignore[no-untyped-def] + eps = 2.220446049250313e-16 + for i in range(n): + lo = h + i - m + hi = h + i + m + 1 + w_sum = cw[hi] - cw[lo] + tw = cwx[hi] - cwx[lo] + ttw = cwxx[hi] - cwxx[lo] + yw = cwa[hi] - cwa[lo] + tyw = cwxa[hi] - cwxa[lo] + if cv: + w_sum -= ws[i] + tw -= ws[i] * xs[i] + ttw -= ws[i] * xs[i] * xs[i] + yw -= ws[i] * a[i] + tyw -= ws[i] * xs[i] * a[i] + denom = w_sum * ttw - tw * tw + if denom > 32.0 * eps * w_sum * ttw: + slope = tyw * w_sum - tw * yw + icept = ttw * yw - tyw * tw + out[i] = (slope * xs[i] + icept) / denom + elif w_sum > 0.0: + out[i] = yw / w_sum + else: + out[i] = 0.0 + + @njit(cache=True) # pragma: no cover - njit + def _prefix(vals, xpad, wpad, m_pad, cwa, cwxa): # type: ignore[no-untyped-def] + acc_a = 0.0 + acc_xa = 0.0 + cwa[0] = 0.0 + cwxa[0] = 0.0 + for j in range(m_pad): + wa = wpad[j] * vals[j] + acc_a += wa + acc_xa += wa * xpad[j] + cwa[j + 1] = acc_a + cwxa[j + 1] = acc_xa + + @njit(cache=True) # pragma: no cover - njit + def _pad_circular(a, h, n, out): # type: ignore[no-untyped-def] + for j in range(h): + out[j] = a[n - h + j] + for j in range(n): + out[h + j] = a[j] + for j in range(h): + out[h + n + j] = a[j] + + @njit(parallel=True, cache=True, fastmath=False) # pragma: no cover - njit + def _kernel( # type: ignore[no-untyped-def] + tau, y, w, inv_dy, freqs, windows, span_fracs, j_mid, j_fin, + alpha, use_alpha, baseline, + ): + nf = freqs.shape[0] + n = tau.shape[0] + n_spans = windows.shape[0] + h = j_mid // 2 + if j_fin // 2 > h: + h = j_fin // 2 + for k in range(n_spans): + if windows[k] // 2 > h: + h = windows[k] // 2 + m_pad = n + 2 * h + eps = 2.220446049250313e-16 + out = np.empty(nf) + for p in prange(nf): + f = freqs[p] + x = np.empty(n) + for j in range(n): + q = tau[j] * f + x[j] = q - np.floor(q) + order = np.argsort(x) + xs = np.empty(n) + ys = np.empty(n) + ws = np.empty(n) + ids = np.empty(n) + for j in range(n): + o = order[j] + xs[j] = x[o] + ys[j] = y[o] + ws[j] = w[o] + ids[j] = inv_dy[o] + xpad = np.empty(m_pad) + for j in range(h): + xpad[j] = xs[n - h + j] - 1.0 + xpad[h + n + j] = xs[j] + 1.0 + for j in range(n): + xpad[h + j] = xs[j] + wpad = np.empty(m_pad) + _pad_circular(ws, h, n, wpad) + + cw = np.empty(m_pad + 1) + cwx = np.empty(m_pad + 1) + cwxx = np.empty(m_pad + 1) + acc_w = 0.0 + acc_x = 0.0 + acc_xx = 0.0 + cw[0] = 0.0 + cwx[0] = 0.0 + cwxx[0] = 0.0 + for j in range(m_pad): + wj = wpad[j] + xj = xpad[j] + acc_w += wj + acc_x += wj * xj + acc_xx += wj * xj * xj + cw[j + 1] = acc_w + cwx[j + 1] = acc_x + cwxx[j + 1] = acc_xx + + apad = np.empty(m_pad) + cwa = np.empty(m_pad + 1) + cwxa = np.empty(m_pad + 1) + _pad_circular(ys, h, n, apad) + _prefix(apad, xpad, wpad, m_pad, cwa, cwxa) + curves = np.empty((n_spans, n)) + for k in range(n_spans): + _line(cw, cwx, cwxx, cwa, cwxa, xs, ws, ys, + windows[k] // 2, h, n, True, curves[k]) + + if n_spans == 1: + raw = curves[0].copy() + else: + sm_res = np.empty((n_spans, n)) + resid = np.empty(n) + for k in range(n_spans): + for j in range(n): + d = curves[k, j] - ys[j] + resid[j] = (d if d >= 0.0 else -d) * ids[j] + _pad_circular(resid, h, n, apad) + _prefix(apad, xpad, wpad, m_pad, cwa, cwxa) + _line(cw, cwx, cwxx, cwa, cwxa, xs, ws, resid, + j_mid // 2, h, n, False, sm_res[k]) + best = np.empty(n) + for j in range(n): + kbest = 0 + vbest = sm_res[0, j] + for k in range(1, n_spans): + if sm_res[k, j] < vbest: + vbest = sm_res[k, j] + kbest = k + best[j] = span_fracs[kbest] + if use_alpha: + for j in range(n): + minres = sm_res[0, j] + for k in range(1, n_spans): + if sm_res[k, j] < minres: + minres = sm_res[k, j] + if minres < 0.0: + minres = 0.0 + last = sm_res[n_spans - 1, j] + if last < eps: + last = eps + factor = (minres / last) ** (10.0 - alpha) + if factor > 1.0: + factor = 1.0 + best[j] = best[j] + factor * ( + span_fracs[n_spans - 1] - best[j] + ) + _pad_circular(best, h, n, apad) + _prefix(apad, xpad, wpad, m_pad, cwa, cwxa) + sm_spans = np.empty(n) + _line(cw, cwx, cwxx, cwa, cwxa, xs, ws, best, + j_mid // 2, h, n, False, sm_spans) + raw = np.empty(n) + for j in range(n): + q = sm_spans[j] + if q < span_fracs[0]: + q = span_fracs[0] + elif q > span_fracs[n_spans - 1]: + q = span_fracs[n_spans - 1] + k = n_spans - 1 + for kk in range(1, n_spans): + if q < span_fracs[kk]: + k = kk + break + raw[j] = curves[k - 1, j] + (q - span_fracs[k - 1]) * ( + curves[k, j] - curves[k - 1, j] + ) / (span_fracs[k] - span_fracs[k - 1]) + + _pad_circular(raw, h, n, apad) + _prefix(apad, xpad, wpad, m_pad, cwa, cwxa) + model = np.empty(n) + _line(cw, cwx, cwxx, cwa, cwxa, xs, ws, raw, + j_fin // 2, h, n, False, model) + acc = 0.0 + for j in range(n): + d = ys[j] - model[j] + acc += (d if d >= 0.0 else -d) * ids[j] + out[p] = 1.0 - (acc / n) / baseline + return out + + _NUMBA_SS_KERNEL = _kernel + return _kernel + + +# --- public dispatch ---------------------------------------------------------- + + +def supersmoother_score( + t: FloatArray, + y: FloatArray, + dy: FloatArray | None, + periods: FloatArray, + *, + primary_spans: tuple[float, ...] = (0.05, 0.2, 0.5), + middle_span: float = 0.2, + final_span: float = 0.05, + bass_enhancement: float | None = None, + backend: str = "numpy", + batch: int = 0, + precision: str = "auto", +) -> FloatArray: + """SuperSmoother periodogram score for each trial period. + + Parameters + ---------- + t, y : numpy.ndarray + Finite times (days) and values of one band. + dy : numpy.ndarray or None + 1-sigma errors, or ``None`` for uniform weights. + periods : numpy.ndarray + Trial periods (days). + primary_spans : tuple of float, default (0.05, 0.2, 0.5) + Candidate span fractions, strictly increasing, each in (0, 1]. + middle_span, final_span : float + Spans of the residual/span smoothing and of the final pass. + bass_enhancement : float, optional + Friedman's ``alpha`` in [0, 10]; ``None`` disables it. + backend : str, default "numpy" + ``"numpy"``, ``"numba"``, ``"cupy"``, or ``"torch"`` / ``"torch:"``. + batch : int, default 0 + Trial periods per vectorized chunk (capped by a byte budget); 0 + auto-sizes the chunk — much larger on device backends, whose + single-shot latency is per-chunk dispatch overhead, not arithmetic. + The chunk does not affect the result. + precision : str, default "auto" + Compute dtype for the cupy/torch paths (numpy/numba always run float64). + + Returns + ------- + numpy.ndarray + ``score`` per period, maximized at the true period; 1 is a perfect fit + and 0 means no improvement over a constant. All zeros for a constant + signal. + """ + t = np.ascontiguousarray(t, dtype=np.float64) + y = np.ascontiguousarray(y, dtype=np.float64) + periods_host = np.ascontiguousarray(periods, dtype=np.float64) + if periods_host.size == 0: + return np.zeros(0, dtype=np.float64) + n = t.size + if dy is None: + inv_dy = np.ones(n, dtype=np.float64) + else: + inv_dy = 1.0 / np.ascontiguousarray(dy, dtype=np.float64) + w = inv_dy * inv_dy + w = w / w.sum() + mu = float(np.dot(w, y)) + y0 = y - mu + baseline = float(np.mean(np.abs(y0) * inv_dy)) + if not np.isfinite(baseline) or baseline <= 0.0: + return np.zeros(periods_host.size, dtype=np.float64) + tau = t - t.min() + freqs = 1.0 / periods_host + + spans = tuple(float(s) for s in primary_spans) + windows = span_windows(spans, n) + j_mid = span_windows((middle_span,), n)[0] + j_fin = span_windows((final_span,), n)[0] + alpha = None if bass_enhancement is None else float(bass_enhancement) + + if backend == "numba": + kernel = _numba_ss_kernel() + return np.asarray( + kernel( + tau, y0, w, inv_dy, freqs, + np.asarray(windows, dtype=np.int64), + np.asarray(spans, dtype=np.float64), + j_mid, j_fin, + 0.0 if alpha is None else alpha, alpha is not None, baseline, + ), + dtype=np.float64, + ) + if backend == "cupy": + ensure_cuda_dll_path() + import cupy as cp + + rdtype = ( + np.float32 + if resolve_precision(precision, "cuda") == "float32" + else np.float64 + ) + xp = array_namespace(cp.asarray(tau)) + return _score_batches( + xp, + cp.asarray(tau.astype(rdtype)), cp.asarray(y0.astype(rdtype)), + cp.asarray(w.astype(rdtype)), cp.asarray(inv_dy.astype(rdtype)), + freqs, + span_fracs=spans, windows=windows, j_mid=j_mid, j_fin=j_fin, + alpha=alpha, baseline=baseline, + chunk=_resolve_chunk(batch, n, on_device=True), + ) + if backend == "torch" or backend.startswith("torch:"): + import torch + + device = backend.split(":", 1)[1] if ":" in backend else "cpu" + tdtype = ( + torch.float32 + if resolve_precision(precision, device) == "float32" + else torch.float64 + ) + tau_d = to_device_array(tau, device=device, dtype=tdtype) + return _score_batches( + array_namespace(tau_d), + tau_d, + to_device_array(y0, device=device, dtype=tdtype), + to_device_array(w, device=device, dtype=tdtype), + to_device_array(inv_dy, device=device, dtype=tdtype), + freqs, + span_fracs=spans, windows=windows, j_mid=j_mid, j_fin=j_fin, + alpha=alpha, baseline=baseline, + chunk=_resolve_chunk(batch, n, on_device=device != "cpu"), + ) + if backend != "numpy": + raise ValueError(f"unknown backend {backend!r}") + return _score_batches( + array_namespace(periods_host), + tau, y0, w, inv_dy, freqs, + span_fracs=spans, windows=windows, j_mid=j_mid, j_fin=j_fin, + alpha=alpha, baseline=baseline, + chunk=_resolve_chunk(batch, n, on_device=False), + ) + + +# --- method wrapper ----------------------------------------------------------- + + +class SuperSmootherMethod(PeriodogramMethod): + """SuperSmoother method (numba/numpy CPU, cupy GPU, torch portable).""" + + name: ClassVar[str] = "SUPERSMOOTHER" + objective_sense: ClassVar[Literal["max", "min"]] = "max" + supports_multiband: ClassVar[bool] = True + settings_cls: ClassVar[type] = SuperSmootherSettings + cpu_backend: ClassVar[str] = "numpy" + fast_cpu_backend: ClassVar[str | None] = "numba" + gpu_backend: ClassVar[str | None] = "cupy" + portable_gpu_backend: ClassVar[str | None] = "torch" + all_backends: ClassVar[tuple[str, ...]] = ("numba", "numpy", "cupy", "torch") + + def default_grid(self, lc: LightCurve, settings: SuperSmootherSettings) -> GridSpec: # type: ignore[override] + finite = lc.finite() + if finite.baseline <= 0.0: + raise InsufficientDataError("SUPERSMOOTHER: no usable time baseline") + minimum = settings.minimum_frequency or 1.0 / finite.baseline + maximum = settings.maximum_frequency or pseudo_nyquist_frequency( + finite.time, settings.nyquist_factor + ) + return uniform_frequency_grid( + finite.baseline, + maximum_frequency=maximum, + minimum_frequency=minimum, + samples_per_peak=settings.samples_per_peak, + ) + + def power( # type: ignore[override] + self, + grid: GridSpec, + lc: LightCurve, + settings: SuperSmootherSettings, + backend: str, + engine: object | None = None, + ) -> Periodogram: + finite = lc.finite() + n = finite.n + if n < settings.min_detections: + raise InsufficientDataError( + f"SUPERSMOOTHER: {n} finite points < min_detections " + f"{settings.min_detections}" + ) + if finite.baseline <= 0.0: + raise InsufficientDataError("SUPERSMOOTHER: no usable time baseline") + periods = grid.period + if backend == "torch" or backend.startswith("torch:"): + backend = f"torch:{resolve_torch_device(backend, settings.device)}" + score = supersmoother_score( + finite.time, + finite.value, + finite.error, + periods, + primary_spans=settings.primary_spans, + middle_span=settings.middle_span, + final_span=settings.final_span, + bass_enhancement=settings.bass_enhancement, + backend=backend, + batch=settings.batch_periods, + precision=settings.precision, + ) + return Periodogram.from_spectrum( + method="SUPERSMOOTHER", + backend=backend, + frequency=1.0 / periods, + power=score, + objective_sense="max", + n_samples=n, + baseline=finite.baseline, + meta=finite.meta, + ) + + def multiband_power( # type: ignore[override] + self, + grid: GridSpec, + mblc: MultiBandLightCurve, + settings: SuperSmootherSettings, + backend: str, + engine: object | None = None, + ) -> Periodogram: + from cuperiod.multiband.supersmoother_mb import supersmoother_multiband + + if backend == "torch" or backend.startswith("torch:"): + backend = f"torch:{resolve_torch_device(backend, settings.device)}" + return supersmoother_multiband(grid, mblc, settings, backend) + + def estimate_device_bytes(self, n_points: int) -> int: + return _DEVICE_CHUNK_BYTES + 64 * 1024**2 + n_points * 8 * 8 + + +register(SuperSmootherMethod()) + +__all__ = [ + "DEFAULT_BATCH", + "SuperSmootherMethod", + "span_windows", + "supersmoother_score", +] diff --git a/src/cuperiod/multiband/__init__.py b/src/cuperiod/multiband/__init__.py index 4a912de..6557ce8 100644 --- a/src/cuperiod/multiband/__init__.py +++ b/src/cuperiod/multiband/__init__.py @@ -1,4 +1,19 @@ -"""Multi-band periodogram variants (GLS, BLS, and later MHAOV).""" +"""Multi-band periodogram variants (GLS, BLS, MHAOV, PDM, CE, string-length, +SuperSmoother). + +One module per method, each exporting the single entry point the owning +:class:`~cuperiod.methods.base.PeriodogramMethod` calls from ``multiband_power``: +:func:`~cuperiod.multiband.gls_mb.gls_multiband_power`, +:func:`~cuperiod.multiband.bls_mb.bls_multiband_power`, +:func:`~cuperiod.multiband.mhaov_mb.mhaov_multiband_power`, +:func:`~cuperiod.multiband.pdm_mb.pdm_multiband_theta`, +:func:`~cuperiod.multiband.conditional_entropy_mb.ce_multiband_entropy`, +:func:`~cuperiod.multiband.string_length_mb.string_length_multiband` and +:func:`~cuperiod.multiband.supersmoother_mb.supersmoother_multiband`. + +The submodules are imported lazily by their methods (never here), so a single-band run +never pays for the multi-band code paths — hence the empty ``__all__``. +""" from __future__ import annotations diff --git a/src/cuperiod/multiband/conditional_entropy_mb.py b/src/cuperiod/multiband/conditional_entropy_mb.py new file mode 100644 index 0000000..9a9ee2c --- /dev/null +++ b/src/cuperiod/multiband/conditional_entropy_mb.py @@ -0,0 +1,109 @@ +"""Multi-band conditional-entropy period search. + +Conditional entropy asks how well phase predicts brightness (Graham et al. 2013). That +question is filter-local: the g-band and r-band amplitudes, means and colours differ, so +a single joint phase-magnitude histogram would be smeared by the band offsets alone and +would look disordered at *every* trial period. Each band therefore gets its own +``(phase, magnitude)`` histogram — the single-band kernel rescales magnitudes to the +band's own range internally, which is exactly the per-band standardization wanted here — +and only the resulting entropies are pooled, + + H_mb(f) = sum_k n_k H_k(f) / sum_k n_k, + +with ``H_k`` the conditional entropy of band ``k`` and ``n_k`` its finite point count. +Since ``H_k`` is itself an average over that band's points (its Shannon sum divided by +``n_k``), weighting by ``n_k`` makes ``H_mb`` the conditional entropy per observation of +the whole data set: a well-sampled band counts for as much as its observations are +worth, and a handful of points in a third filter cannot outvote it. Ordered folds give +low entropy in every band at once, so this is a *minimization* method. +""" + +from __future__ import annotations + +import numpy as np + +from cuperiod.core.config import CESettings +from cuperiod.core.errors import InsufficientDataError +from cuperiod.core.grid import GridSpec +from cuperiod.core.lightcurve import MultiBandLightCurve +from cuperiod.core.result import Periodogram +from cuperiod.methods.conditional_entropy import conditional_entropy + +#: A band needs at least this many finite points to fill a usable 2-D histogram. +_MIN_BAND_POINTS = 8 + + +def ce_multiband_entropy( + grid: GridSpec, + mblc: MultiBandLightCurve, + settings: CESettings, + backend: str, +) -> Periodogram: + """Compute the pooled multi-band conditional entropy on ``grid``. + + Parameters + ---------- + grid : GridSpec + Shared trial grid (built from the stacked baseline); used as periods. + mblc : MultiBandLightCurve + Two or more bands of one star. + settings : CESettings + CE settings (histogram resolution, batching, ...); a band participates when it + has at least ``max(n_phase_bins, 8)`` finite points. + backend : str + Concrete backend (``"numpy"``, ``"numba"``, ``"cupy"``, ``"torch:"``). + + Returns + ------- + Periodogram + Point-count-weighted mean of the per-band entropies (minimized at the true + period). + + Raises + ------ + InsufficientDataError + If no band has enough finite points, or the stacked baseline is empty. + """ + finite = mblc.finite() + min_points = max(settings.n_phase_bins, _MIN_BAND_POINTS) + bands = [lc for lc in finite.bands.values() if lc.n >= min_points] + if not bands: + raise InsufficientDataError( + f"CE multiband: no band has {min_points} finite points" + ) + stacked_time, _, _, _ = finite.stacked() + baseline = float(stacked_time.max() - stacked_time.min()) + if baseline <= 0.0: + raise InsufficientDataError("CE multiband: no usable time baseline") + + periods = grid.period + pooled = np.zeros(periods.size, dtype=np.float64) + n_total = 0 + for lc in bands: + entropy = conditional_entropy( + lc.time, + lc.value, + periods, + n_phase_bins=settings.n_phase_bins, + n_mag_bins=settings.n_mag_bins, + backend=backend, + batch=settings.batch_periods, + precision=settings.precision, + ) + pooled += float(lc.n) * entropy + n_total += lc.n + power = pooled / float(n_total) + + return Periodogram.from_spectrum( + method="CE", + backend=backend, + frequency=1.0 / periods, + power=power, + objective_sense="min", + n_samples=n_total, + baseline=baseline, + meta={**dict(finite.meta), "bands": finite.band_names}, + ) + + +__all__ = ["ce_multiband_entropy"] diff --git a/src/cuperiod/multiband/fap_mb.py b/src/cuperiod/multiband/fap_mb.py new file mode 100644 index 0000000..14c953f --- /dev/null +++ b/src/cuperiod/multiband/fap_mb.py @@ -0,0 +1,335 @@ +"""Bootstrap false-alarm statistics for the multi-band GLS. + +astropy's ``LombScargleMultiband`` ships no false-alarm probabilities at all — +the single-band analytic formulas assume one sinusoid fit to one band. cuPeriod +calibrates the multi-band periodogram honestly instead, with a within-band +bootstrap: under the null hypothesis of no coherent signal, each band's +``(value, error)`` pairs are exchangeable across that band's epochs, so they are +resampled with replacement while every observation time stays fixed. That +preserves the window function, the per-band sample sizes, and the +heteroskedastic error distribution while destroying phase coherence. The maximum +power over the searched grid is recorded for each resample, and the false-alarm +probability of an observed peak is its rank in that null sample: +``FAP(z) = (1 + #{max_r >= z}) / (R + 1)``. + +For the default ``offsets`` model on a NUFFT backend the bootstrap is nearly +free: the times never change, so every resample reuses the same nonuniform +points and the whole batch runs as multi-transform NUFFTs — the same ``K + 2`` +transforms as one power evaluation, each carrying a stack of bootstrap +strengths. The ``perband``/``flex`` models and the torch backend fall back to an +explicit loop over resamples (still native-speed per iteration). +""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any + +import numpy as np + +from cuperiod.core._typing import FloatArray +from cuperiod.core.backend import ensure_cuda_dll_path +from cuperiod.core.config import GLSSettings +from cuperiod.core.errors import InsufficientDataError +from cuperiod.core.grid import GridSpec +from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve +from cuperiod.methods.gls import _trig_sums +from cuperiod.multiband.gls_mb import ( + _MBPrep, + _offsets_assemble, + _prep_multiband, + gls_multiband_power, +) + + +@dataclass(frozen=True) +class MultibandFAP: + """The null distribution of the multi-band peak power, from a bootstrap. + + Parameters + ---------- + null_max : numpy.ndarray + Maximum power over the searched grid for each of the ``n_bootstrap`` + within-band resamples. + n_bootstrap : int + Number of resamples. + seed : int + Seed the resampling used. + model : str + The multi-band model that was calibrated (``mb_model``). + backend : str + Backend that computed the null powers. + """ + + null_max: FloatArray + n_bootstrap: int + seed: int + model: str + backend: str + + def fap(self, power: Any) -> Any: + """False-alarm probability of ``power`` against the bootstrap null. + + ``FAP(z) = (1 + #{null_max >= z}) / (n_bootstrap + 1)`` — the add-one + rank estimate, whose smallest resolvable value is + ``1 / (n_bootstrap + 1)``. Accepts a scalar or an array. + """ + z = np.asarray(power, dtype=np.float64) + sorted_null = np.sort(self.null_max) + below = np.searchsorted(sorted_null, z, side="left") + out = (1.0 + (sorted_null.size - below)) / (self.n_bootstrap + 1.0) + return float(out) if np.ndim(power) == 0 else out + + def level(self, fap: float) -> float: + """Power threshold whose false-alarm probability is ``fap``. + + The ``1 - fap`` quantile of the null maxima. Requires + ``fap >= 1 / (n_bootstrap + 1)`` — below that the bootstrap cannot + resolve the tail and more resamples are needed. + """ + if not 0.0 < fap <= 1.0: + raise ValueError(f"fap must be in (0, 1], got {fap}") + if fap * (self.n_bootstrap + 1) < 1.0: + raise ValueError( + f"fap={fap} is below the bootstrap resolution " + f"1/(n_bootstrap+1) = {1.0 / (self.n_bootstrap + 1):.2e}; " + "increase n_bootstrap" + ) + return float(np.quantile(self.null_max, 1.0 - fap)) + + +#: Device-memory budget for one bootstrap batch of trig-sum outputs (bytes). +_FAP_CHUNK_BYTES = 1 << 28 + + +def _resample_arrays( + prep: _MBPrep, n_bootstrap: int, seed: int +) -> tuple[FloatArray, FloatArray, list[FloatArray], FloatArray]: + """Within-band pair resampling, vectorized over all resamples. + + Returns the globally re-normalized weights ``(R, N)``, the band-centered + resampled values' strengths ``w * y`` ``(R, N)``, the per-band total weights + (each ``(R, 1)``), and the per-resample reference chi-squared ``(R, 1)``. + """ + rng = np.random.default_rng(seed) + n = prep.tau.size + u_raw = prep.w * prep.w_scale + u = np.empty((n_bootstrap, n), dtype=np.float64) + y = np.empty((n_bootstrap, n), dtype=np.float64) + for sl in prep.slices: + n_k = sl.stop - sl.start + idx = rng.integers(0, n_k, size=(n_bootstrap, n_k)) + u[:, sl] = u_raw[sl][idx] + y[:, sl] = prep.value[sl][idx] + w = u / u.sum(axis=1, keepdims=True) + band_weight: list[FloatArray] = [] + for sl in prep.slices: + w_k = w[:, sl].sum(axis=1, keepdims=True) + mean_k = (w[:, sl] * y[:, sl]).sum(axis=1, keepdims=True) / w_k + y[:, sl] -= mean_k + band_weight.append(w_k) + chi2_ref = (w * y * y).sum(axis=1, keepdims=True) + return w, w * y, band_weight, chi2_ref + + +def _null_max_offsets_nufft( + prep: _MBPrep, + f0: float, + df: float, + nf: int, + backend: str, + eps: float, + n_bootstrap: int, + seed: int, +) -> FloatArray: + """Null peak powers for the offsets model via multi-transform NUFFTs. + + All resamples share the observation times, so each batch runs the same + ``K + 2`` transforms as a single power evaluation with the bootstrap + strengths stacked along ``n_trans``; only the per-batch maxima return to + the host. + """ + w, wy, band_weight, chi2_ref = _resample_arrays(prep, n_bootstrap, seed) + + tau: Any = prep.tau + if backend == "cufinufft": + ensure_cuda_dll_path() + import cupy as cp + + xp: Any = cp + tau = cp.asarray(tau) + else: + xp = np + + n_bands = len(prep.slices) + denom = 16 * max(nf, 1) * (n_bands + 6) + r_chunk = max(1, _FAP_CHUNK_BYTES // denom) + null_max = np.empty(n_bootstrap, dtype=np.float64) + for start in range(0, n_bootstrap, r_chunk): + stop = min(start + r_chunk, n_bootstrap) + rows = slice(start, stop) + w_c: Any = xp.asarray(w[rows]) + wy_c: Any = xp.asarray(wy[rows]) + band_cs = [] + weights = [] + for sl, w_k in zip(prep.slices, band_weight, strict=True): + sw_k = _trig_sums(tau[sl], w_c[:, sl], f0, df, nf, backend, eps) # type: ignore[arg-type] + band_cs.append((sw_k.real, sw_k.imag)) + weights.append(xp.asarray(w_k[rows])) + swy = _trig_sums(tau, wy_c, f0, df, nf, backend, eps) # type: ignore[arg-type] + sw2 = _trig_sums(tau, w_c, 2.0 * f0, 2.0 * df, nf, backend, eps) # type: ignore[arg-type] + chi2_c = xp.asarray(chi2_ref[rows]) + if xp is np: + with np.errstate(divide="ignore", invalid="ignore"): + power = _offsets_assemble( + xp, sw2.real, sw2.imag, swy.real, swy.imag, + band_cs, weights, chi2_c, + ) + else: + power = _offsets_assemble( + xp, sw2.real, sw2.imag, swy.real, swy.imag, + band_cs, weights, chi2_c, + ) + batch_max = xp.max(power, axis=1) + null_max[rows] = np.asarray( + batch_max.get() if hasattr(batch_max, "get") else batch_max, + dtype=np.float64, + ) + return null_max + + +def _null_max_loop( + mblc: MultiBandLightCurve, + grid: GridSpec, + settings: GLSSettings, + backend: str, + n_bootstrap: int, + seed: int, +) -> FloatArray: + """Null peak powers by explicit recomputation (perband/flex models, torch). + + Each resample rebuilds the multi-band light curve with within-band + resampled ``(value, error)`` pairs and reruns the native power path. + """ + rng = np.random.default_rng(seed) + finite = mblc.finite() + quiet = settings.model_copy(update={"mb_fap_bootstrap": 0}) + null_max = np.empty(n_bootstrap, dtype=np.float64) + for r in range(n_bootstrap): + bands: dict[str, LightCurve] = {} + for name, lc in finite.bands.items(): + if lc.n == 0: + continue + idx = rng.integers(0, lc.n, size=lc.n) + bands[name] = LightCurve( + time=lc.time, + value=lc.value[idx], + error=None if lc.error is None else lc.error[idx], + domain=lc.domain, + ) + resampled = MultiBandLightCurve.from_light_curves(bands, meta=finite.meta) + pg = gls_multiband_power(grid, resampled, quiet, backend) + null_max[r] = float(pg.power.max()) if pg.power.size else 0.0 + return null_max + + +def bootstrap_null_max( + mblc: MultiBandLightCurve, + grid: GridSpec, + settings: GLSSettings, + backend: str, + n_bootstrap: int, + seed: int, +) -> FloatArray: + """Null distribution of the multi-band peak power on ``grid``. + + Dispatches to the batched-NUFFT fast path (offsets model on + finufft/cufinufft) or the explicit loop (everything else). + """ + if ( + settings.mb_model == "offsets" + and backend in ("finufft", "cufinufft") + and grid.uniform + ): + prep = _prep_multiband(mblc, settings) + f0, df, nf = grid.uniform_frequency_params() + return _null_max_offsets_nufft( + prep, f0, df, nf, backend, settings.nufft_eps, n_bootstrap, seed + ) + return _null_max_loop(mblc, grid, settings, backend, n_bootstrap, seed) + + +def multiband_fap( + data: Any, + settings: GLSSettings | None = None, + *, + grid: GridSpec | None = None, + backend: str = "auto", + n_bootstrap: int = 500, + seed: int = 0, +) -> MultibandFAP: + """Calibrate the multi-band GLS null distribution by within-band bootstrap. + + Parameters + ---------- + data : various + Anything :func:`cuperiod.to_input` accepts; a single-band + :class:`~cuperiod.LightCurve` is treated as a one-band set (giving an + honest bootstrap FAP for the plain GLS as well). + settings : GLSSettings, optional + GLS settings; ``mb_model`` selects the calibrated model. + grid : GridSpec, optional + Frequency grid; defaults to the method's grid for the stacked bands. + The false-alarm level of the *maximum* depends on the searched grid, so + pass the same grid used for the search. + backend : str, default "auto" + Backend selector, as :func:`cuperiod.periodogram`. + n_bootstrap : int, default 500 + Number of within-band resamples (the smallest resolvable FAP is + ``1 / (n_bootstrap + 1)``). + seed : int, default 0 + Resampling seed. + + Returns + ------- + MultibandFAP + The null sample with ``fap(power)`` and ``level(fap)`` accessors. + + Examples + -------- + >>> calib = multiband_fap(mblc, n_bootstrap=1000) # doctest: +SKIP + >>> pg = cup.periodogram(mblc, "GLS") # doctest: +SKIP + >>> calib.fap(pg.best_periods(1)[0].power) # doctest: +SKIP + >>> calib.level(0.01) # 1% false-alarm power threshold # doctest: +SKIP + """ + from cuperiod.api import to_input + from cuperiod.methods.gls import GLSMethod + + lc = to_input(data) + if isinstance(lc, LightCurve): + lc = MultiBandLightCurve.from_light_curves({"band": lc}, meta=lc.meta) + method = GLSMethod() + coerced = method.coerce_settings(settings) + assert isinstance(coerced, GLSSettings) + resolved = method.resolve_backend(backend) + if resolved == "astropy": + raise ValueError( + "multiband_fap needs a native backend (finufft/cufinufft/torch)" + ) + if grid is None: + from cuperiod.api import _multiband_grid + + grid = _multiband_grid(method, lc, coerced) + if grid.size == 0: + raise InsufficientDataError("multiband_fap: empty trial grid") + null_max = bootstrap_null_max(lc, grid, coerced, resolved, n_bootstrap, seed) + return MultibandFAP( + null_max=null_max, + n_bootstrap=n_bootstrap, + seed=seed, + model=coerced.mb_model, + backend=resolved, + ) + + +__all__ = ["MultibandFAP", "bootstrap_null_max", "multiband_fap"] diff --git a/src/cuperiod/multiband/gls_mb.py b/src/cuperiod/multiband/gls_mb.py index 38b3cdc..18bd90b 100644 --- a/src/cuperiod/multiband/gls_mb.py +++ b/src/cuperiod/multiband/gls_mb.py @@ -1,47 +1,774 @@ """Multi-band generalized Lomb-Scargle (VanderPlas & Ivezić 2015). -Several filters of the same star are fit jointly with a shared sinusoid on a common -phase plus per-band offset/amplitude terms — the model astropy implements as -``LombScargleMultiband``. This recovers a period even when no single band is sampled -well enough on its own, which is the common situation for multi-survey photometry. +Several filters of the same star are fit jointly at each trial frequency, which +recovers a period even when no single band is sampled well enough on its own — the +common situation for sparse multi-survey photometry and the Rubin/LSST cadence. + +Three models are offered (``GLSSettings.mb_model``), all named by how the bands +share the signal: + +``"offsets"`` (default) + One sinusoid on a shared phase plus an independent constant offset per band — + the shared-phase ``(N_base, N_band) = (1, 0)`` model of VanderPlas & Ivezić + (2015), their recommended search model for sparse multi-band data: all phase + information pools into two signal parameters while each band spends only one + nuisance parameter. cuPeriod evaluates it in closed form from band-projected + trigonometric sums — the per-band offsets are profiled out analytically, + leaving the Zechmeister-Kürster assembly with every sum replaced by its + band-centered counterpart — using ``K + 2`` NUFFTs, so the cost is close to a + single single-band GLS over the stacked points. + +``"perband"`` + The multi-phase ``(0, 1)`` model: each band is fit with its own floating-mean + sinusoid (independent amplitude *and phase*) and the per-band standard powers + are combined with the reference-chi-squared weights of VanderPlas & Ivezić + (2015, eq. 23): ``P = sum_k chi2_0k P_k / sum_k chi2_0k``. Note astropy's + ``method="fast"`` intends this combination but weighs bands by the summed + squared periodogram instead of ``chi2_0k`` (making its result depend on the + frequency grid); cuPeriod implements the published weighting. + +``"flex"`` + The flexible regularized model as implemented by astropy's + ``LombScargleMultiband`` flexible method: ``mb_nterms_base`` shared harmonics + plus ``mb_nterms_band`` harmonics-with-offset per band, ridge-regularized to + lift the base/band degeneracy. cuPeriod builds the per-frequency normal + equations from per-band harmonic trig sums (NUFFT or direct) and solves them + in batch, reproducing astropy's power to float64 accuracy — including the + trace-scaled ridge — on CPU, CUDA, or any torch device. + +The ``"astropy"`` backend delegates to ``astropy.timeseries.LombScargleMultiband`` +(``offsets`` maps to the flexible solver with ``(1, 0)`` terms, ``perband`` to +``(0, 1)``) and is the reference the native paths are tested against. """ from __future__ import annotations +from collections.abc import Sequence +from dataclasses import dataclass +from typing import Any + import numpy as np +from cuperiod.core._arrayapi import ( + array_namespace, + device_ref, + resolve_precision, + resolve_torch_device, + to_device_array, + to_host, +) +from cuperiod.core._typing import FloatArray +from cuperiod.core.backend import ensure_cuda_dll_path from cuperiod.core.config import GLSSettings from cuperiod.core.errors import InsufficientDataError from cuperiod.core.grid import GridSpec from cuperiod.core.lightcurve import MultiBandLightCurve from cuperiod.core.result import Periodogram +from cuperiod.methods.gls import ( + CufinufftGLS, + _gls_sums_direct, + _trig_sums, + lombscargle_power, + lombscargle_power_torch, +) +#: A band needs this many finite points to get its own sinusoid (perband model). +_MIN_PERBAND_POINTS = 3 -def gls_multiband_power( - grid: GridSpec, +#: Byte budget for one ``(chunk, p, p)`` normal-equation stack; the frequency +#: chunk adapts to the parameter count so large-``nterms``/many-band models +#: cannot blow device memory. +_FLEX_CHUNK_BYTES = 1 << 27 + + +@dataclass(frozen=True) +class _MBPrep: + """Stacked, band-contiguous arrays shared by the native multi-band paths. + + ``tau`` is referenced to the global earliest time; ``w`` sums to 1 across all + bands (inverse-variance, or uniform when any band lacks errors — mixing + weighted and unweighted bands would make the joint fit ill-defined) and + ``w_scale`` restores the raw ``sum(1/dy^2)`` scale where an absolute + normal-matrix scale matters (the flex model's un-traced ridge); ``y`` has each + band's weighted mean removed, so the per-band data sums need no explicit + offset terms and ``chi2_ref`` — the weighted variance about the per-band + means — is the reference chi-squared of the offsets-only null model. + """ + + tau: FloatArray + w: FloatArray + y: FloatArray + value: FloatArray + slices: tuple[slice, ...] + band_weight: tuple[float, ...] + w_scale: float + chi2_ref: float + n: int + baseline: float + band_names: tuple[str, ...] + + +def _prep_multiband(mblc: MultiBandLightCurve, settings: GLSSettings) -> _MBPrep: + """Validate, stack, weight, and band-center a multi-band light curve.""" + finite = mblc.finite() + bands = [(name, lc) for name, lc in finite.bands.items() if lc.n > 0] + n = sum(lc.n for _, lc in bands) + if n < settings.min_detections: + raise InsufficientDataError( + f"GLS multiband: {n} finite points < min_detections " + f"{settings.min_detections}" + ) + time = np.concatenate([lc.time for _, lc in bands]) + baseline = float(time.max() - time.min()) + if baseline <= 0.0: + raise InsufficientDataError("GLS multiband: no usable time baseline") + + value = np.concatenate([lc.value for _, lc in bands]) + use_errors = all(lc.error is not None for _, lc in bands) + if use_errors: + error = np.concatenate([lc.error for _, lc in bands]) # type: ignore[misc] + w = 1.0 / (error * error) + else: + w = np.ones_like(time) + w_scale = float(w.sum()) + w /= w_scale + + tau = time - time.min() + slices: list[slice] = [] + band_weight: list[float] = [] + y = value.copy() + start = 0 + for _, lc in bands: + stop = start + lc.n + sl = slice(start, stop) + wk = float(w[sl].sum()) + y[sl] -= float(np.dot(w[sl], value[sl])) / wk + slices.append(sl) + band_weight.append(wk) + start = stop + chi2_ref = float(np.dot(w, y * y)) + return _MBPrep( + tau=tau, + w=w, + y=y, + value=value, + slices=tuple(slices), + band_weight=tuple(band_weight), + w_scale=w_scale, + chi2_ref=chi2_ref, + n=n, + baseline=baseline, + band_names=tuple(name for name, _ in bands), + ) + + +def _nufft_sums( + tau: Any, + strengths: Any, + f0: float, + df: float, + nf: int, + backend: str, + eps: float, + engine: object | None, +) -> Any: + """One type-1 trig-sum transform, through the batch engine when one is supplied. + + The batch runner (and the interop partition kernel) hand the single-band + :class:`~cuperiod.methods.gls.CufinufftGLS` engine to the multi-band path too; + its bucketed plan cache serves the ``K + 2`` offsets transforms and the flex + harmonic sums equally well, since a plan is fixed by mode count and ``n_trans`` + alone. Anything other than a cufinufft engine on the cufinufft backend falls + through to the plain per-call transform. + """ + if backend == "cufinufft" and isinstance(engine, CufinufftGLS): + return engine.trig_sums(tau, strengths, f0, df, nf) + return _trig_sums(tau, strengths, f0, df, nf, backend, eps) # type: ignore[arg-type] + + +# --- offsets model ----------------------------------------------------------- + + +def _offsets_assemble( + xp: Any, + c2: Any, + s2: Any, + yc: Any, + ys: Any, + band_cs: list[tuple[Any, Any]], + band_weight: Sequence[Any], + chi2_ref: Any, +) -> Any: + """Offsets-model power from global and per-band trig sums. + + The per-band constant offsets are profiled out of the least squares, which + turns the usual floating-mean corrections ``cc - c*c`` (etc.) into their + band-projected counterparts ``CC - sum_k C_k^2 / W_k``: the same + Zechmeister-Kürster quadratic form, evaluated in the subspace orthogonal to + every band's constant. ``yc``/``ys`` are already band-centered because the + data strengths were. Degenerate frequencies map to 0. Everything is + elementwise, so the inputs may carry a leading batch axis (the bootstrap + path stacks resamples, with per-batch ``band_weight``/``chi2_ref`` + columns). + """ + cc = 0.5 * (1.0 + c2) + ss = 0.5 * (1.0 - c2) + cs = 0.5 * s2 + for (c_k, s_k), wk in zip(band_cs, band_weight, strict=True): + cc = cc - c_k * c_k / wk + ss = ss - s_k * s_k / wk + cs = cs - c_k * s_k / wk + denom = chi2_ref * (cc * ss - cs * cs) + power = (ss * yc * yc + cc * ys * ys - 2.0 * cs * yc * ys) / denom + return xp.where(xp.isfinite(power), power, xp.zeros_like(power)) + + +def _offsets_power_nufft( + prep: _MBPrep, + f0: float, + df: float, + nf: int, + backend: str, + eps: float, + engine: object | None = None, +) -> FloatArray: + """Offsets-model power via NUFFT band sums (finufft on CPU, cufinufft on GPU). + + ``K + 2`` type-1 transforms: per band the weight sums ``(C_k, S_k)``, one + global transform of the band-centered data strengths ``w*y``, and one global + doubled-grid transform of the weights. On the cufinufft path all inputs move + to the device once and the assembly stays there; only the final power crosses + back to the host. + """ + tau: Any = prep.tau + w: Any = prep.w + wy: Any = prep.w * prep.y + if backend == "cufinufft": + ensure_cuda_dll_path() + import cupy as cp + + xp: Any = cp + tau, w, wy = cp.asarray(tau), cp.asarray(w), cp.asarray(wy) + else: + xp = np + + band_cs: list[tuple[Any, Any]] = [] + for sl in prep.slices: + sw_k = _nufft_sums(tau[sl], w[sl][None, :], f0, df, nf, backend, eps, engine)[0] + band_cs.append((sw_k.real, sw_k.imag)) + swy = _nufft_sums(tau, wy[None, :], f0, df, nf, backend, eps, engine)[0] + sw2 = _nufft_sums(tau, w[None, :], 2.0 * f0, 2.0 * df, nf, backend, eps, engine)[0] + + if xp is np: + with np.errstate(divide="ignore", invalid="ignore"): + power = _offsets_assemble( + xp, sw2.real, sw2.imag, swy.real, swy.imag, + band_cs, prep.band_weight, prep.chi2_ref, + ) + else: + power = _offsets_assemble( + xp, sw2.real, sw2.imag, swy.real, swy.imag, + band_cs, prep.band_weight, prep.chi2_ref, + ) + return to_host(power) + + +def _offsets_power_torch( + prep: _MBPrep, + f0: float, + df: float, + nf: int, + *, + device: str, + precision: str, + freq_batch: int, +) -> FloatArray: + """Offsets-model power via the portable per-band direct trig sums. + + Runs :func:`~cuperiod.methods.gls._gls_sums_direct` once per band (the global + sums are the accumulated band sums) and feeds the band-projected assembly, so + it works on any torch device — including float32-only Apple MPS. + """ + import torch + + prec = resolve_precision(precision, device) + tdtype = torch.float32 if prec == "float32" else torch.float64 + tau_d = to_device_array(prep.tau, device=device, dtype=tdtype) + w_d = to_device_array(prep.w, device=device, dtype=tdtype) + wy_d = to_device_array(prep.w * prep.y, device=device, dtype=tdtype) + xp = array_namespace(tau_d) + + yc = ys = c2 = s2 = None + band_cs: list[tuple[Any, Any]] = [] + for sl in prep.slices: + c_k, s_k, yc_k, ys_k, c2_k, s2_k = _gls_sums_direct( + xp, tau_d[sl], w_d[sl], wy_d[sl], f0, df, nf, freq_batch=freq_batch + ) + band_cs.append((c_k, s_k)) + yc = yc_k if yc is None else yc + yc_k + ys = ys_k if ys is None else ys + ys_k + c2 = c2_k if c2 is None else c2 + c2_k + s2 = s2_k if s2 is None else s2 + s2_k + power = _offsets_assemble( + xp, c2, s2, yc, ys, band_cs, prep.band_weight, prep.chi2_ref + ) + return to_host(power) + + +# --- perband model ----------------------------------------------------------- + + +def _perband_power( mblc: MultiBandLightCurve, + f0: float, + df: float, + nf: int, + backend: str, settings: GLSSettings, -) -> Periodogram: - """Compute the multi-band GLS power on ``grid``. + engine: object | None = None, +) -> tuple[FloatArray, int, float, tuple[str, ...]]: + """Multi-phase ``(0, 1)`` model: chi2_0-weighted per-band floating-mean GLS. - Parameters - ---------- - grid : GridSpec - Frequency grid (built from the stacked baseline). - mblc : MultiBandLightCurve - Two or more bands of one star. - settings : GLSSettings - GLS settings (``fit_mean`` selects the floating-mean base model). + Each band with at least :data:`_MIN_PERBAND_POINTS` finite points is fit + independently (its own amplitude and phase) with the native single-band GLS on + the shared grid, and the standard-normalized powers are combined with the + per-band reference chi-squared weights of VanderPlas & Ivezić (2015, eq. 23). + """ + finite = mblc.finite() + bands = [ + (name, lc) for name, lc in finite.bands.items() + if lc.n >= _MIN_PERBAND_POINTS + ] + n = sum(lc.n for _, lc in bands) + if not bands or n < settings.min_detections: + raise InsufficientDataError( + f"GLS multiband: {n} finite points across usable bands " + f"< min_detections {settings.min_detections}" + ) + time = np.concatenate([lc.time for _, lc in bands]) + baseline = float(time.max() - time.min()) + if baseline <= 0.0: + raise InsufficientDataError("GLS multiband: no usable time baseline") - Returns - ------- - Periodogram - The joint power spectrum (backend ``"astropy"``). + combined: FloatArray | None = None + weight_sum = 0.0 + for _, lc in bands: + w_k = np.ones(lc.n) if lc.error is None else 1.0 / (lc.error * lc.error) + mean_k = float(np.dot(w_k, lc.value) / w_k.sum()) + chi2_0k = float(np.dot(w_k, (lc.value - mean_k) ** 2)) + if backend == "torch" or backend.startswith("torch:"): + device = backend.split(":", 1)[1] if ":" in backend else "cpu" + p_k = lombscargle_power_torch( + lc.time, lc.value, lc.error, f0, df, nf, + fit_mean=True, + device=device, + precision=settings.precision, + freq_batch=settings.direct_freq_batch, + ) + elif backend == "cufinufft" and isinstance(engine, CufinufftGLS): + p_k = engine.power( + lc.time, lc.value, lc.error, f0, df, nf, fit_mean=True + ) + else: + p_k = lombscargle_power( + lc.time, lc.value, lc.error, f0, df, nf, + fit_mean=True, + backend=backend, # type: ignore[arg-type] + eps=settings.nufft_eps, + ) + contribution = chi2_0k * p_k + combined = contribution if combined is None else combined + contribution + weight_sum += chi2_0k + assert combined is not None + power = combined / weight_sum if weight_sum > 0.0 else np.zeros_like(combined) + return power, n, baseline, tuple(name for name, _ in bands) - Raises - ------ - InsufficientDataError - If too few finite points remain across all bands. + +# --- flexible model ---------------------------------------------------------- + + +@dataclass(frozen=True) +class _BandSums: + """Per-band harmonic trig sums feeding the flex normal equations. + + ``cw[m]``/``sw[m]`` hold ``sum_j w_j cos/sin(2 pi m f tau_j)`` over this + band's points for ``m = 1..H`` (frequency arrays); ``cy[n]``/``sy[n]`` the + same with strengths ``w*y``. ``w0``/``y0`` are the ``m = 0`` scalars (the + band's total weight and weighted data sum). + """ + + cw: list[Any] + sw: list[Any] + cy: list[Any] + sy: list[Any] + w0: float + y0: float + + +def _flex_orders(nterms_base: int, nterms_band: int) -> tuple[int, int]: + """(weight-sum harmonic order, data-sum harmonic order) for the flex model. + + Normal-matrix entries are products of two harmonics of order at most + ``max(nb, nk)``, so the weight sums are needed to twice that; the right-hand + side pairs one harmonic with the data. + """ + m = max(nterms_base, nterms_band) + return 2 * m, m + + +def _flex_sums_nufft( + prep: _MBPrep, f0: float, df: float, nf: int, backend: str, eps: float, + h_w: int, h_wy: int, engine: object | None = None, +) -> list[_BandSums]: + """Per-band harmonic sums via NUFFT (harmonic ``m`` runs on the ``m``-scaled + grid; the ``w``/``w*y`` pair shares one batched transform where both are + needed).""" + tau: Any = prep.tau + w: Any = prep.w + wy: Any = prep.w * prep.y + if backend == "cufinufft": + ensure_cuda_dll_path() + import cupy as cp + + tau, w, wy = cp.asarray(tau), cp.asarray(w), cp.asarray(wy) + + xp: Any = np + if backend == "cufinufft": + import cupy as cp + + xp = cp + out: list[_BandSums] = [] + for sl, wk in zip(prep.slices, prep.band_weight, strict=True): + cw: list[Any] = [None] + sw: list[Any] = [None] + cy: list[Any] = [None] + sy: list[Any] = [None] + pair = xp.stack([w[sl], wy[sl]]) + for m in range(1, h_w + 1): + strengths = pair if m <= h_wy else pair[:1] + sums = _nufft_sums( + tau[sl], strengths, m * f0, m * df, nf, backend, eps, engine + ) + cw.append(sums[0].real) + sw.append(sums[0].imag) + if m <= h_wy: + cy.append(sums[1].real) + sy.append(sums[1].imag) + y0 = float(np.dot(prep.w[sl], prep.y[sl])) + out.append(_BandSums(cw=cw, sw=sw, cy=cy, sy=sy, w0=wk, y0=y0)) + return out + + +def _flex_sums_direct( + xp: Any, tau: Any, w: Any, wy: Any, f0: float, df: float, nf: int, + h_w: int, h_wy: int, freq_batch: int, +) -> tuple[list[Any], list[Any], list[Any], list[Any]]: + """One band's harmonic sums by direct trig evaluation (the portable path). + + Harmonics are chained with the angle-addition recurrence, so ``cos``/``sin`` + are evaluated once per frequency regardless of the harmonic order. Chunked + over frequency like the single-band direct path. + """ + from cuperiod.methods.gls import _DIRECT_CHUNK_ELEMS + + fdtype = tau.dtype + dev = device_ref(tau) + n_points = int(tau.shape[0]) + chunk = max(1, min(freq_batch, _DIRECT_CHUNK_ELEMS // max(1, n_points))) + freqs = f0 + df * xp.arange(nf, dtype=fdtype, device=dev) + cw = [None] + [xp.empty(nf, dtype=fdtype, device=dev) for _ in range(h_w)] + sw = [None] + [xp.empty(nf, dtype=fdtype, device=dev) for _ in range(h_w)] + cy = [None] + [xp.empty(nf, dtype=fdtype, device=dev) for _ in range(h_wy)] + sy = [None] + [xp.empty(nf, dtype=fdtype, device=dev) for _ in range(h_wy)] + two_pi = 2.0 * float(np.pi) + w_row = w[None, :] + wy_row = wy[None, :] + for start in range(0, nf, chunk): + stop = min(start + chunk, nf) + ang = (two_pi * freqs[start:stop])[:, None] * tau[None, :] + cos1 = xp.cos(ang) + sin1 = xp.sin(ang) + cos_m, sin_m = cos1, sin1 + for m in range(1, h_w + 1): + cw[m][start:stop] = xp.sum(w_row * cos_m, axis=1) + sw[m][start:stop] = xp.sum(w_row * sin_m, axis=1) + if m <= h_wy: + cy[m][start:stop] = xp.sum(wy_row * cos_m, axis=1) + sy[m][start:stop] = xp.sum(wy_row * sin_m, axis=1) + if m < h_w: + cos_next = cos_m * cos1 - sin_m * sin1 + sin_m = sin_m * cos1 + cos_m * sin1 + cos_m = cos_next + return cw, sw, cy, sy + + +#: Column descriptor: (band index or -1 for base, kind, harmonic order). +_FlexCol = tuple[int, str, int] + + +def _flex_columns(n_bands: int, nb: int, nk: int) -> list[_FlexCol]: + """The flex design columns in astropy's order (base block, then per band).""" + cols: list[_FlexCol] = [(-1, "const", 0)] + for n in range(1, nb + 1): + cols.append((-1, "sin", n)) + cols.append((-1, "cos", n)) + for b in range(n_bands): + cols.append((b, "const", 0)) + for n in range(1, nk + 1): + cols.append((b, "sin", n)) + cols.append((b, "cos", n)) + return cols + + +def _pair_entry( + c_of: Any, s_of: Any, ki: str, ni: int, kj: str, nj: int +) -> Any: + """``_w`` from the restriction's harmonic sums. + + ``c_of(m)``/``s_of(m)`` return the ``cos``/``sin`` weight sums of the + relevant restriction (one band, or the whole set) at harmonic ``m``; the + product-to-sum identities reduce every entry to at most two of them. + """ + if ki == "const" and kj == "const": + return c_of(0) + if ki == "const": + return s_of(nj) if kj == "sin" else c_of(nj) + if kj == "const": + return s_of(ni) if ki == "sin" else c_of(ni) + if ki == "sin" and kj == "sin": + return 0.5 * (c_of(abs(ni - nj)) - c_of(ni + nj)) + if ki == "cos" and kj == "cos": + return 0.5 * (c_of(abs(ni - nj)) + c_of(ni + nj)) + n_s, n_c = (ni, nj) if ki == "sin" else (nj, ni) + if n_s == n_c: + return 0.5 * s_of(n_s + n_c) + sign = 1.0 if n_s > n_c else -1.0 + return 0.5 * (s_of(n_s + n_c) + sign * s_of(abs(n_s - n_c))) + + +def _flex_power_from_sums( + xp: Any, + band_sums: list[_BandSums], + chi2_ref: float, + w_scale: float, + nf: int, + settings: GLSSettings, + fdtype: Any, + dev: Any, +) -> Any: + """Assemble and solve the regularized normal equations in frequency batches. + + Reproduces astropy's ``lombscargle_mbflex``: normal matrix ``G`` and + right-hand side ``b`` built from the (band-centered, weighted) harmonic sums, + ridge ``diag(G) += trace(G) * reg`` (or ``+= reg`` when + ``mb_regularize_by_trace=False`` — the sums are restored to astropy's raw + ``1/dy^2`` scale via ``w_scale`` so the absolute ridge means the same thing), + then ``P = b . solve(G, b) / chi2_ref``. Singular chunks fall back to a + per-frequency least-squares solve on the host, mirroring astropy's + ``lstsq`` fallback. + """ + nb, nk = settings.mb_nterms_base, settings.mb_nterms_band + n_bands = len(band_sums) + cols = _flex_columns(n_bands, nb, nk) + p = len(cols) + n_base = 1 + 2 * nb + + reg = np.zeros(p, dtype=np.float64) + if settings.mb_reg_base is not None: + reg[:n_base] = settings.mb_reg_base + if settings.mb_reg_band is not None: + reg[n_base:] = settings.mb_reg_band + reg_d = ( + xp.asarray(reg, dtype=fdtype) + if dev is None + else xp.asarray(reg, dtype=fdtype, device=dev) + ) + + scale = float(w_scale) + chi2_0 = chi2_ref * scale + + def restriction(b: int, sl: slice) -> tuple[Any, Any, Any, Any]: + """(c_of, s_of, cy_of, sy_of) accessors for band ``b`` (or all, b=-1).""" + if b >= 0: + bs = band_sums[b] + + def c_of(m: int) -> Any: + return bs.w0 * scale if m == 0 else scale * bs.cw[m][sl] + + def s_of(m: int) -> Any: + return 0.0 if m == 0 else scale * bs.sw[m][sl] + + def cy_of(m: int) -> Any: + return bs.y0 * scale if m == 0 else scale * bs.cy[m][sl] + + def sy_of(m: int) -> Any: + return 0.0 if m == 0 else scale * bs.sy[m][sl] + + else: + + def c_of(m: int) -> Any: + if m == 0: + return sum(bs.w0 for bs in band_sums) * scale + total = band_sums[0].cw[m][sl] + for bs in band_sums[1:]: + total = total + bs.cw[m][sl] + return scale * total + + def s_of(m: int) -> Any: + if m == 0: + return 0.0 + total = band_sums[0].sw[m][sl] + for bs in band_sums[1:]: + total = total + bs.sw[m][sl] + return scale * total + + def cy_of(m: int) -> Any: + if m == 0: + return sum(bs.y0 for bs in band_sums) * scale + total = band_sums[0].cy[m][sl] + for bs in band_sums[1:]: + total = total + bs.cy[m][sl] + return scale * total + + def sy_of(m: int) -> Any: + if m == 0: + return 0.0 + total = band_sums[0].sy[m][sl] + for bs in band_sums[1:]: + total = total + bs.sy[m][sl] + return scale * total + + return c_of, s_of, cy_of, sy_of + + diag_idx = xp.arange(p) if dev is None else xp.arange(p, device=dev) + power = ( + xp.empty(nf, dtype=fdtype) + if dev is None + else xp.empty(nf, dtype=fdtype, device=dev) + ) + chunk = max(256, _FLEX_CHUNK_BYTES // (p * p * 8)) + for start in range(0, nf, chunk): + stop = min(start + chunk, nf) + sl = slice(start, stop) + n_chunk = stop - start + if dev is None: + g = xp.zeros((n_chunk, p, p), dtype=fdtype) + b_vec = xp.zeros((n_chunk, p), dtype=fdtype) + else: + g = xp.zeros((n_chunk, p, p), dtype=fdtype, device=dev) + b_vec = xp.zeros((n_chunk, p), dtype=fdtype, device=dev) + accessors = {b: restriction(b, sl) for b in range(-1, n_bands)} + for i, (bi, ki, ni) in enumerate(cols): + c_of, s_of, cy_of, sy_of = accessors[bi] + b_vec[:, i] = sy_of(ni) if ki == "sin" else cy_of(ni) + for j in range(i, p): + bj, kj, nj = cols[j] + if bi >= 0 and bj >= 0 and bi != bj: + continue # disjoint band indicators: exactly zero + # The tighter restriction wins: base x band-k pairs live on + # band k's points. + c_r, s_r, _, _ = accessors[bj if bj >= 0 else bi] + entry = _pair_entry(c_r, s_r, ki, ni, kj, nj) + g[:, i, j] = entry + if j != i: + g[:, j, i] = entry + trace = xp.sum(g[:, diag_idx, diag_idx], axis=-1) + if settings.mb_regularize_by_trace: + g[:, diag_idx, diag_idx] += trace[:, None] * reg_d + else: + g[:, diag_idx, diag_idx] += reg_d + try: + theta = xp.linalg.solve(g, b_vec[..., None])[..., 0] + dchi2 = xp.sum(b_vec * theta, axis=-1) + except Exception: + # Singular normal matrix somewhere in the chunk (e.g. ridge disabled): + # astropy falls back to lstsq per frequency; do the same on the host. + g_h, b_h = to_host(g), to_host(b_vec) + dchi2_h = np.empty(n_chunk, dtype=np.float64) + for k in range(n_chunk): + try: + theta_k = np.linalg.solve(g_h[k], b_h[k]) + except np.linalg.LinAlgError: + theta_k = np.linalg.lstsq(g_h[k], b_h[k], rcond=None)[0] + dchi2_h[k] = float(b_h[k] @ theta_k) + dchi2 = ( + xp.asarray(dchi2_h, dtype=fdtype) + if dev is None + else xp.asarray(dchi2_h, dtype=fdtype, device=dev) + ) + power[sl] = dchi2 / chi2_0 + return xp.where(xp.isfinite(power), power, xp.zeros_like(power)) + + +def _flex_power_nufft( + prep: _MBPrep, f0: float, df: float, nf: int, backend: str, + settings: GLSSettings, engine: object | None = None, +) -> FloatArray: + """Flex-model power via NUFFT harmonic sums + batched normal-equation solve.""" + h_w, h_wy = _flex_orders(settings.mb_nterms_base, settings.mb_nterms_band) + band_sums = _flex_sums_nufft( + prep, f0, df, nf, backend, settings.nufft_eps, h_w, h_wy, engine + ) + if backend == "cufinufft": + import cupy as cp + + xp: Any = cp + fdtype: Any = cp.float64 + dev = None + power = _flex_power_from_sums( + xp, band_sums, prep.chi2_ref, prep.w_scale, nf, settings, fdtype, dev + ) + else: + with np.errstate(divide="ignore", invalid="ignore"): + power = _flex_power_from_sums( + np, band_sums, prep.chi2_ref, prep.w_scale, nf, settings, + np.float64, None, + ) + return to_host(power) + + +def _flex_power_torch( + prep: _MBPrep, f0: float, df: float, nf: int, *, + device: str, settings: GLSSettings, +) -> FloatArray: + """Flex-model power via direct per-band harmonic sums on any torch device.""" + import torch + + prec = resolve_precision(settings.precision, device) + tdtype = torch.float32 if prec == "float32" else torch.float64 + h_w, h_wy = _flex_orders(settings.mb_nterms_base, settings.mb_nterms_band) + tau_d = to_device_array(prep.tau, device=device, dtype=tdtype) + w_d = to_device_array(prep.w, device=device, dtype=tdtype) + wy_d = to_device_array(prep.w * prep.y, device=device, dtype=tdtype) + xp = array_namespace(tau_d) + band_sums: list[_BandSums] = [] + for sl, wk in zip(prep.slices, prep.band_weight, strict=True): + cw, sw, cy, sy = _flex_sums_direct( + xp, tau_d[sl], w_d[sl], wy_d[sl], f0, df, nf, h_w, h_wy, + settings.direct_freq_batch, + ) + y0 = float(np.dot(prep.w[sl], prep.y[sl])) + band_sums.append(_BandSums(cw=cw, sw=sw, cy=cy, sy=sy, w0=wk, y0=y0)) + power = _flex_power_from_sums( + xp, band_sums, prep.chi2_ref, prep.w_scale, nf, settings, + tdtype, device_ref(tau_d), + ) + return to_host(power) + + +# --- astropy reference path -------------------------------------------------- + + +def _astropy_power( + grid: GridSpec, mblc: MultiBandLightCurve, settings: GLSSettings +) -> tuple[FloatArray, int, float, tuple[str, ...]]: + """Reference multi-band power from ``astropy.timeseries.LombScargleMultiband``. + + The ``"offsets"`` model maps to the flexible solver with + ``(nterms_base, nterms_band) = (1, 0)`` and ``"perband"`` to ``(0, 1)`` — + the same model spaces, lifted from exact degeneracy by astropy's default + ridge — while ``"flex"`` passes the configured term counts and + regularization through. """ from astropy.timeseries import LombScargleMultiband @@ -56,31 +783,174 @@ def gls_multiband_power( baseline = float(time.max() - time.min()) if n else 0.0 if baseline <= 0.0: raise InsufficientDataError("GLS multiband: no usable time baseline") - + if settings.mb_model == "offsets": + nterms_base, nterms_band = 1, 0 + elif settings.mb_model == "perband": + nterms_base, nterms_band = 0, 1 + else: + nterms_base, nterms_band = settings.mb_nterms_base, settings.mb_nterms_band ls = LombScargleMultiband( time, value, band, error, - nterms_base=1, - nterms_band=1, + nterms_base=nterms_base, + nterms_band=nterms_band, + reg_base=settings.mb_reg_base, + reg_band=settings.mb_reg_band, + regularize_by_trace=settings.mb_regularize_by_trace, ) - frequency = grid.frequency power = np.nan_to_num( - np.asarray(ls.power(frequency), dtype=np.float64), + np.asarray(ls.power(grid.frequency, method="flexible"), dtype=np.float64), nan=0.0, posinf=0.0, neginf=0.0, ) + return power, n, baseline, finite.band_names + + +# --- entry point ------------------------------------------------------------- + + +def gls_multiband_power( + grid: GridSpec, + mblc: MultiBandLightCurve, + settings: GLSSettings, + backend: str, + engine: object | None = None, +) -> Periodogram: + """Compute the multi-band GLS power on ``grid``. + + Parameters + ---------- + grid : GridSpec + Frequency grid (built from the stacked baseline). + mblc : MultiBandLightCurve + Two or more bands of one star. + settings : GLSSettings + GLS settings; ``mb_model`` selects the multi-band model and the + ``mb_*`` fields configure the flexible variant. + backend : str + Resolved backend: ``"finufft"``, ``"cufinufft"``, ``"torch"`` / + ``"torch:"``, or ``"astropy"``. + engine : object, optional + A :class:`~cuperiod.methods.gls.CufinufftGLS` batch engine; on the + cufinufft backend its plan cache is reused across bands, harmonics, and + light curves. Ignored on every other backend. The bootstrap-FAP pass + deliberately does not use it: the resample chunks batch through + transforms whose ``n_trans`` varies with the grid size, and caching a + plan per ``n_trans`` value would balloon device memory in a batch run. + + Returns + ------- + Periodogram + The joint power spectrum. ``meta["bands"]`` lists the contributing bands + and ``meta["mb_model"]`` records the model. + + Raises + ------ + InsufficientDataError + If too few finite points remain across all bands, or the grid is empty. + """ + if grid.size == 0: + raise InsufficientDataError("GLS multiband: empty trial grid") + + finite_meta = dict(mblc.finite().meta) + if backend == "astropy" or not grid.uniform: + power, n, baseline, band_names = _astropy_power(grid, mblc, settings) + actual_backend = "astropy" + frequency = grid.frequency + else: + f0, df, nf = grid.uniform_frequency_params() + frequency = f0 + df * np.arange(nf, dtype=np.float64) + is_torch = backend == "torch" or backend.startswith("torch:") + if settings.mb_model == "perband": + if is_torch: + device = resolve_torch_device(backend, settings.device) + actual_backend = f"torch:{device}" + backend = actual_backend + else: + actual_backend = backend + power, n, baseline, band_names = _perband_power( + mblc, f0, df, nf, backend, settings, engine + ) + else: + prep = _prep_multiband(mblc, settings) + n, baseline, band_names = prep.n, prep.baseline, prep.band_names + if settings.mb_model == "offsets": + if is_torch: + device = resolve_torch_device(backend, settings.device) + actual_backend = f"torch:{device}" + power = _offsets_power_torch( + prep, f0, df, nf, + device=device, + precision=settings.precision, + freq_batch=settings.direct_freq_batch, + ) + else: + actual_backend = backend + power = _offsets_power_nufft( + prep, f0, df, nf, backend, settings.nufft_eps, engine + ) + else: # flex + if is_torch: + device = resolve_torch_device(backend, settings.device) + actual_backend = f"torch:{device}" + power = _flex_power_torch( + prep, f0, df, nf, device=device, settings=settings + ) + else: + actual_backend = backend + power = _flex_power_nufft( + prep, f0, df, nf, backend, settings, engine + ) + power = np.nan_to_num( + np.asarray(power, dtype=np.float64), nan=0.0, posinf=0.0, neginf=0.0 + ) + extras: dict[str, FloatArray] = {} + meta: dict[str, Any] = { + **finite_meta, "bands": band_names, "mb_model": settings.mb_model, + } + if ( + settings.mb_fap_bootstrap > 0 + and actual_backend != "astropy" + and grid.uniform + ): + from cuperiod.core.peaks import local_maxima + from cuperiod.multiband.fap_mb import MultibandFAP, bootstrap_null_max + + null_max = bootstrap_null_max( + mblc, grid, settings, backend, + settings.mb_fap_bootstrap, settings.mb_fap_seed, + ) + calibration = MultibandFAP( + null_max=null_max, + n_bootstrap=settings.mb_fap_bootstrap, + seed=settings.mb_fap_seed, + model=settings.mb_model, + backend=actual_backend, + ) + fap = np.full(power.shape, np.nan, dtype=np.float64) + candidates = local_maxima(power) + if candidates.size: + fap[candidates] = calibration.fap(power[candidates]) + extras["fap"] = fap + meta["fap_method"] = "bootstrap" + meta["fap_n_bootstrap"] = settings.mb_fap_bootstrap + meta["fap_seed"] = settings.mb_fap_seed + meta["fap_level_10pct"] = float(np.quantile(null_max, 0.90)) + if settings.mb_fap_bootstrap >= 99: + meta["fap_level_1pct"] = float(np.quantile(null_max, 0.99)) return Periodogram.from_spectrum( method="GLS", - backend="astropy", + backend=actual_backend, frequency=frequency, power=power, objective_sense="max", n_samples=n, baseline=baseline, - meta={**dict(finite.meta), "bands": finite.band_names}, + extras=extras, + meta=meta, ) diff --git a/src/cuperiod/multiband/pdm_mb.py b/src/cuperiod/multiband/pdm_mb.py new file mode 100644 index 0000000..749190b --- /dev/null +++ b/src/cuperiod/multiband/pdm_mb.py @@ -0,0 +1,118 @@ +"""Multi-band Phase Dispersion Minimization. + +Every filter of the same star shares one period but keeps its *own* mean light curve: +the mean magnitude, the amplitude and even the folded shape are filter-dependent, so +nothing is gained by forcing the bands onto a common curve. Each band is therefore +phase-folded and binned on its own (Stellingwerf 1978) and only the resulting +*dispersions* are pooled, + + Theta_mb(f) = sum_k w_k Theta_k(f) / sum_k w_k, w_k = max(n_k - n_bins, 1), + +with ``Theta_k`` the single-band Stellingwerf ratio of band ``k`` and ``n_k`` its finite +point count. A band too sparse or too noisy to pin the period down alone still pulls its +weight, and — as in the single-band case — the statistic collapses at the true period, +so this is a *minimization* method. + +The weights are the bands' within-bin degrees of freedom under Stellingwerf's +fixed-dof convention (``n_k`` points spread over ``n_bins`` bins leave +``n_k - n_bins`` of them, floored at one for a band with barely more points than +bins; the realized denominator differs only where a fold leaves bins empty). With +those weights the pooled statistic is *exactly* the pooled within-bin sum of squares +over the pooled degrees of freedom of the per-band **standardized** data: +``Theta_k = s_k^2 / sigma_k^2`` already divides band ``k``'s scatter by that band's +own variance, so standardizing each band before pooling is implicit and needs no +separate step. That matters because filters differ in amplitude and photometric +precision; pooling raw sums of squares would let the noisiest band decide the period +on its own. +""" + +from __future__ import annotations + +import numpy as np + +from cuperiod.core.config import PDMSettings +from cuperiod.core.errors import InsufficientDataError +from cuperiod.core.grid import GridSpec +from cuperiod.core.lightcurve import MultiBandLightCurve +from cuperiod.core.result import Periodogram +from cuperiod.methods.pdm import pdm_theta + + +def pdm_multiband_theta( + grid: GridSpec, + mblc: MultiBandLightCurve, + settings: PDMSettings, + backend: str, +) -> Periodogram: + """Compute the pooled multi-band PDM statistic on ``grid``. + + Parameters + ---------- + grid : GridSpec + Shared trial grid (built from the stacked baseline); used as periods. + mblc : MultiBandLightCurve + Two or more bands of one star. + settings : PDMSettings + PDM settings (bin count, covers, batching, ...); a band participates when it + has at least ``n_bins + 2`` finite points. + backend : str + Concrete backend (``"numpy"``, ``"numba"``, ``"cupy"``, ``"torch:"``). + + Returns + ------- + Periodogram + Degrees-of-freedom-weighted mean of the per-band ``Theta`` (minimized at the + true period). + + Raises + ------ + InsufficientDataError + If no band has ``n_bins + 2`` finite points, or the stacked baseline is empty. + """ + finite = mblc.finite() + min_points = settings.n_bins + 2 + bands = [lc for lc in finite.bands.values() if lc.n >= min_points] + if not bands: + raise InsufficientDataError( + f"PDM multiband: no band has {min_points} finite points " + f"(n_bins {settings.n_bins} + 2)" + ) + stacked_time, _, _, _ = finite.stacked() + baseline = float(stacked_time.max() - stacked_time.min()) + if baseline <= 0.0: + raise InsufficientDataError("PDM multiband: no usable time baseline") + + periods = grid.period + pooled = np.zeros(periods.size, dtype=np.float64) + weight_total = 0.0 + n_total = 0 + for lc in bands: + theta = pdm_theta( + lc.time, + lc.value, + periods, + n_bins=settings.n_bins, + n_covers=settings.n_covers, + backend=backend, + batch=settings.batch_periods, + precision=settings.precision, + ) + weight = float(max(lc.n - settings.n_bins, 1)) + pooled += weight * theta + weight_total += weight + n_total += lc.n + power = pooled / weight_total + + return Periodogram.from_spectrum( + method="PDM", + backend=backend, + frequency=1.0 / periods, + power=power, + objective_sense="min", + n_samples=n_total, + baseline=baseline, + meta={**dict(finite.meta), "bands": finite.band_names}, + ) + + +__all__ = ["pdm_multiband_theta"] diff --git a/src/cuperiod/multiband/string_length_mb.py b/src/cuperiod/multiband/string_length_mb.py new file mode 100644 index 0000000..cd818a5 --- /dev/null +++ b/src/cuperiod/multiband/string_length_mb.py @@ -0,0 +1,109 @@ +"""Multi-band string-length period search. + +The string length measures how tightly a *folded* light curve joins up (Lafler & Kinman +1965; Dworetsky 1983), and a fold is only smooth within one filter: bands differ in mean +magnitude and amplitude, so stringing all bands together would spend most of the string +hopping between filters rather than tracing the variability. Each band is therefore +folded and strung on its own — the single-band kernel rescales each band's magnitudes to +Dworetsky's span of 0.5, so the phase and magnitude axes contribute comparably in every +filter regardless of its amplitude — and the lengths are pooled by point count, + + L_mb(f) = sum_k n_k L_k(f) / sum_k n_k, + +with ``L_k`` the string length of band ``k`` and ``n_k`` its finite point count. The +weighting reflects that a string over ``n_k`` points is a sum of ``n_k`` steps: pooling +by ``n_k`` compares bands on a per-step footing, so a densely sampled band is not +diluted by a sparse one. A shared period shortens every band's string at once, so this +is a *minimization* method. + +Like the single-band statistic, the pooled length also dips at integer multiples of the +true period (overlaid copies pack the fold tightly), so bounding the search below the +first subharmonic keeps the fundamental the global minimum. +""" + +from __future__ import annotations + +import numpy as np + +from cuperiod.core.config import StringLengthSettings +from cuperiod.core.errors import InsufficientDataError +from cuperiod.core.grid import GridSpec +from cuperiod.core.lightcurve import MultiBandLightCurve +from cuperiod.core.result import Periodogram +from cuperiod.methods.string_length import string_length + +#: A band needs at least this many finite points to make a meaningful string. +_MIN_BAND_POINTS = 8 + + +def string_length_multiband( + grid: GridSpec, + mblc: MultiBandLightCurve, + settings: StringLengthSettings, + backend: str, +) -> Periodogram: + """Compute the pooled multi-band string length on ``grid``. + + Parameters + ---------- + grid : GridSpec + Shared trial grid (built from the stacked baseline); used as periods. + mblc : MultiBandLightCurve + Two or more bands of one star. + settings : StringLengthSettings + String-length settings (batching, precision, ...); a band participates when it + has at least 8 finite points. + backend : str + Concrete backend (``"numpy"``, ``"numba"``, ``"cupy"``, ``"torch:"``). + + Returns + ------- + Periodogram + Point-count-weighted mean of the per-band string lengths (minimized at the true + period). + + Raises + ------ + InsufficientDataError + If no band has enough finite points, or the stacked baseline is empty. + """ + finite = mblc.finite() + bands = [lc for lc in finite.bands.values() if lc.n >= _MIN_BAND_POINTS] + if not bands: + raise InsufficientDataError( + f"string-length multiband: no band has {_MIN_BAND_POINTS} finite points" + ) + stacked_time, _, _, _ = finite.stacked() + baseline = float(stacked_time.max() - stacked_time.min()) + if baseline <= 0.0: + raise InsufficientDataError("string-length multiband: no usable time baseline") + + periods = grid.period + pooled = np.zeros(periods.size, dtype=np.float64) + n_total = 0 + for lc in bands: + length = string_length( + lc.time, + lc.value, + periods, + backend=backend, + batch=settings.batch_periods, + precision=settings.precision, + ) + pooled += float(lc.n) * length + n_total += lc.n + power = pooled / float(n_total) + + return Periodogram.from_spectrum( + method="STRINGLENGTH", + backend=backend, + frequency=1.0 / periods, + power=power, + objective_sense="min", + n_samples=n_total, + baseline=baseline, + meta={**dict(finite.meta), "bands": finite.band_names}, + ) + + +__all__ = ["string_length_multiband"] diff --git a/src/cuperiod/multiband/supersmoother_mb.py b/src/cuperiod/multiband/supersmoother_mb.py new file mode 100644 index 0000000..2a2fa6f --- /dev/null +++ b/src/cuperiod/multiband/supersmoother_mb.py @@ -0,0 +1,121 @@ +"""Multi-band SuperSmoother. + +Every filter of the same star shares one trial period but keeps its own folded +shape — SuperSmoother is fully non-parametric, so there is no shared-phase model to +pool into. Following gatspy's ``SuperSmootherMultiband``, each band is smoothed +independently on the shared grid and the per-band scores are combined with +baseline-error weights, + + score_mb(f) = sum_k B_k score_k(f) / sum_k B_k, + B_k = mean_i |y_i - mu_k| / dy_i over band k, + +with ``mu_k`` band ``k``'s inverse-variance weighted mean. ``B_k`` is band ``k``'s +mean absolute standardized deviation about its own mean — the denominator of that +band's score — so the combined statistic is exactly the *total* fractional reduction +in mean absolute deviation across all bands: a noisy or flat band contributes little +weight, and with one band the combination collapses to the single-band score. +""" + +from __future__ import annotations + +import numpy as np + +from cuperiod.core.config import SuperSmootherSettings +from cuperiod.core.errors import InsufficientDataError +from cuperiod.core.grid import GridSpec +from cuperiod.core.lightcurve import MultiBandLightCurve +from cuperiod.core.result import Periodogram +from cuperiod.methods.supersmoother import supersmoother_score + +#: A band needs this many finite points for its smallest (3-point) span windows. +_MIN_BAND_POINTS = 3 + + +def supersmoother_multiband( + grid: GridSpec, + mblc: MultiBandLightCurve, + settings: SuperSmootherSettings, + backend: str, +) -> Periodogram: + """Compute the baseline-weighted multi-band SuperSmoother score on ``grid``. + + Parameters + ---------- + grid : GridSpec + Shared trial grid (built from the stacked baseline); used as periods. + mblc : MultiBandLightCurve + Two or more bands of one star. + settings : SuperSmootherSettings + SuperSmoother settings (spans, bass enhancement, batching, ...); a band + participates when it has at least 3 finite points. + backend : str + Concrete backend (``"numpy"``, ``"numba"``, ``"cupy"``, ``"torch:"``). + + Returns + ------- + Periodogram + Baseline-error-weighted mean of the per-band scores (maximized at the + true period). + + Raises + ------ + InsufficientDataError + If too few finite points remain across usable bands, or the stacked + baseline is empty. + """ + finite = mblc.finite() + bands = [lc for lc in finite.bands.values() if lc.n >= _MIN_BAND_POINTS] + n_total = sum(lc.n for lc in bands) + if not bands or n_total < settings.min_detections: + raise InsufficientDataError( + f"SUPERSMOOTHER multiband: {n_total} finite points across usable " + f"bands < min_detections {settings.min_detections}" + ) + stacked_time, _, _, _ = finite.stacked() + baseline = float(stacked_time.max() - stacked_time.min()) + if baseline <= 0.0: + raise InsufficientDataError("SUPERSMOOTHER multiband: no usable time baseline") + + periods = grid.period + combined = np.zeros(periods.size, dtype=np.float64) + weight_total = 0.0 + for lc in bands: + if lc.error is None: + inv_dy = np.ones(lc.n, dtype=np.float64) + else: + inv_dy = 1.0 / np.asarray(lc.error, dtype=np.float64) + w = inv_dy * inv_dy + mu = float(np.dot(w, lc.value) / w.sum()) + b_k = float(np.mean(np.abs(lc.value - mu) * inv_dy)) + if not np.isfinite(b_k) or b_k <= 0.0: + continue # a constant band carries no deviation to reduce + score = supersmoother_score( + lc.time, + lc.value, + lc.error, + periods, + primary_spans=settings.primary_spans, + middle_span=settings.middle_span, + final_span=settings.final_span, + bass_enhancement=settings.bass_enhancement, + backend=backend, + batch=settings.batch_periods, + precision=settings.precision, + ) + combined += b_k * score + weight_total += b_k + power = combined / weight_total if weight_total > 0.0 else combined + + return Periodogram.from_spectrum( + method="SUPERSMOOTHER", + backend=backend, + frequency=1.0 / periods, + power=power, + objective_sense="max", + n_samples=n_total, + baseline=baseline, + meta={**dict(finite.meta), "bands": finite.band_names}, + ) + + +__all__ = ["supersmoother_multiband"] diff --git a/src/cuperiod/prewhiten/__init__.py b/src/cuperiod/prewhiten/__init__.py new file mode 100644 index 0000000..0f8dd04 --- /dev/null +++ b/src/cuperiod/prewhiten/__init__.py @@ -0,0 +1,105 @@ +"""Automated, uncertainty-aware pre-whitening for classical pulsators. + +Frequency analysis of δ Scuti, γ Doradus and SPB stars is traditionally an interactive +Period04 session: find the tallest peak, fit it, subtract it, look again, and decide by +eye when to stop. That does not survive contact with a TESS full-frame-image catalogue, +let alone PLATO. This subpackage automates the loop end to end and makes every judgement +call an explicit, recorded setting. + +.. code-block:: python + + import cuperiod as cup + + solution = cup.prewhiten((time, mag, mag_err)) + print(solution.summary()) + + series = cup.find_period_spacing(solution.period, solution.amplitude) + print(series.summary()) + +What it provides +---------------- +* A batch-capable GPU/NUFFT **amplitude spectrum** (:mod:`~cuperiod.prewhiten.spectrum`) + whose sampling-only terms are cached, so each pre-whitening iteration costs a single + transform. +* **Iterative extraction** (:mod:`~cuperiod.prewhiten.engine`): after each step every + amplitude, phase and the offset are re-solved jointly and the newest frequency is + refined non-linearly; all frequencies are swept together in the final polish. +* **Principled stopping criteria** — Breger signal-to-noise, false-alarm probability, + ΔBIC, an amplitude floor — combined and always reported. +* **Error propagation** (:mod:`~cuperiod.prewhiten.uncertainty`): least-squares + covariance including the correlations between close frequencies, the classical + Montgomery & O'Donoghue formulae, or a residual bootstrap; optionally inflated by the + Schwarzenberg-Czerny correlation factor. +* **Combination-frequency identification** + (:mod:`~cuperiod.prewhiten.combinations`) with uncertainty-aware tolerances and + chance-coincidence rates. +* **g-mode period-spacing tools** (:mod:`~cuperiod.prewhiten.spacing`): comb search, + tilted-pattern extraction, échelle coordinates, buoyancy radius. +* **Batch pre-whitening** (:mod:`~cuperiod.prewhiten.batch`) over CPU or GPU worker + pools, written to Parquet/CSV. +""" + +from __future__ import annotations + +from cuperiod.prewhiten.batch import batch_prewhiten +from cuperiod.prewhiten.combinations import Combination, identify_combinations +from cuperiod.prewhiten.engine import ( + default_maximum_frequency, + default_prewhiten_grid, + prewhiten, +) +from cuperiod.prewhiten.fap import baluev_fap +from cuperiod.prewhiten.fit import MultiSineFit, fit_multisine +from cuperiod.prewhiten.result import PreWhitenResult, Sinusoid +from cuperiod.prewhiten.spacing import ( + PeriodSpacingSeries, + SpacingSpectrum, + buoyancy_radius, + echelle, + find_period_spacing, + spacing_spectrum, +) +from cuperiod.prewhiten.spectrum import ( + AmplitudeSpectrum, + SpectrumEngine, + amplitude_spectrum, + noise_level, + spectral_window, +) +from cuperiod.prewhiten.uncertainty import ( + Uncertainties, + analytic_uncertainties, + bootstrap_uncertainties, + component_uncertainties, + correlation_factor, +) + +__all__ = [ + "AmplitudeSpectrum", + "Combination", + "MultiSineFit", + "PeriodSpacingSeries", + "PreWhitenResult", + "Sinusoid", + "SpacingSpectrum", + "SpectrumEngine", + "Uncertainties", + "amplitude_spectrum", + "analytic_uncertainties", + "baluev_fap", + "batch_prewhiten", + "bootstrap_uncertainties", + "buoyancy_radius", + "component_uncertainties", + "correlation_factor", + "default_maximum_frequency", + "default_prewhiten_grid", + "echelle", + "find_period_spacing", + "fit_multisine", + "identify_combinations", + "noise_level", + "prewhiten", + "spacing_spectrum", + "spectral_window", +] diff --git a/src/cuperiod/prewhiten/batch.py b/src/cuperiod/prewhiten/batch.py new file mode 100644 index 0000000..241fa29 --- /dev/null +++ b/src/cuperiod/prewhiten/batch.py @@ -0,0 +1,274 @@ +"""Batch pre-whitening: :func:`batch_prewhiten`. + +Runs the whole extraction loop over many light curves with the same worker machinery as +:func:`cuperiod.batch_periodograms` — a spawned CPU process pool, or GPU workers — and +flattens the result to **one row per extracted component**, which is the shape a +frequency catalogue wants: filter on ``snr``, group by ``key``, join on ``label``. A +light curve that yields no component still contributes one row, so nothing silently +disappears from the catalogue. + +Directory sinks are resumable exactly as in the periodogram batch: a re-run skips chunks +whose part file already exists. +""" + +from __future__ import annotations + +from collections.abc import Sequence +from dataclasses import dataclass +from pathlib import Path +from typing import Any + +from cuperiod.batch.io import InputItem, load_source, resolve_inputs, write_rows +from cuperiod.batch.runner import ( + BatchSummary, + _chunked, + _classify_sink, + _dir_manifest_guard, + _finalize_file, + _part_path, + _pending_chunks, + _run_pool, +) +from cuperiod.batch.sizing import cpu_worker_count, pin_worker_threads +from cuperiod.core.columns import ColumnMap, Domain +from cuperiod.core.config import PreWhitenSettings +from cuperiod.core.device import free_gpu_memory, suggest_gpu_workers +from cuperiod.core.lightcurve import MultiBandLightCurve +from cuperiod.prewhiten.engine import prewhiten +from cuperiod.prewhiten.result import PreWhitenResult, Sinusoid + + +@dataclass(frozen=True) +class _ChunkConfig: + """Immutable, picklable settings shared by every chunk task.""" + + settings: PreWhitenSettings + backend: str + columns: ColumnMap | None + domain: Domain | None + max_components: int | None + + +def prewhiten_to_rows( + key: str, result: PreWhitenResult, *, max_components: int | None = None +) -> list[dict[str, Any]]: + """Flatten a solution to catalogue rows — one per component (or one empty row). + + Every row repeats the per-star summary (sample count, baseline, stop reason, fit + statistics) so a single table is self-describing without a join. + + Parameters + ---------- + key : str + The light curve's batch key. + result : PreWhitenResult + The solution to flatten. + max_components : int, optional + Keep only the first ``max_components`` components. + + Returns + ------- + list of dict + """ + summary = { + "key": key, + "n_components": result.n_components, + "n_pruned": result.n_pruned, + "n_samples": result.n_samples, + "baseline": result.baseline, + "rayleigh": result.rayleigh, + "t_ref": result.t_ref, + "offset": result.offset, + "stop_reason": result.stop_reason, + "rms": result.rms, + "reduced_chi2": result.reduced_chi2, + "bic": result.bic, + "correlation_factor": result.correlation_factor, + "backend": result.backend, + } + components = result.components + if max_components is not None: + components = components[:max_components] + if not components: + return [{**summary, **dict(_EMPTY_COMPONENT)}] + return [{**summary, **_component_cells(component)} for component in components] + + +#: Numeric component fields, in row order. Kept float (``rank`` included) and NaN-filled +#: rather than ``None`` so every chunk of a directory sink infers the *same* Arrow type: +#: a part in which no star had a combination would otherwise type that column null, +#: making the whole dataset unreadable. +#: ``blended`` is deliberately absent: a boolean has no missing value to fill for a +#: light curve that yielded nothing, and ``amplitude_ratio`` carries the same +#: information with a threshold the catalogue's consumer picks. +_NUMERIC_FIELDS: tuple[str, ...] = ( + "rank", "frequency", "frequency_error", "period", "period_error", + "amplitude", "amplitude_error", "spectrum_amplitude", "amplitude_ratio", + "phase", "phase_error", "snr", "fap", "delta_bic", +) + +#: String component fields, empty-string-filled for the same reason. +_TEXT_FIELDS: tuple[str, ...] = ("label", "combination") + +#: The all-missing component block used for a light curve that yielded nothing. +_EMPTY_COMPONENT: dict[str, Any] = { + **dict.fromkeys(_NUMERIC_FIELDS, float("nan")), + **dict.fromkeys(_TEXT_FIELDS, ""), +} + + +def _component_cells(component: Sinusoid) -> dict[str, Any]: + """One component as stably-typed row cells (see :data:`_NUMERIC_FIELDS`).""" + values = component.to_dict() + cells: dict[str, Any] = { + name: float(values[name]) for name in _NUMERIC_FIELDS + } + cells.update({name: values[name] or "" for name in _TEXT_FIELDS}) + return cells + + +def _process_chunk( + items: Sequence[InputItem], cfg: _ChunkConfig +) -> tuple[list[dict[str, Any]], list[tuple[str, str]]]: + """Pre-whiten every light curve in a chunk; collect rows and errors.""" + rows: list[dict[str, Any]] = [] + errors: list[tuple[str, str]] = [] + for key, source in items: + try: + lc = load_source(source, columns=cfg.columns, domain=cfg.domain) + if isinstance(lc, MultiBandLightCurve): + raise ValueError("pre-whitening needs single-band light curves") + result = prewhiten(lc, settings=cfg.settings, backend=cfg.backend) + rows.extend( + prewhiten_to_rows(key, result, max_components=cfg.max_components) + ) + except Exception as exc: # one bad light curve must not kill the batch + errors.append((key, f"{type(exc).__name__}: {exc}")) + return rows, errors + + +def batch_prewhiten( + inputs: Any, + *, + settings: PreWhitenSettings | None = None, + backend: str = "auto", + device: str = "cpu", + workers: int | None = None, + columns: ColumnMap | None = None, + domain: Domain | None = None, + sink: str | Path | None = None, + max_components: int | None = None, + resume: bool = True, + chunk_size: int = 64, +) -> BatchSummary: + """Pre-whiten many light curves. + + Parameters + ---------- + inputs : various + Anything :func:`cuperiod.batch_periodograms` accepts: an iterable of light + curves or ``(key, lc)`` pairs, a glob string, a directory, or a + ``(DataFrame, group_column)`` tuple. + settings : PreWhitenSettings, optional + Extraction settings applied to every light curve. ``store_spectra`` is forced + off — catalogue rows never carry spectra, so keeping them would only waste + worker memory. + backend : str, default "auto" + Amplitude-spectrum backend. + device : {"cpu", "gpu"}, default "cpu" + Where to run the workers. + workers : int, optional + Worker count; ``None`` picks all-but-one core (CPU) or a GPU-sized default. + columns, domain : optional + Column mapping and brightness-domain handling for file and table inputs. + sink : str or Path, optional + ``.parquet``/``.csv`` file, or a directory (resumable, one part per chunk). + ``None`` returns the rows in memory. + max_components : int, optional + Store only this many components per light curve. + resume : bool, default True + Skip chunks already written (directory sink). + chunk_size : int, default 64 + Light curves per chunk/task. + + Returns + ------- + BatchSummary + ``methods`` is reported as ``("PREWHITEN",)``. + + Examples + -------- + >>> cup.batch_prewhiten("lightcurves/*.csv", sink="modes.parquet") # doctest: +SKIP + """ + if device not in {"cpu", "gpu"}: + raise ValueError("device must be 'cpu' or 'gpu'") + # Catalogue rows never carry spectra, so keeping them would only make each worker + # hold (and ship nothing from) megabytes of grid arrays per star: force them off. + cfg = _ChunkConfig( + settings=(settings or PreWhitenSettings()).model_copy( + update={"store_spectra": False} + ), + backend="gpu" if device == "gpu" else backend, + columns=columns, + domain=domain, + max_components=max_components, + ) + + sink_kind, sink_dir, sink_file = _classify_sink(sink) + items = resolve_inputs(inputs, columns=columns, domain=domain) + chunks = _chunked(items, max(1, chunk_size)) + if sink_kind == "dir": + _dir_manifest_guard(sink_dir, max(1, chunk_size), resume) + pending = _pending_chunks(chunks, sink_kind, sink_dir, resume) + n_skipped = len(items) - sum(len(chunks[i]) for i in pending) + + all_rows: list[dict[str, Any]] = [] + errors: list[tuple[str, str]] = [] + n_done = 0 + + def absorb( + idx: int, rows: list[dict[str, Any]], errs: list[tuple[str, str]] + ) -> None: + nonlocal n_done + n_done += len(rows) + errors.extend(errs) + if sink_kind == "dir": + if rows: + write_rows(rows, _part_path(sink_dir, idx)) + else: + all_rows.extend(rows) + + if device == "gpu": + n_workers = workers if workers is not None else suggest_gpu_workers("GLS") + if n_workers <= 1: + for idx in pending: + absorb(idx, *_process_chunk(chunks[idx], cfg)) + free_gpu_memory() + else: + _run_pool(chunks, pending, cfg, absorb, n_workers, worker=_process_chunk) + else: + n_workers = cpu_worker_count(workers) + if n_workers <= 1: + for idx in pending: + absorb(idx, *_process_chunk(chunks[idx], cfg)) + else: + pin_worker_threads() + _run_pool(chunks, pending, cfg, absorb, n_workers, worker=_process_chunk) + + if sink_kind == "file": + _finalize_file(all_rows, sink_file, resume) + + return BatchSummary( + n_inputs=len(items), + n_done=n_done, + n_failed=len(errors), + n_skipped=n_skipped, + methods=("PREWHITEN",), + device=device, + sink=str(sink) if sink is not None else None, + errors=errors, + rows=None if sink_kind != "memory" else all_rows, + ) + + +__all__ = ["batch_prewhiten", "prewhiten_to_rows"] diff --git a/src/cuperiod/prewhiten/combinations.py b/src/cuperiod/prewhiten/combinations.py new file mode 100644 index 0000000..d9feea8 --- /dev/null +++ b/src/cuperiod/prewhiten/combinations.py @@ -0,0 +1,252 @@ +"""Combination-frequency identification. + +A non-linear pulsator's Fourier spectrum is not a list of independent modes: a large +fraction of the peaks are *combinations* :math:`f = \\sum_i n_i f_i` of a few +high-amplitude parents — harmonics ``2f_1``, sums ``f_1 + f_2``, differences +``f_1 - f_2``. Reporting those as independent modes is one of the classic ways to +over-count the mode density of a δ Scuti star, so this module flags them. + +Two things make the search trustworthy rather than merely suggestive: + +**The tolerance is uncertainty-aware.** A match must fall inside +``max(sigma_tolerance, rayleigh_tolerance)`` where the first is +``n_sigma * sqrt(sigma_child^2 + sum_i n_i^2 sigma_i^2)`` — the propagated uncertainty +of the predicted combination — and the second is a fraction of the Rayleigh resolution, +which floors the test when the formal errors are unrealistically small. + +**Chance coincidences are counted.** With enough parents and a generous order, *some* +frequency will land within tolerance of *some* combination by luck. Every match carries +the expected number of chance matches for the set of coefficient vectors that was +searched, so a user can see immediately whether an identification means anything. +""" + +from __future__ import annotations + +from collections.abc import Iterator +from dataclasses import dataclass +from typing import Any + +import numpy as np + +from cuperiod.core._typing import FloatArray + + +@dataclass(frozen=True) +class Combination: + """One frequency identified as a combination of higher-amplitude parents. + + Attributes + ---------- + index : int + Index of the child component within the solution. + parents : tuple of int + Indices of the parent components used. + coefficients : tuple of int + Integer multipliers aligned with ``parents`` (never all zero). + order : int + ``sum(abs(coefficients))`` — 2 for ``2f_1`` or ``f_1 + f_2``, 3 for + ``2f_1 - f_2``, and so on. + label : str + Human-readable identification, e.g. ``"F5 = 2F1 - F2"``. + predicted : float + The combination frequency implied by the parents (cycles/day). + residual : float + ``observed - predicted`` (cycles/day). + tolerance : float + The matching tolerance that was applied (cycles/day). + expected_false : float + Expected number of chance matches for this child given the coefficient vectors + searched and the tolerance. Values approaching (or above) 1 mean the + identification carries little information. + """ + + index: int + parents: tuple[int, ...] + coefficients: tuple[int, ...] + order: int + label: str + predicted: float + residual: float + tolerance: float + expected_false: float + + def to_dict(self) -> dict[str, Any]: + """Flatten to a plain dict.""" + return { + "index": self.index, + "label": self.label, + "parents": list(self.parents), + "coefficients": list(self.coefficients), + "order": self.order, + "predicted": self.predicted, + "residual": self.residual, + "tolerance": self.tolerance, + "expected_false": self.expected_false, + } + + +def _coefficient_vectors(n_parents: int, max_order: int) -> Iterator[tuple[int, ...]]: + """All integer vectors with ``0 < sum|n_i| <= max_order``. + + Enumerated depth-first against the remaining order budget, so the count stays modest + (60 vectors for five parents at order 2) instead of the ``(2m+1)^P`` a naive + product would produce. + """ + + def walk( + position: int, budget: int, prefix: tuple[int, ...] + ) -> Iterator[tuple[int, ...]]: + if position == n_parents: + if budget < max_order: # at least one non-zero coefficient + yield prefix + return + for value in range(-budget, budget + 1): + yield from walk(position + 1, budget - abs(value), (*prefix, value)) + + yield from walk(0, max_order, ()) + + +def _format_label( + child_label: str, parent_labels: tuple[str, ...], coefficients: tuple[int, ...] +) -> str: + """Render ``F5 = 2F1 - F2`` from labels and integer coefficients. + + Positive terms are written first so a difference reads ``F2 - F1`` rather than + ``-F1 + F2``. + """ + used = [ + (label, coefficient) + for label, coefficient in zip(parent_labels, coefficients, strict=True) + if coefficient != 0 + ] + used.sort(key=lambda item: item[1] < 0) + terms: list[str] = [] + for label, coefficient in used: + magnitude = abs(coefficient) + body = f"{magnitude if magnitude != 1 else ''}{label}" + if not terms: + terms.append(f"-{body}" if coefficient < 0 else body) + else: + terms.append(f"{'-' if coefficient < 0 else '+'} {body}") + return f"{child_label} = {' '.join(terms)}" + + +def identify_combinations( + frequency: FloatArray, + amplitude: FloatArray, + *, + frequency_error: FloatArray | None = None, + labels: tuple[str, ...] | None = None, + rayleigh: float = 0.0, + max_order: int = 2, + max_parents: int = 5, + tolerance_rayleigh: float = 0.25, + n_sigma: float = 3.0, +) -> tuple[Combination, ...]: + """Flag components that are integer combinations of higher-amplitude parents. + + Parents are the highest-amplitude components: a peak is only ever explained by + frequencies *stronger* than itself, which is the physical ordering for non-linear + combinations and also stops the search from explaining a mode by its own harmonics. + Among all admissible matches the lowest order wins, and ties are broken by the + smallest frequency residual. + + Parameters + ---------- + frequency, amplitude : numpy.ndarray + The extracted components (any order; parents are chosen by amplitude). + frequency_error : numpy.ndarray, optional + 1-sigma frequency uncertainties, used for the propagated tolerance. + labels : tuple of str, optional + Display labels, defaulting to ``F1``, ``F2``, ... + rayleigh : float, default 0.0 + Rayleigh resolution ``1/T`` (cycles/day); floors the tolerance. + max_order : int, default 2 + Largest ``sum|n_i|`` considered. + max_parents : int, default 5 + Number of highest-amplitude components usable as parents. + tolerance_rayleigh : float, default 0.25 + Tolerance floor as a fraction of the Rayleigh resolution. + n_sigma : float, default 3.0 + Tolerance in units of the propagated frequency uncertainty. + + Returns + ------- + tuple of Combination + One entry per identified child, in ascending child index. + + Examples + -------- + >>> identify_combinations(np.array([5.0, 7.0, 12.0]), # doctest: +SKIP + ... np.array([1.0, 0.5, 0.1]), + ... rayleigh=0.01) + (Combination(index=2, label='F3 = F1 + F2', ...),) + """ + freq = np.asarray(frequency, dtype=np.float64).ravel() + amp = np.asarray(amplitude, dtype=np.float64).ravel() + k = int(freq.size) + if k < 2 or max_order < 1 or max_parents < 1: + return () + sigma = ( + np.zeros(k, dtype=np.float64) + if frequency_error is None + else np.nan_to_num( + np.asarray(frequency_error, dtype=np.float64).ravel(), nan=0.0 + ) + ) + names = labels or tuple(f"F{i + 1}" for i in range(k)) + span = float(freq.max() - freq.min()) if k > 1 else 0.0 + floor = tolerance_rayleigh * rayleigh + + by_amplitude = np.argsort(amp, kind="stable")[::-1] + found: list[Combination] = [] + for position, child in enumerate(by_amplitude): + if position == 0: + continue + parents = tuple(int(i) for i in by_amplitude[: min(position, max_parents)]) + if not parents: + continue + parent_freq = freq[list(parents)] + parent_sigma = sigma[list(parents)] + parent_names = tuple(names[i] for i in parents) + vectors = list(_coefficient_vectors(len(parents), max_order)) + best: Combination | None = None + for coefficients in vectors: + weights = np.asarray(coefficients, dtype=np.float64) + predicted = float(np.dot(weights, parent_freq)) + if predicted <= 0.0: + continue + propagated = float( + np.sqrt(sigma[child] ** 2 + np.dot(weights**2, parent_sigma**2)) + ) + tolerance = max(n_sigma * propagated, floor) + residual = float(freq[child]) - predicted + if tolerance <= 0.0 or abs(residual) > tolerance: + continue + order = int(np.sum(np.abs(weights))) + if best is not None and ( + order > best.order + or (order == best.order and abs(residual) >= abs(best.residual)) + ): + continue + best = Combination( + index=int(child), + parents=parents, + coefficients=tuple(int(c) for c in coefficients), + order=order, + label=_format_label(names[child], parent_names, coefficients), + predicted=predicted, + residual=residual, + tolerance=tolerance, + expected_false=( + len(vectors) * 2.0 * tolerance / span + if span > 0.0 + else float("nan") + ), + ) + if best is not None: + found.append(best) + return tuple(sorted(found, key=lambda c: c.index)) + + +__all__ = ["Combination", "identify_combinations"] diff --git a/src/cuperiod/prewhiten/engine.py b/src/cuperiod/prewhiten/engine.py new file mode 100644 index 0000000..fc04a07 --- /dev/null +++ b/src/cuperiod/prewhiten/engine.py @@ -0,0 +1,541 @@ +"""The iterative extraction loop: :func:`prewhiten`. + +This is the automated replacement for the interactive Period04 workflow. Starting from +the raw light curve it repeats + +1. compute the amplitude spectrum of the current residuals, +2. take the tallest peak that is resolved from everything already extracted, +3. re-solve every amplitude, phase and the offset jointly and refine the new frequency + non-linearly (``refine``, ``"last"`` by default; the final polish sweeps them all), +4. decide whether the new component survives the stopping criteria, + +until a component fails, no resolved peak remains, or the frequency cap is reached. The +decision at step 4 is the part interactive workflows leave to the operator's judgement, +so it is made explicit here: every run records *why* it stopped, and the criteria are +settings rather than habits. + +Cost is dominated by step 1, and :class:`~cuperiod.prewhiten.spectrum.SpectrumEngine` +makes it one NUFFT per iteration by caching everything that depends only on sampling. +Step 3 uses variable projection, so the optimiser only ever sees the ``K`` frequencies. +""" + +from __future__ import annotations + +from typing import Any + +import numpy as np + +from cuperiod.core._typing import FloatArray +from cuperiod.core.columns import ColumnMap, Domain +from cuperiod.core.config import PreWhitenSettings +from cuperiod.core.errors import InsufficientDataError +from cuperiod.core.grid import ( + GridSpec, + pseudo_nyquist_frequency, + uniform_frequency_grid, +) +from cuperiod.core.lightcurve import LightCurve, MultiBandLightCurve +from cuperiod.prewhiten.combinations import Combination, identify_combinations +from cuperiod.prewhiten.fap import baluev_fap +from cuperiod.prewhiten.fit import MultiSineFit, fit_multisine +from cuperiod.prewhiten.result import PreWhitenResult, Sinusoid, amplitude_ratio +from cuperiod.prewhiten.spectrum import AmplitudeSpectrum, SpectrumEngine +from cuperiod.prewhiten.uncertainty import component_uncertainties + +#: Upper bound on the prune/re-fit passes of the final solution (each strictly shrinks +#: the component count, so this is a safety net rather than a real limit). +_MAX_PRUNE_PASSES = 20 + +#: How many candidate peaks may be discarded (because their refinement merged into an +#: existing component) before the run gives up looking for more. +_MAX_REJECTED_CANDIDATES = 20 + +#: Floor of the automatic search band (cycles/day). The median-gap pseudo-Nyquist of +#: nightly ground-based sampling collapses to a few cycles/day — far below the +#: delta Scuti / HADS frequencies (periods down to ~0.02 d) this tool exists to +#: extract, whose non-sinusoidal light curves also need the first few harmonics in +#: band. Irregular sampling has no true Nyquist limit, so searching above the +#: pseudo-Nyquist is legitimate; dense space cadences exceed the floor and ignore it. +DEFAULT_MAX_FREQUENCY_FLOOR = 50.0 + + +def default_maximum_frequency(time: FloatArray, nyquist_factor: int = 5) -> float: + """The automatic top of the pre-whitening band for this sampling (cycles/day). + + ``nyquist_factor`` times the median-gap pseudo-Nyquist frequency, but never below + :data:`DEFAULT_MAX_FREQUENCY_FLOOR`: sparse ground-based sampling would otherwise + put the whole classical-pulsator regime out of band and the extraction would fit + the daily aliases of the real signal instead. + + Parameters + ---------- + time : numpy.ndarray + Observation times (days). + nyquist_factor : int, default 5 + Multiple of the pseudo-Nyquist frequency to allow. + + Returns + ------- + float + The default ``maximum_frequency`` in cycles/day. + """ + return max( + pseudo_nyquist_frequency(time, nyquist_factor), DEFAULT_MAX_FREQUENCY_FLOOR + ) + + +def default_prewhiten_grid( + lc: LightCurve, settings: PreWhitenSettings | None = None +) -> GridSpec: + """The default uniform frequency grid for pre-whitening ``lc``. + + Runs from ``1/T`` to :func:`default_maximum_frequency` — the pseudo-Nyquist of the + sampling, floored at :data:`DEFAULT_MAX_FREQUENCY_FLOOR` so short-period pulsators + stay in band on sparse ground-based data — oversampled by ``samples_per_peak`` + (10 by default — a finer grid than a plain period search needs, because each peak's + position seeds a non-linear fit). + + Parameters + ---------- + lc : LightCurve + The light curve (non-finite points are ignored). + settings : PreWhitenSettings, optional + Grid-controlling settings; defaults are used when omitted. + + Returns + ------- + GridSpec + A uniform frequency grid. + """ + cfg = settings or PreWhitenSettings() + finite = lc.finite() + if finite.baseline <= 0.0: + raise InsufficientDataError("pre-whitening: no usable time baseline") + maximum = cfg.maximum_frequency + if maximum is None: + maximum = default_maximum_frequency(finite.time, cfg.nyquist_factor) + minimum = cfg.minimum_frequency + if minimum is None: + minimum = 1.0 / finite.baseline + if minimum >= maximum: + raise InsufficientDataError( + f"pre-whitening: empty search band ({minimum} .. {maximum} cycles/day)" + ) + return uniform_frequency_grid( + finite.baseline, + maximum_frequency=maximum, + minimum_frequency=minimum, + samples_per_peak=cfg.samples_per_peak, + ) + + +def _peak_fap( + time: FloatArray, + error: FloatArray | None, + power: float, + *, + f_max: float, +) -> float: + """Baluev false-alarm probability of a peak of normalized power ``power``. + + The amplitude spectrum's ``power`` is the standard-normalized generalized + Lomb-Scargle power by construction, so :func:`baluev_fap` applies directly. An + undefined statistic (a degenerate spectrum, too few points) yields NaN rather than + aborting the extraction. + """ + if not np.isfinite(power) or power <= 0.0: + return float("nan") + return float( + baluev_fap(min(power, 1.0 - 1e-15), time, error, maximum_frequency=f_max) + ) + + +def _accept( + *, + snr: float, + fap: float, + delta_bic: float, + amplitude: float, + settings: PreWhitenSettings, +) -> tuple[bool, str]: + """Whether a freshly extracted component survives; the reason when it does not. + + Every configured criterion must pass. A criterion whose statistic is undefined + (NaN) counts as a failure — silently keeping a component whose significance could + not be measured is exactly the mistake automated pre-whitening exists to avoid. + """ + for criterion in settings.stop_criteria: + if criterion == "snr": + if not (snr >= settings.snr_threshold): + measured = f"{snr:.2f}" if np.isfinite(snr) else "undefined" + return False, f"S/N {measured} < {settings.snr_threshold:g}" + elif criterion == "fap": + if not (fap <= settings.fap_threshold): + measured = f"{fap:.3g}" if np.isfinite(fap) else "undefined" + return False, f"FAP {measured} > {settings.fap_threshold:g}" + elif criterion == "bic": + if not (delta_bic <= -settings.min_delta_bic): + measured = ( + f"{delta_bic:+.1f}" if np.isfinite(delta_bic) else "undefined" + ) + return False, f"dBIC {measured} > -{settings.min_delta_bic:g}" + elif criterion == "amplitude": + floor = settings.min_amplitude + if floor is not None and not (amplitude >= floor): + return False, f"amplitude {amplitude:.4g} < {floor:g}" + return True, "" + + +def _component_snr( + spectrum: AmplitudeSpectrum, fit: MultiSineFit, settings: PreWhitenSettings +) -> FloatArray: + """Breger signal-to-noise of every component against a residual spectrum.""" + out = np.empty(fit.n_components, dtype=np.float64) + for k in range(fit.n_components): + noise = spectrum.noise_at( + float(fit.frequency[k]), + window=settings.snr_window, + estimator=settings.noise_estimator, + ) + out[k] = ( + float(fit.amplitude[k]) / noise + if np.isfinite(noise) and noise > 0.0 + else float("nan") + ) + return out + + +def _as_light_curve( + data: Any, columns: ColumnMap | None, domain: Domain | None +) -> LightCurve: + """Coerce a user input to a single-band :class:`LightCurve`.""" + from cuperiod.api import to_input + + lc = to_input(data, columns=columns, domain=domain) + if isinstance(lc, MultiBandLightCurve): + raise ValueError( + "pre-whitening works on a single band; pass one band " + "(e.g. mblc.bands['V']) rather than a MultiBandLightCurve" + ) + return lc + + +def prewhiten( + data: Any, + *, + settings: PreWhitenSettings | None = None, + grid: GridSpec | None = None, + backend: str | None = None, + columns: ColumnMap | None = None, + domain: Domain | None = None, +) -> PreWhitenResult: + """Extract a pulsator's frequency solution automatically. + + Parameters + ---------- + data : various + The light curve, in any form :func:`cuperiod.to_input` accepts (a + :class:`~cuperiod.LightCurve`, a ``(t, y[, dy])`` tuple, a table, ...). Must be + a single band. + settings : PreWhitenSettings, optional + Grid, stopping, fitting and uncertainty controls. Defaults are the conservative + published choices — see :class:`~cuperiod.PreWhitenSettings`. + grid : GridSpec, optional + A custom uniform frequency grid; defaults to + :func:`default_prewhiten_grid`. + backend : str, optional + Overrides ``settings.backend`` for the amplitude spectrum. + columns, domain : optional + Column mapping and brightness-domain handling for table inputs. + + Returns + ------- + PreWhitenResult + The ranked component list with uncertainties, the residuals and their spectrum, + the fit statistics, and the reason the extraction stopped. + + Raises + ------ + InsufficientDataError + If the light curve has too few finite points or no time baseline. + + Examples + -------- + >>> import cuperiod as cup # doctest: +SKIP + >>> solution = cup.prewhiten((time, mag, mag_err)) # doctest: +SKIP + >>> print(solution.summary()) # doctest: +SKIP + >>> solution.frequency, solution.frequency_error # doctest: +SKIP + """ + cfg = settings or PreWhitenSettings() + lc = _as_light_curve(data, columns, domain).finite() + n = lc.n + if n < cfg.min_detections: + raise InsufficientDataError( + f"pre-whitening: {n} finite points < min_detections {cfg.min_detections}" + ) + if lc.baseline <= 0.0: + raise InsufficientDataError("pre-whitening: no usable time baseline") + + trial_grid = grid if grid is not None else default_prewhiten_grid(lc, cfg) + engine = SpectrumEngine( + lc.time, + lc.error, + grid=trial_grid, + normalization=cfg.normalization, + backend=backend or cfg.backend, + device=cfg.device, + precision=cfg.precision, + eps=cfg.nufft_eps, + freq_batch=cfg.direct_freq_batch, + ) + time, value, error = lc.time, lc.value, lc.error + f_min = float(engine.frequency[0]) + f_max = float(engine.frequency[-1]) + grid_low, grid_high = max(0.5 * f_min, 1e-12), f_max + separation = cfg.min_separation_rayleigh / lc.baseline + max_shift = cfg.refine_bound_rayleigh / lc.baseline + + def refine_bounds(frequencies: FloatArray) -> tuple[FloatArray, FloatArray]: + """Per-frequency refinement box: at most one bound width from where it started. + + Without this a refinement started on a modest peak can slide down the wing of a + much stronger neighbour and land on top of it, producing near-identical + frequencies with enormous, mutually cancelling amplitudes. + """ + low = np.maximum(frequencies - max_shift, grid_low) + high = np.minimum(frequencies + max_shift, grid_high) + return low, np.maximum(high, np.nextafter(low, np.inf)) + + fit = fit_multisine( + time, value, error, np.zeros(0), + fit_mean=True, t_ref=engine.t_ref, refine="none", covariance=False, + ) + initial_spectrum = engine.spectrum(value) + spectrum = initial_spectrum + faps: list[float] = [] + deltas: list[float] = [] + blocked: list[float] = [] + stop_reason = f"reached max_frequencies ({cfg.max_frequencies})" + iterations = 0 + max_attempts = cfg.max_frequencies + _MAX_REJECTED_CANDIDATES + + while fit.n_components < cfg.max_frequencies and iterations < max_attempts: + iterations += 1 + avoid = np.concatenate( + [fit.frequency, np.asarray(blocked, dtype=np.float64)] + ) + index = spectrum.peak_index(exclude=avoid, separation=separation) + if index is None: + stop_reason = "no peak resolved from the existing components remains" + break + f_guess, _ = spectrum.refine_peak(index) + candidates = np.append(fit.frequency, f_guess) + try: + trial = fit_multisine( + time, value, error, candidates, + fit_mean=cfg.fit_mean, + t_ref=engine.t_ref, + refine=cfg.refine, + sweeps=cfg.sweeps, + frequency_bounds=refine_bounds(candidates), + max_nfev=cfg.max_nfev, + covariance=False, + ) + except (ValueError, np.linalg.LinAlgError) as exc: # pragma: no cover + stop_reason = f"fit failed: {exc}" + break + new_frequency = float(trial.frequency[-1]) + if fit.n_components and float( + np.min(np.abs(trial.frequency[:-1] - new_frequency)) + ) < separation: + # The refinement merged the candidate into an existing component: the peak + # was that component's residual, not a new mode. Block it and look further + # down the spectrum rather than abandoning the run. + blocked.append(f_guess) + continue + # Deferred until the candidate survives the collision guard: a discarded + # candidate never uses its false-alarm probability. + fap = _peak_fap( + time, error, float(spectrum.power[index]), f_max=f_max + ) + trial_spectrum = engine.spectrum(trial.residuals) + amplitude = float(trial.amplitude[-1]) + noise = trial_spectrum.noise_at( + new_frequency, window=cfg.snr_window, estimator=cfg.noise_estimator + ) + snr = amplitude / noise if np.isfinite(noise) and noise > 0.0 else float("nan") + delta_bic = trial.bic - fit.bic + accepted, reason = _accept( + snr=snr, fap=fap, delta_bic=delta_bic, amplitude=amplitude, settings=cfg + ) + if not accepted: + stop_reason = reason + break + fit, spectrum = trial, trial_spectrum + faps.append(fap) + deltas.append(delta_bic) + else: + if cfg.max_frequencies == 0: + stop_reason = "max_frequencies is 0" + elif iterations >= max_attempts: + stop_reason = "too many candidates merged with existing components" + + def polish(frequencies: FloatArray) -> MultiSineFit: + """Re-fit at ``frequencies`` as accurately as the component count allows.""" + return fit_multisine( + time, value, error, frequencies, + fit_mean=fit.fit_mean, + t_ref=engine.t_ref, + refine=( + "simultaneous" + if frequencies.size <= cfg.max_simultaneous + else "cyclic" + ), + sweeps=cfg.sweeps, + frequency_bounds=refine_bounds(frequencies), + max_nfev=cfg.max_nfev, + covariance=True, + ) + + # The loop only refines each frequency as it is extracted; the polish optimises the + # whole solution jointly (or, when there are too many components for that to be + # affordable, sweeps them cyclically) so no frequency is left at a stale value. + if cfg.final_refine and fit.n_components > 0: + fit = polish(np.ascontiguousarray(fit.frequency)) + spectrum = engine.spectrum(fit.residuals) + elif fit.covariance.size == 0: + # Every fit inside the loop skips the covariance (it is only needed once); the + # accepted solution still has to carry one for the reported uncertainties. + fit = fit_multisine( + time, value, error, fit.frequency, + fit_mean=fit.fit_mean, t_ref=engine.t_ref, refine="none", covariance=True, + ) + + # The joint polish redistributes power between close components, so a frequency that + # cleared the threshold when it was extracted can end up insignificant in the final + # solution. Drop those and re-fit until every surviving component passes the same + # test it was admitted by; each pass strictly shrinks the solution, so this ends. + kept = list(range(fit.n_components)) + n_pruned = 0 + if cfg.prune and "snr" in cfg.stop_criteria and fit.n_components: + for _ in range(_MAX_PRUNE_PASSES): + measured = _component_snr(spectrum, fit, cfg) + survivors = [ + i + for i in range(fit.n_components) + if measured[i] >= cfg.snr_threshold + ] + if len(survivors) == fit.n_components: + break + n_pruned += fit.n_components - len(survivors) + kept = [kept[i] for i in survivors] + if not survivors: + fit = fit_multisine( + time, value, error, np.zeros(0), + fit_mean=True, t_ref=engine.t_ref, refine="none", covariance=True, + ) + spectrum = engine.spectrum(fit.residuals) + break + fit = polish(fit.frequency[survivors]) + spectrum = engine.spectrum(fit.residuals) + if n_pruned: + stop_reason = ( + f"{stop_reason}; {n_pruned} insignificant component" + f"{'' if n_pruned == 1 else 's'} pruned" + ) + + errors = component_uncertainties( + time, error, fit, + method=cfg.uncertainty, + correlation_correction=cfg.correlation_correction, + n_resamples=cfg.n_resamples, + seed=cfg.seed, + refine=cfg.refine, + sweeps=cfg.sweeps, + frequency_bounds=refine_bounds(fit.frequency), + ) + snr_final = _component_snr(spectrum, fit, cfg) + labels = tuple(f"F{i + 1}" for i in range(fit.n_components)) + matches: tuple[Combination, ...] = () + if cfg.combinations and fit.n_components > 1: + matches = identify_combinations( + fit.frequency, + fit.amplitude, + frequency_error=errors.frequency, + labels=labels, + rayleigh=1.0 / lc.baseline, + max_order=cfg.combination_max_order, + max_parents=cfg.combination_parents, + tolerance_rayleigh=cfg.combination_tolerance_rayleigh, + n_sigma=cfg.combination_sigma, + ) + by_index = {c.index: c.label for c in matches} + + # The spectrum's own reading at each reported frequency: a single-frequency + # measurement of the data, independent of the joint fit. Where the two disagree the + # component's amplitude is entangled with a correlated neighbour (a close pair, or + # far more often an alias sidelobe of the same mode) and means little on its own. + direct = initial_spectrum.amplitude_at(fit.frequency) + ratios = [ + amplitude_ratio(float(fit.amplitude[k]), float(direct[k])) + for k in range(fit.n_components) + ] + + components = tuple( + Sinusoid( + rank=k + 1, + label=labels[k], + frequency=float(fit.frequency[k]), + frequency_error=float(errors.frequency[k]), + amplitude=float(fit.amplitude[k]), + amplitude_error=float(errors.amplitude[k]), + phase=float(fit.phase[k]), + phase_error=float(errors.phase[k]), + snr=float(snr_final[k]), + fap=faps[kept[k]] if kept[k] < len(faps) else float("nan"), + delta_bic=deltas[kept[k]] if kept[k] < len(deltas) else float("nan"), + combination=by_index.get(k), + spectrum_amplitude=float(direct[k]), + blended=bool( + ratios[k] > cfg.blend_tolerance + or ratios[k] < 1.0 / cfg.blend_tolerance + ), + ) + for k in range(fit.n_components) + ) + keep = cfg.store_spectra + return PreWhitenResult( + components=components, + combinations=matches, + offset=fit.offset, + offset_error=fit.offset_error, + t_ref=fit.t_ref, + time=time, + residuals=fit.residuals, + n_samples=n, + baseline=lc.baseline, + stop_reason=stop_reason, + n_iterations=iterations, + n_pruned=n_pruned, + rms=fit.rms, + chi2=fit.chi2, + reduced_chi2=fit.reduced_chi2, + bic=fit.bic, + # The D the estimator actually applied: it returns 1.0 whenever nothing was + # inflated, including for the bootstrap, which is never corrected. + correlation_factor=errors.correlation_factor, + uncertainty_method=cfg.uncertainty, + backend=engine.backend, + spectrum=initial_spectrum if keep else None, + residual_spectrum=spectrum if keep else None, + window=engine.window() if keep else None, + meta=dict(lc.meta), + ) + + +__all__ = [ + "DEFAULT_MAX_FREQUENCY_FLOOR", + "default_maximum_frequency", + "default_prewhiten_grid", + "prewhiten", +] diff --git a/src/cuperiod/prewhiten/fap.py b/src/cuperiod/prewhiten/fap.py new file mode 100644 index 0000000..ee5ed07 --- /dev/null +++ b/src/cuperiod/prewhiten/fap.py @@ -0,0 +1,113 @@ +"""Analytic false-alarm probability of a periodogram peak — Baluev (2008). + +The extraction loop reports a false-alarm probability for every candidate peak and can +stop on it (``stop_criteria=("fap", ...)``). The statistic is Baluev's alias-free upper +bound (MNRAS 385, 1279, eqn 6) for the *standard-normalized* generalized Lomb-Scargle +power, which is exactly the ``power`` carried by an +:class:`~cuperiod.prewhiten.spectrum.AmplitudeSpectrum`: + +.. math:: + + \\mathrm{FAP}(z) \\le 1 - \\big(1 - \\mathrm{FAP}_1(z)\\big)\\,e^{-\\tau(z)}, + +with :math:`\\mathrm{FAP}_1(z) = (1-z)^{(N-3)/2}` the single-frequency tail probability +and :math:`\\tau` the expected number of up-crossings over the searched band, + +.. math:: + + \\tau(z) = \\gamma\\, f_{\\max} \\sqrt{4\\pi\\,\\mathrm{Var}_w(t)}\\; + (1-z)^{(N-4)/2} \\sqrt{\\tfrac{1}{2}(N-1)\\,z}. + +The implementation reproduces ``astropy.timeseries.LombScargle``'s +``false_alarm_probability(..., method="baluev")`` (see the function's notes on time +zero-points) — it exists so a pre-whitening run never has to import +``astropy.timeseries``, whose first import costs around a second: with thousands of +light curves per worker that is noise, but for the single-star CLI and GUI paths it +roughly doubled the time to the first solution. +""" + +from __future__ import annotations + +import numpy as np + +from cuperiod.core._typing import FloatArray + + +def baluev_fap( + power: float | FloatArray, + time: FloatArray, + error: FloatArray | None = None, + *, + maximum_frequency: float, +) -> float | FloatArray: + """Baluev (2008) false-alarm probability of a standard-normalized power. + + Parameters + ---------- + power : float or numpy.ndarray + Standard-normalized Lomb-Scargle power in ``[0, 1)`` — the ``power`` attribute + of an :class:`~cuperiod.prewhiten.spectrum.AmplitudeSpectrum`. Values are + clipped to ``[0, 1]``; a power of exactly 1 would be a perfect fit, so pass + ``1 - eps`` for numerical sanity. + time : numpy.ndarray + Observation times (days). Only their weighted variance enters. + error : numpy.ndarray, optional + 1-sigma uncertainties; weights the time variance by ``1/error**2``. ``None`` + weights uniformly. + maximum_frequency : float + Upper edge of the searched frequency band (cycles/day). The bound scales with + the band, so quote the band actually searched. + + Returns + ------- + float or numpy.ndarray + The false-alarm probability, matching the input's scalar-or-array shape. + NaN when fewer than four observations make the statistic undefined. + + Notes + ----- + This is an *upper bound* that ignores aliasing; for strongly aliased sampling it is + conservative (the true FAP is lower). Matches + ``astropy.timeseries.LombScargle.false_alarm_probability(method="baluev")`` to + machine precision for centred times; for raw Julian dates the two differ at the + ~1e-4 level because astropy evaluates the time variance in one-pass form, which is + where this implementation is the more accurate of the two. + """ + from scipy.special import gammaln + + t = np.asarray(time, dtype=np.float64) + n = int(t.size) + z = np.clip(np.asarray(power, dtype=np.float64), 0.0, 1.0) + if n < 4: + result = np.full(z.shape, np.nan) + return result if np.ndim(power) else float("nan") + # The weighted time variance, computed in centred (two-pass) form: the one-pass + # ``E[t^2] - E[t]^2`` loses ~11 digits on full Julian dates, where the FAP must not + # depend on the zero-point of the time axis at all. + if error is None: + w = np.full(t.shape, 1.0 / n) + else: + w = 1.0 / np.square(np.asarray(error, dtype=np.float64)) + w /= w.sum() + centred = t - float(np.dot(w, t)) + variance = float(np.dot(w, np.square(centred))) + n_h = n - 1 # degrees of freedom of the constant-only null hypothesis + n_k = n - 3 # degrees of freedom of the sinusoid-plus-constant model + # Baluev's Gamma-function prefactor, ~(1 - 0.75/N) for large N. + prefactor = np.sqrt(2.0 / n_h) * np.exp( + gammaln(0.5 * n_h) - gammaln(0.5 * (n_h - 1)) + ) + bandwidth = maximum_frequency * np.sqrt(4.0 * np.pi * variance) + tau = ( + prefactor + * bandwidth + * (1.0 - z) ** (0.5 * (n_k - 1)) + * np.sqrt(0.5 * n_h * z) + ) + single = (1.0 - z) ** (0.5 * n_k) + # 1 - (1 - single) * exp(-tau), written to stay precise for small probabilities. + fap = -np.expm1(-tau) + single * np.exp(-tau) + return fap if np.ndim(power) else float(fap) + + +__all__ = ["baluev_fap"] diff --git a/src/cuperiod/prewhiten/fit.py b/src/cuperiod/prewhiten/fit.py new file mode 100644 index 0000000..acd92ad --- /dev/null +++ b/src/cuperiod/prewhiten/fit.py @@ -0,0 +1,654 @@ +"""Non-linear multi-sinusoid least squares — the "improve all" step of pre-whitening. + +Period04's central operation is a simultaneous fit of every extracted component, + +.. math:: + + y(t) = c_0 + \\sum_k A_k \\sin\\!\\big(2\\pi f_k (t - t_{\\rm ref}) + \\phi_k\\big), + +re-run after each new frequency so amplitudes and phases stay consistent as the solution +grows. This module implements that fit and the covariance it implies. + +The model is *separable*: for fixed frequencies the amplitudes, phases and offset are +the solution of a linear least-squares problem. Only the frequencies are genuinely +non-linear, so the optimiser works on them alone by variable projection (Golub & +Pereyra 1973) with Kaufman's (1975) Jacobian — ``K`` free parameters instead of +``3K + 1``, and every linear parameter solved exactly at each step. + +Three refinement policies are offered: + +``"last"`` (the extraction loop's default) + Optimise only the newest frequency against the residual of the others — one + three-column sub-problem — while still re-solving *every* amplitude, phase and the + offset jointly and exactly. Established frequencies move by far less than their own + uncertainty when a new component is peeled off, so refining them at every iteration + costs ``O(K)`` sub-problems to buy nothing; the final polish sweeps them all. +``"cyclic"`` + Block coordinate descent over all ``K`` frequencies: each is optimised in turn + against the residual with its own component added back, then the linear coefficients + are re-solved jointly. ``O(K N)`` per sweep, and because the model is additive every + step is an exact block minimisation of the same objective, so the fit improves + monotonically. +``"simultaneous"`` + Full variable projection over all ``K`` frequencies at once — including their mutual + covariances, which matters for close pairs. The gold standard, at ``O(N K^2)`` per + evaluation; used for the final polish by default. +""" + +from __future__ import annotations + +from collections.abc import Sequence +from dataclasses import dataclass +from typing import Any, Final, Literal + +import numpy as np + +from cuperiod.core._typing import FloatArray +from cuperiod.prewhiten.spectrum import weighted_epoch + +#: Frequency-refinement policy. +Refinement = Literal["none", "last", "cyclic", "simultaneous"] + +#: Relative rank cutoff for the linear solves and the covariance pseudo-inverse. +_RCOND: Final = 1e-12 + +#: Widest design still solved through the normal equations (see :func:`_solve`). +_NORMAL_MAX_COLS: Final = 12 + +#: Convergence tolerances for the frequency optimiser. A frequency is worth knowing to +#: perhaps a hundredth of its uncertainty, which is ~1e-8 relative even for a long, +#: precise data set; 1e-11 leaves three orders of magnitude of margin and stops the +#: optimiser burning iterations chasing the last bits of round-off. +_FTOL: Final = 1e-11 +_XTOL: Final = 1e-11 +_GTOL: Final = 1e-11 + +#: Elements per transient block when accumulating the covariance normal matrix (8 MB). +_COV_BLOCK_ELEMS: Final = 1 << 20 + +_TWO_PI: Final = 2.0 * np.pi + + +def _as_weights( + n: int, error: FloatArray | None +) -> tuple[FloatArray, FloatArray, bool]: + """``(w, sqrt(w), weighted)`` for inverse-variance or uniform weighting.""" + if error is None: + ones = np.ones(n, dtype=np.float64) + return ones, ones, False + dy = np.ascontiguousarray(np.asarray(error, dtype=np.float64)) + w = 1.0 / (dy * dy) + return w, np.sqrt(w), True + + +def _design(dt: FloatArray, freqs: FloatArray, fit_mean: bool) -> FloatArray: + """The ``(N, 2K + 1)`` linear design ``[cos_1, sin_1, ..., cos_K, sin_K, 1]``. + + Built one frequency at a time so no ``(N, K)`` angle matrix is ever materialised — + the same total trigonometric work with bounded transient memory. + """ + n = int(dt.size) + k = int(freqs.size) + ncol = 2 * k + (1 if fit_mean else 0) + x = np.empty((n, max(ncol, 1)), dtype=np.float64) + for j in range(k): + theta = (_TWO_PI * float(freqs[j])) * dt + x[:, 2 * j] = np.cos(theta) + x[:, 2 * j + 1] = np.sin(theta) + if fit_mean: + x[:, -1] = 1.0 + return x[:, :ncol] + + +def _solve(design: FloatArray, rhs: FloatArray) -> Any: + """Least-squares solution of ``design @ b = rhs`` (multi-RHS, rank-revealing). + + Narrow designs — every evaluation of the cyclic refinement's three-column + sub-problem, which is where the extraction loop spends most of its time — go through + the normal equations with a Cholesky factorisation. Forming ``X^T X`` squares the + condition number, but a few trigonometric columns are conditioned like ``O(1)`` + so the squared condition number is still negligible, and a Gram-diagonal guard + plus Cholesky's own positive-definiteness check catches the degenerate cases. That + is several times faster than a QR of the tall matrix. + + Everything wider falls back to ``gelsy``, a column-pivoted QR: about the cost of a + plain QR — far less than the SVD-based drivers — while still truncating + rank-deficient directions, which matters when two trial frequencies drift close + enough to make the design singular. + """ + if design.shape[1] <= _NORMAL_MAX_COLS and design.shape[0] >= design.shape[1]: + solution = _solve_normal(design, rhs) + if solution is not None: + return solution + from scipy.linalg import lstsq + + return lstsq( + design, rhs, cond=_RCOND, lapack_driver="gelsy", check_finite=False + )[0] + + +def _solve_normal(design: FloatArray, rhs: FloatArray) -> Any: + """Normal-equation solve, or ``None`` when the design looks degenerate.""" + from scipy.linalg import LinAlgError, cho_factor, cho_solve + + gram = design.T @ design + diagonal = np.diag(gram) + if not np.all(np.isfinite(diagonal)): + return None + largest = float(diagonal.max()) if diagonal.size else 0.0 + if largest <= 0.0 or float(diagonal.min()) <= _RCOND * largest: + return None + try: + factor = cho_factor(gram, lower=True, check_finite=False) + solution = cho_solve(factor, design.T @ rhs, check_finite=False) + except (LinAlgError, ValueError): + return None + return solution if np.all(np.isfinite(solution)) else None + + +def _split_linear( + beta: FloatArray, k: int, fit_mean: bool +) -> tuple[FloatArray, FloatArray, float]: + """Split a linear solution into ``(cos coefficients, sin coefficients, offset)``.""" + a = np.ascontiguousarray(beta[0 : 2 * k : 2]) + b = np.ascontiguousarray(beta[1 : 2 * k : 2]) + offset = float(beta[-1]) if fit_mean else 0.0 + return a, b, offset + + +class _VarPro: + """Variable-projection residual/Jacobian for the frequencies of a multi-sine fit. + + The residual and the Jacobian are cached per parameter vector, and the Jacobian is + built *lazily*: the residual costs one multi-column least-squares solve, the + Jacobian projection a second, ``K``-column one, and a trust-region step the + optimiser rejects only ever asks for the residual — so rejected steps (frequent in + tightly bounded fits near close pairs) never pay for derivatives. + """ + + def __init__( + self, dt: FloatArray, yw: FloatArray, sw: FloatArray, fit_mean: bool + ) -> None: + self._dt = dt + self._yw = yw + self._sw = sw + self._fit_mean = fit_mean + self._key: bytes | None = None + self._jac_key: bytes | None = None + self._design: FloatArray = np.zeros((0, 0), dtype=np.float64) + self._design_w: FloatArray = np.zeros((0, 0), dtype=np.float64) + self._beta: FloatArray = np.zeros(0, dtype=np.float64) + self._residual: FloatArray = np.zeros(0, dtype=np.float64) + self._jacobian: FloatArray = np.zeros((0, 0), dtype=np.float64) + + def _evaluate(self, freqs: FloatArray) -> None: + key = np.ascontiguousarray(freqs, dtype=np.float64).tobytes() + if key == self._key: + return + design = _design(self._dt, freqs, self._fit_mean) + design_w = design * self._sw[:, None] + beta = _solve(design_w, self._yw) + self._residual = self._yw - design_w @ beta + self._design, self._design_w, self._beta = design, design_w, beta + self._key = key + + def fun(self, freqs: FloatArray) -> FloatArray: + """Weighted residual vector at ``freqs`` (linear parameters projected out).""" + self._evaluate(freqs) + return self._residual + + def jac(self, freqs: FloatArray) -> FloatArray: + """Kaufman variable-projection Jacobian at ``freqs``.""" + self._evaluate(freqs) + if self._jac_key != self._key: + k = (self._design.shape[1] - (1 if self._fit_mean else 0)) // 2 + n = int(self._dt.size) + a, b, _ = _split_linear(self._beta, k, self._fit_mean) + # d/df_k of the k-th component: 2*pi*dt * (b_k cos - a_k sin). + deriv = np.empty((n, k), dtype=np.float64) + scaled_dt = (_TWO_PI * self._dt) * self._sw + for j in range(k): + deriv[:, j] = scaled_dt * ( + b[j] * self._design[:, 2 * j] - a[j] * self._design[:, 2 * j + 1] + ) + self._jacobian = -( + deriv - self._design_w @ _solve(self._design_w, deriv) + ) + self._jac_key = self._key + return self._jacobian + + +def _normalize_bounds( + bounds: tuple[Any, Any], k: int +) -> tuple[FloatArray, FloatArray]: + """Broadcast scalar-or-array frequency bounds to two length-``k`` arrays. + + The upper bound is nudged above the lower one where they coincide: a collapsed box + is legal input here (a frequency pinned by the caller) but the optimiser rejects it. + """ + lo = np.broadcast_to(np.asarray(bounds[0], dtype=np.float64), (k,)).copy() + hi = np.broadcast_to(np.asarray(bounds[1], dtype=np.float64), (k,)).copy() + hi = np.maximum(hi, np.nextafter(lo, np.inf)) + return lo, hi + + +def _optimize_frequencies( + dt: FloatArray, + yw: FloatArray, + sw: FloatArray, + freqs: FloatArray, + *, + fit_mean: bool, + bounds: tuple[Any, Any], + scale: float, + max_nfev: int, +) -> FloatArray: + """Refine ``freqs`` by variable projection; never returns a worse solution.""" + from scipy.optimize import least_squares + + if freqs.size == 0: + return freqs + lo, hi = _normalize_bounds(bounds, int(freqs.size)) + start = np.clip(np.ascontiguousarray(freqs, dtype=np.float64), lo, hi) + varpro = _VarPro(dt, yw, sw, fit_mean) + start_cost = float(np.sum(varpro.fun(start) ** 2)) + try: + result = least_squares( + varpro.fun, + start, + jac=varpro.jac, + bounds=(lo, hi), + method="trf", + x_scale=np.full(start.size, max(scale, float(np.finfo(float).tiny))), + ftol=_FTOL, + xtol=_XTOL, + gtol=_GTOL, + max_nfev=max_nfev, + ) + except (ValueError, np.linalg.LinAlgError): # pragma: no cover - defensive + return start + improved = np.ascontiguousarray(np.asarray(result.x, dtype=np.float64)) + if not np.all(np.isfinite(improved)): # pragma: no cover - defensive + return start + if 2.0 * float(result.cost) > start_cost: # pragma: no cover - defensive + return start + return improved + + +def _cyclic_refine( + dt: FloatArray, + y: FloatArray, + yw: FloatArray, + sw: FloatArray, + freqs: FloatArray, + *, + fit_mean: bool, + bounds: tuple[FloatArray, FloatArray], + scale: float, + max_nfev: int, + sweeps: int, + indices: Sequence[int] | None = None, +) -> FloatArray: + """Block coordinate descent over the frequencies (see the module docstring). + + ``indices`` restricts the sweep to a subset — the ``"last"`` policy passes just the + newest frequency — while the linear parameters are always re-solved for *all* of + them. + """ + freqs = np.ascontiguousarray(freqs, dtype=np.float64).copy() + k = int(freqs.size) + targets = range(k) if indices is None else indices + for _ in range(max(1, sweeps)): + design = _design(dt, freqs, fit_mean) + beta = _solve(design * sw[:, None], yw) + model = design @ beta + for j in targets: + component = ( + float(beta[2 * j]) * design[:, 2 * j] + + float(beta[2 * j + 1]) * design[:, 2 * j + 1] + ) + partial = model - component + target = (y - partial) * sw + refined = _optimize_frequencies( + dt, target, sw, freqs[j : j + 1], + fit_mean=fit_mean, + bounds=(bounds[0][j : j + 1], bounds[1][j : j + 1]), + scale=scale, + max_nfev=max_nfev, + ) + freqs[j] = refined[0] + # Re-solve just this component against its own target and fold it back into + # the running model; the joint linear solve happens once per sweep (and once + # more in the caller), so this stays O(N) per frequency. + sub_design = _design(dt, freqs[j : j + 1], fit_mean) + sub_beta = _solve(sub_design * sw[:, None], target) + model = partial + sub_design @ sub_beta + design[:, 2 * j] = sub_design[:, 0] + design[:, 2 * j + 1] = sub_design[:, 1] + beta[2 * j] = sub_beta[0] + beta[2 * j + 1] = sub_beta[1] + return freqs + + +def _normal_matrix( + dt: FloatArray, + sw: FloatArray, + freqs: FloatArray, + amps: FloatArray, + phases: FloatArray, + fit_mean: bool, +) -> FloatArray: + """``J^T W J`` for the natural parameters ``[f, A, phi(, c0)]``. + + Accumulated in row blocks so the ``(N, 3K + 1)`` Jacobian is never materialised in + full — a 100k-point curve with 100 frequencies would otherwise need a quarter of a + gigabyte just to report uncertainties. + """ + k = int(freqs.size) + n = int(dt.size) + ncol = 3 * k + (1 if fit_mean else 0) + gram = np.zeros((ncol, ncol), dtype=np.float64) + if ncol == 0 or n == 0: + return gram + block = max(1, _COV_BLOCK_ELEMS // max(ncol, 1)) + for start in range(0, n, block): + stop = min(start + block, n) + dt_b = dt[start:stop] + jac = np.empty((stop - start, ncol), dtype=np.float64) + for j in range(k): + theta = _TWO_PI * float(freqs[j]) * dt_b + float(phases[j]) + cos_j = np.cos(theta) + jac[:, j] = float(amps[j]) * cos_j * (_TWO_PI * dt_b) # d/df + jac[:, k + j] = np.sin(theta) # d/dA + jac[:, 2 * k + j] = float(amps[j]) * cos_j # d/dphi + if fit_mean: + jac[:, -1] = 1.0 + jac *= sw[start:stop, None] + gram += jac.T @ jac + return gram + + +def _covariance( + gram: FloatArray, *, rss: float, n_samples: int, n_parameters: int +) -> FloatArray: + """``s^2 (J^T W J)^+`` with ``s^2 = RSS / (N - M)``. + + Scaling by the reduced chi-square is deliberate: it makes the uncertainties correct + when no error bars were supplied (the noise level comes from the fit itself) and + robust to the common case of survey error bars mis-scaled by a constant factor. + """ + if gram.size == 0: + return gram + dof = n_samples - n_parameters + scale = rss / dof if dof > 0 else float("nan") + values, vectors = np.linalg.eigh(gram) + cutoff = _RCOND * float(max(values.max(), 0.0)) + keep = values > cutoff + inverse_values = np.where(keep, 1.0 / np.where(keep, values, 1.0), 0.0) + covariance: FloatArray = (vectors * inverse_values) @ vectors.T + return covariance * scale + + +@dataclass(frozen=True) +class MultiSineFit: + """The fitted multi-sinusoid solution for one light curve. + + Attributes + ---------- + frequency, amplitude, phase : numpy.ndarray + The ``K`` components. ``phase`` is in radians for the convention + ``A sin(2*pi*f*(t - t_ref) + phase)``, wrapped to ``[0, 2*pi)``. + offset : float + The fitted constant ``c_0`` (zero when ``fit_mean=False``). + t_ref : float + Epoch the phases are referenced to (days). + residuals : numpy.ndarray + ``value - model(time)`` at the input samples. + covariance : numpy.ndarray + Parameter covariance in the natural parameterisation, ordered + ``[f_0..f_{K-1}, A_0..A_{K-1}, phi_0..phi_{K-1}(, c_0)]``. Empty when the caller + asked for no covariance. + rss : float + Weighted residual sum of squares (equal to chi-square when errors were given). + n_samples, n_parameters : int + Sample and free-parameter counts (``M = 3K + 1``). + weighted : bool + Whether inverse-variance weights were used. + """ + + frequency: FloatArray + amplitude: FloatArray + phase: FloatArray + offset: float + t_ref: float + residuals: FloatArray + covariance: FloatArray + rss: float + n_samples: int + n_parameters: int + weighted: bool + fit_mean: bool = True + + @property + def n_components(self) -> int: + """Number of sinusoids in the solution.""" + return int(self.frequency.size) + + @property + def chi2(self) -> float: + """Chi-square (equal to :attr:`rss`; meaningful when errors were supplied).""" + return self.rss + + @property + def reduced_chi2(self) -> float: + """Chi-square per degree of freedom.""" + dof = self.n_samples - self.n_parameters + return self.rss / dof if dof > 0 else float("nan") + + @property + def rms(self) -> float: + """Unweighted RMS of the residuals, in the units of the input.""" + if self.residuals.size == 0: + return float("nan") + return float(np.sqrt(np.mean(self.residuals**2))) + + @property + def bic(self) -> float: + """Bayesian information criterion (lower is better). + + With errors the Gaussian log-likelihood is ``-chi2/2`` and + ``BIC = chi2 + M ln N``. Without errors the noise scale is unknown and profiled + out, giving ``BIC = N ln(RSS/N) + M ln N``. Either way only *differences* + between solutions on one data set matter, which is all the stopping rule uses. + """ + return self._criterion(float(np.log(self.n_samples)) if self.n_samples else 0.0) + + @property + def aic(self) -> float: + """Akaike information criterion (lower is better).""" + return self._criterion(2.0) + + def _criterion(self, per_parameter: float) -> float: + n, m = self.n_samples, self.n_parameters + if n <= 0: + return float("nan") + penalty = m * per_parameter + if self.weighted: + return self.rss + penalty + if self.rss <= 0.0: # pragma: no cover - an exact fit + return -float("inf") + return n * float(np.log(self.rss / n)) + penalty + + # -- derived uncertainties --------------------------------------------------- + def _sigma(self, block: int) -> FloatArray: + k = self.n_components + if self.covariance.size == 0 or k == 0: + return np.full(k, np.nan, dtype=np.float64) + diagonal = np.diag(self.covariance)[block * k : (block + 1) * k] + return np.sqrt(np.clip(diagonal, 0.0, None)) + + @property + def frequency_error(self) -> FloatArray: + """1-sigma frequency uncertainties from the covariance (cycles/day).""" + return self._sigma(0) + + @property + def amplitude_error(self) -> FloatArray: + """1-sigma amplitude uncertainties from the covariance.""" + return self._sigma(1) + + @property + def phase_error(self) -> FloatArray: + """1-sigma phase uncertainties from the covariance (radians).""" + return self._sigma(2) + + @property + def offset_error(self) -> float: + """1-sigma uncertainty on the constant term.""" + if self.covariance.size == 0 or not self.fit_mean: + return float("nan") + return float(np.sqrt(max(float(self.covariance[-1, -1]), 0.0))) + + # -- evaluation -------------------------------------------------------------- + def component(self, index: int, time: FloatArray) -> FloatArray: + """The ``index``-th sinusoid evaluated at ``time``.""" + dt = np.asarray(time, dtype=np.float64) - self.t_ref + theta = _TWO_PI * float(self.frequency[index]) * dt + float(self.phase[index]) + return float(self.amplitude[index]) * np.sin(theta) + + def model(self, time: FloatArray, *, include_offset: bool = True) -> FloatArray: + """The full model evaluated at ``time``.""" + t = np.asarray(time, dtype=np.float64) + out = np.full(t.shape, self.offset if include_offset else 0.0, dtype=np.float64) + for k in range(self.n_components): + out += self.component(k, t) + return out + + +def fit_multisine( + time: FloatArray, + value: FloatArray, + error: FloatArray | None, + frequencies: FloatArray, + *, + fit_mean: bool = True, + t_ref: float | None = None, + refine: Refinement = "cyclic", + sweeps: int = 1, + frequency_bounds: tuple[Any, Any] | None = None, + max_nfev: int = 200, + covariance: bool = True, +) -> MultiSineFit: + """Fit ``y = c0 + sum_k A_k sin(2 pi f_k (t - t_ref) + phi_k)``. + + Parameters + ---------- + time, value : numpy.ndarray + The light curve (finite points only). + error : numpy.ndarray, optional + 1-sigma uncertainties; ``None`` fits unweighted. + frequencies : numpy.ndarray + Starting frequencies in cycles/day. May be empty (then only the offset is fit). + Refinement is *local*: a start further than about half a Rayleigh width + (``0.5/T``) from the true frequency can settle on a sidelobe, so seed it from a + spectrum peak — which is what :func:`~cuperiod.prewhiten.prewhiten` does. + fit_mean : bool, default True + Include a free constant term. + t_ref : float, optional + Phase reference epoch; defaults to + :func:`~cuperiod.prewhiten.spectrum.weighted_epoch`, which decorrelates each + phase from its frequency and so minimises the reported phase uncertainty. + refine : {"none", "last", "cyclic", "simultaneous"}, default "cyclic" + Frequency-refinement policy (see the module docstring). ``"none"`` solves only + the linear parameters at the given frequencies. + sweeps : int, default 1 + Number of cyclic sweeps (ignored by the other policies). + frequency_bounds : (lower, upper), optional + Box the refined frequencies. Scalars apply to every frequency; arrays give each + one its own box, which is how the extraction loop stops a refinement from + wandering off its own peak and onto a neighbour's. Defaults to + ``(f_min/2, 2 f_max)`` of the starting values. + max_nfev : int, default 200 + Optimiser evaluation cap per non-linear solve. + covariance : bool, default True + Compute the parameter covariance (the source of the reported uncertainties). + + Returns + ------- + MultiSineFit + + Examples + -------- + >>> fit = fit_multisine(t, mag, err, [1.234, 2.468]) # doctest: +SKIP + >>> fit.amplitude, fit.amplitude_error # doctest: +SKIP + """ + t = np.ascontiguousarray(np.asarray(time, dtype=np.float64)) + y = np.ascontiguousarray(np.asarray(value, dtype=np.float64)) + if t.shape != y.shape: + raise ValueError("time and value must have the same length") + freqs = np.ascontiguousarray(np.asarray(frequencies, dtype=np.float64)).ravel() + if freqs.size == 0 and not fit_mean: + raise ValueError("fit_multisine needs at least one frequency or fit_mean=True") + n = int(t.size) + w, sw, weighted = _as_weights(n, error) + ref = weighted_epoch(t, w) if t_ref is None else float(t_ref) + dt = t - ref + yw = sw * y + baseline = float(t.max() - t.min()) if n else 0.0 + rayleigh = 1.0 / baseline if baseline > 0.0 else 1.0 + + if frequency_bounds is not None: + raw_bounds: tuple[Any, Any] = frequency_bounds + elif freqs.size: + low = max(0.5 * float(freqs.min()), 1e-12) + raw_bounds = (low, max(2.0 * float(freqs.max()), low * (1.0 + 1e-9))) + else: + raw_bounds = (1e-12, 1.0) + bounds = _normalize_bounds(raw_bounds, int(freqs.size)) + + if freqs.size and refine == "simultaneous": + freqs = _optimize_frequencies( + dt, yw, sw, freqs, + fit_mean=fit_mean, bounds=bounds, scale=rayleigh, max_nfev=max_nfev, + ) + elif freqs.size and refine in {"cyclic", "last"}: + freqs = _cyclic_refine( + dt, y, yw, sw, freqs, + fit_mean=fit_mean, bounds=bounds, scale=rayleigh, + max_nfev=max_nfev, sweeps=1 if refine == "last" else sweeps, + indices=(int(freqs.size) - 1,) if refine == "last" else None, + ) + + design = _design(dt, freqs, fit_mean) + beta = _solve(design * sw[:, None], yw) + a, b, offset = _split_linear(beta, int(freqs.size), fit_mean) + amplitude = np.hypot(a, b) + phase = np.mod(np.arctan2(a, b), _TWO_PI) + residuals = y - design @ beta + rss = float(np.dot(w, residuals * residuals)) + n_parameters = int(3 * freqs.size + (1 if fit_mean else 0)) + + if covariance: + gram = _normal_matrix(dt, sw, freqs, amplitude, phase, fit_mean) + cov = _covariance( + gram, rss=rss, n_samples=n, n_parameters=n_parameters + ) + else: + cov = np.zeros((0, 0), dtype=np.float64) + return MultiSineFit( + frequency=freqs, + amplitude=amplitude, + phase=phase, + offset=offset, + t_ref=ref, + residuals=residuals, + covariance=cov, + rss=rss, + n_samples=n, + n_parameters=n_parameters, + weighted=weighted, + fit_mean=fit_mean, + ) + + +__all__ = ["MultiSineFit", "Refinement", "fit_multisine"] diff --git a/src/cuperiod/prewhiten/result.py b/src/cuperiod/prewhiten/result.py new file mode 100644 index 0000000..0195867 --- /dev/null +++ b/src/cuperiod/prewhiten/result.py @@ -0,0 +1,386 @@ +"""Result objects for pre-whitening: :class:`Sinusoid` and :class:`PreWhitenResult`. + +A :class:`PreWhitenResult` is the frequency solution of one light curve — the ranked +list of extracted sinusoids with their uncertainties and signal-to-noise, the residuals +and their spectrum, the fit statistics, and an explicit record of *why the extraction +stopped*. That last part matters: a frequency list without its stopping criterion cannot +be reproduced or compared with anyone else's. +""" + +from __future__ import annotations + +from collections.abc import Mapping +from dataclasses import dataclass, field +from typing import Any + +import numpy as np + +from cuperiod.core._typing import FloatArray +from cuperiod.prewhiten.combinations import Combination +from cuperiod.prewhiten.spectrum import AmplitudeSpectrum + +_TWO_PI = 2.0 * np.pi + + +def amplitude_ratio(amplitude: float, spectrum_amplitude: float) -> float: + """Fitted amplitude over the spectrum's own reading at the same frequency. + + See :attr:`Sinusoid.amplitude_ratio` for what the number means. Returns ``inf`` + when the spectrum is flat there but the fit still claims amplitude, and NaN when + neither is measurable. + """ + if not (np.isfinite(amplitude) and np.isfinite(spectrum_amplitude)): + return float("nan") + if spectrum_amplitude > 0.0: + return amplitude / spectrum_amplitude + return float("inf") if amplitude > 0.0 else float("nan") + + +@dataclass(frozen=True) +class Sinusoid: + """One extracted sinusoidal component. + + Attributes + ---------- + rank : int + 1-based extraction order (rank 1 was the strongest peak of the original data). + label : str + Display label ``F1``, ``F2``, ... matching ``rank``. + frequency, frequency_error : float + Frequency and its 1-sigma uncertainty in cycles/day. + amplitude, amplitude_error : float + Amplitude and its 1-sigma uncertainty, in the units of the input. + phase, phase_error : float + Phase and its 1-sigma uncertainty in radians, for the convention + ``A sin(2*pi*f*(t - t_ref) + phase)``. + snr : float + Amplitude divided by the local noise level of the residual spectrum after this + component was removed (the Breger et al. 1993 criterion). + fap : float + False-alarm probability of the peak in the spectrum it was drawn from, or NaN if + it could not be computed. + delta_bic : float + Change in the Bayesian information criterion when this component was added. + Negative means the component improved the model. + combination : str or None + Identification as a combination of stronger components, if any. + spectrum_amplitude : float + The amplitude spectrum of the *input data* read directly at this frequency — + the single-frequency measurement, independent of the joint fit. + blended : bool + Whether :attr:`amplitude_ratio` falls outside the run's + :attr:`~cuperiod.PreWhitenSettings.blend_tolerance`. + """ + + rank: int + label: str + frequency: float + frequency_error: float + amplitude: float + amplitude_error: float + phase: float + phase_error: float + snr: float + fap: float = float("nan") + delta_bic: float = float("nan") + combination: str | None = None + spectrum_amplitude: float = float("nan") + blended: bool = False + + @property + def period(self) -> float: + """Period in days.""" + return 1.0 / self.frequency if self.frequency != 0.0 else float("inf") + + @property + def period_error(self) -> float: + """1-sigma period uncertainty in days (``sigma_P = sigma_f / f^2``).""" + if self.frequency == 0.0: + return float("nan") + return self.frequency_error / (self.frequency * self.frequency) + + @property + def amplitude_ratio(self) -> float: + """Fitted :attr:`amplitude` over :attr:`spectrum_amplitude` (1.0 = agreement). + + The fitted amplitude comes from the *joint* solution of every component at + once; the spectrum's reading treats this frequency as if it were alone. They + agree for a mode that is resolved from its neighbours and free of window + leakage, so a ratio far from 1 says this component's amplitude is not an + independent measurement — it is entangled with the components it is correlated + with, and moving one moves the other. That happens for genuinely close pairs + and, very commonly in ground-based data, for a mode and its own alias + sidelobes. + + A discrepancy is **not** a significance test: a blended component can be + perfectly real (an alias sidelobe *is* in the data). It means the amplitude + should be quoted with its partners, not on its own. + """ + return amplitude_ratio(self.amplitude, self.spectrum_amplitude) + + def to_dict(self) -> dict[str, Any]: + """Flatten to a plain dict (also the batch/CSV row layout).""" + return { + "rank": self.rank, + "label": self.label, + "frequency": self.frequency, + "frequency_error": self.frequency_error, + "period": self.period, + "period_error": self.period_error, + "amplitude": self.amplitude, + "amplitude_error": self.amplitude_error, + "spectrum_amplitude": self.spectrum_amplitude, + "amplitude_ratio": self.amplitude_ratio, + "blended": self.blended, + "phase": self.phase, + "phase_error": self.phase_error, + "snr": self.snr, + "fap": self.fap, + "delta_bic": self.delta_bic, + "combination": self.combination, + } + + +@dataclass(frozen=True) +class PreWhitenResult: + """The frequency solution of one light curve. + + Attributes + ---------- + components : tuple of Sinusoid + The extracted sinusoids, in extraction order (strongest first). + combinations : tuple of Combination + Components identified as integer combinations of stronger ones. + offset, offset_error : float + The fitted constant term and its uncertainty. + t_ref : float + Epoch the phases are referenced to (days). + time, residuals : numpy.ndarray + The times used and ``value - model``, aligned. + n_samples : int + Number of finite points used. + baseline : float + Time span in days (the Rayleigh resolution is ``1/baseline``). + stop_reason : str + Why the extraction stopped — always populated. + n_iterations : int + Extraction attempts made, including the rejected final one. + n_pruned : int + Components dropped by the final significance re-check (see + :attr:`~cuperiod.PreWhitenSettings.prune`). + rms, chi2, reduced_chi2, bic : float + Fit statistics of the accepted solution. + correlation_factor : float + Schwarzenberg-Czerny ``D`` applied to the uncertainties (1.0 if uncorrected + or when ``uncertainty="bootstrap"``, which is never inflated). + uncertainty_method : str + Which estimator produced the reported errors. + backend : str + Concrete spectrum backend that ran. + spectrum, residual_spectrum : AmplitudeSpectrum or None + Amplitude spectra of the original data and of the residuals (``None`` when the + run was told not to keep them, as in batch mode). + window : AmplitudeSpectrum or None + The spectral window ``|W(f)|`` of the sampling, for alias diagnosis (``None`` + when spectra are not kept). + meta : Mapping + Free-form metadata carried from the light curve. + """ + + components: tuple[Sinusoid, ...] + combinations: tuple[Combination, ...] + offset: float + offset_error: float + t_ref: float + time: FloatArray + residuals: FloatArray + n_samples: int + baseline: float + stop_reason: str + n_iterations: int + n_pruned: int + rms: float + chi2: float + reduced_chi2: float + bic: float + correlation_factor: float + uncertainty_method: str + backend: str + spectrum: AmplitudeSpectrum | None = None + residual_spectrum: AmplitudeSpectrum | None = None + window: AmplitudeSpectrum | None = None + meta: Mapping[str, Any] = field(default_factory=dict) + + # -- convenience views ------------------------------------------------------- + def __len__(self) -> int: + return len(self.components) + + def __iter__(self) -> Any: + return iter(self.components) + + def __getitem__(self, index: int) -> Sinusoid: + return self.components[index] + + @property + def n_components(self) -> int: + """Number of extracted sinusoids.""" + return len(self.components) + + @property + def rayleigh(self) -> float: + """Rayleigh frequency resolution ``1/baseline`` (cycles/day).""" + return 1.0 / self.baseline if self.baseline > 0.0 else float("inf") + + @property + def n_blended(self) -> int: + """How many components' amplitudes disagree with the spectrum's own reading. + + See :attr:`Sinusoid.amplitude_ratio`. A non-zero count is a reliability + warning about individual amplitudes, not about the solution's significance. + """ + return sum(1 for c in self.components if c.blended) + + def _column(self, name: str) -> FloatArray: + return np.asarray( + [getattr(c, name) for c in self.components], dtype=np.float64 + ) + + @property + def frequency(self) -> FloatArray: + """Component frequencies (cycles/day).""" + return self._column("frequency") + + @property + def frequency_error(self) -> FloatArray: + """Component frequency uncertainties (cycles/day).""" + return self._column("frequency_error") + + @property + def period(self) -> FloatArray: + """Component periods (days).""" + return self._column("period") + + @property + def amplitude(self) -> FloatArray: + """Component amplitudes.""" + return self._column("amplitude") + + @property + def amplitude_error(self) -> FloatArray: + """Component amplitude uncertainties.""" + return self._column("amplitude_error") + + @property + def phase(self) -> FloatArray: + """Component phases (radians).""" + return self._column("phase") + + @property + def snr(self) -> FloatArray: + """Component signal-to-noise ratios.""" + return self._column("snr") + + def independent(self) -> tuple[Sinusoid, ...]: + """Components not identified as combinations of stronger ones. + + The candidate independent mode list — what a mode-identification or + period-spacing analysis should be run on. + """ + return tuple(c for c in self.components if c.combination is None) + + # -- evaluation -------------------------------------------------------------- + def model(self, time: FloatArray, *, include_offset: bool = True) -> FloatArray: + """Evaluate the fitted multi-sine model at ``time``.""" + t = np.asarray(time, dtype=np.float64) + out = np.full(t.shape, self.offset if include_offset else 0.0, dtype=np.float64) + dt = t - self.t_ref + for c in self.components: + out += c.amplitude * np.sin(_TWO_PI * c.frequency * dt + c.phase) + return out + + # -- serialization ----------------------------------------------------------- + def to_table(self) -> list[dict[str, Any]]: + """The component list as plain dicts, one row per component.""" + return [c.to_dict() for c in self.components] + + def to_dataframe(self) -> Any: + """The component list as a pandas ``DataFrame`` (requires pandas).""" + import pandas as pd + + return pd.DataFrame(self.to_table()) + + def to_dict(self, *, include_residuals: bool = False) -> dict[str, Any]: + """Serialize to a plain, JSON-friendly dict.""" + out: dict[str, Any] = { + "n_components": self.n_components, + "n_samples": self.n_samples, + "baseline": self.baseline, + "rayleigh": self.rayleigh, + "t_ref": self.t_ref, + "offset": self.offset, + "offset_error": self.offset_error, + "stop_reason": self.stop_reason, + "n_iterations": self.n_iterations, + "n_pruned": self.n_pruned, + "n_blended": self.n_blended, + "rms": self.rms, + "chi2": self.chi2, + "reduced_chi2": self.reduced_chi2, + "bic": self.bic, + "correlation_factor": self.correlation_factor, + "uncertainty_method": self.uncertainty_method, + "backend": self.backend, + "components": self.to_table(), + "combinations": [c.to_dict() for c in self.combinations], + } + if include_residuals: + out["time"] = self.time.tolist() + out["residuals"] = self.residuals.tolist() + return out + + def summary(self, *, max_rows: int = 50) -> str: + """A formatted, human-readable report of the solution.""" + head = ( + f"Pre-whitening: {self.n_components} component" + f"{'' if self.n_components == 1 else 's'} from {self.n_samples} points " + f"over {self.baseline:.4g} d (backend={self.backend})" + ) + stop = f" stopped: {self.stop_reason}" + stats = ( + f" residual rms {self.rms:.6g} reduced chi2 {self.reduced_chi2:.4g}" + f" D={self.correlation_factor:.2f} errors: {self.uncertainty_method}" + ) + header = ( + f" {'ID':<4} {'frequency (1/d)':>17} {'+/-':>11} " + f"{'amplitude':>13} {'+/-':>11} {'phase':>8} {'S/N':>7} {'A/Asp':>7} note" + ) + lines = [head, stop, stats, "", header] + for c in self.components[:max_rows]: + note = c.combination or "" + ratio = c.amplitude_ratio + shown = f"{ratio:.2f}" if np.isfinite(ratio) else "—" + lines.append( + f" {c.label:<4} {c.frequency:>17.9g} {c.frequency_error:>11.3g} " + f"{c.amplitude:>13.6g} {c.amplitude_error:>11.3g} " + f"{c.phase:>8.4f} {c.snr:>7.2f} " + f"{shown + ('*' if c.blended else ''):>7} {note}" + ) + if self.n_components > max_rows: + lines.append(f" ... {self.n_components - max_rows} more") + if self.n_blended: + lines.append( + f" * {self.n_blended} amplitude" + f"{'' if self.n_blended == 1 else 's'} disagree with the spectrum " + "(A/Asp): blended with a correlated neighbour, so quote them together " + "rather than alone." + ) + return "\n".join(lines) + + def __repr__(self) -> str: + return ( + f"PreWhitenResult({self.n_components} components, " + f"n={self.n_samples}, stop={self.stop_reason!r})" + ) + + +__all__ = ["PreWhitenResult", "Sinusoid", "amplitude_ratio"] diff --git a/src/cuperiod/prewhiten/spacing.py b/src/cuperiod/prewhiten/spacing.py new file mode 100644 index 0000000..bf32ab7 --- /dev/null +++ b/src/cuperiod/prewhiten/spacing.py @@ -0,0 +1,607 @@ +"""g-mode period-spacing tools. + +High-order gravity modes of the same degree and azimuthal order are asymptotically +equally spaced **in period**, and the spacing carries the physics: its mean value fixes +the buoyancy travel time, its slope traces near-core rotation, and periodic dips in it +reveal chemical-gradient zones left by a retreating convective core. Recovering that +pattern from a frequency list is the step after pre-whitening for γ Dor and SPB stars. + +Three tools, in the order they are normally used: + +:func:`spacing_spectrum` + Where is the comb? A scan over trial spacings of + ``|sum_j a_j exp(2 pi i P_j / dP)|^2`` — the Fourier response of the period list + treated as a spike train. Sharply peaked at a genuine regular spacing, and unlike a + histogram of consecutive differences it is unaffected by missing modes. +:func:`find_period_spacing` + Which modes belong to it? A dynamic-programme search for the longest chain of modes + whose consecutive spacings follow a *tilted* pattern ``dP(P) = a + b P``, allowing a + bounded number of missing radial orders to be bridged. +:func:`echelle` + Does it look right? Period modulo the spacing, the diagnostic plot in which a clean + series is a near-vertical ridge. + +The same machinery works on frequencies, where a regular spacing is the p-mode large +separation or a rotational splitting — pass frequencies instead of periods. +""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Final + +import numpy as np + +from cuperiod.core._typing import FloatArray +from cuperiod.core.config import SpacingSettings + +#: Seconds per day, for reporting the buoyancy radius in the usual units. +_SECONDS_PER_DAY: Final = 86400.0 + +#: Cap on the trial-spacing grid so a pathological input cannot allocate unboundedly. +_MAX_GRID: Final = 1 << 21 + +#: Elements per transient block of the comb response (8 MB). +_BLOCK_ELEMS: Final = 1 << 20 + +#: Fraction of the peak response a wider comb must retain to be promoted over it. +_SUBMULTIPLE_RATIO: Final = 0.8 + +#: Largest integer multiple of the winning spacing tested for the promotion above. +_MAX_SUBMULTIPLE: Final = 6 + +#: Phase-residual cut (in fractions of a spacing) for "this value is on that comb". +_COMB_MEMBER_TOL: Final = 0.15 + + +@dataclass(frozen=True) +class SpacingSpectrum: + """Comb response of a set of values against trial spacings. + + Attributes + ---------- + spacing : numpy.ndarray + Trial spacings, ascending, in the units of the input (days for periods). + power : numpy.ndarray + Response in ``[0, 1]``; 1 means every value lands on the same comb. + best_spacing : float + The reported comb spacing — the tallest response, promoted past any sub-multiple + of itself (see the module notes). + best_power : float + The response at ``best_spacing``; not necessarily ``power.max()``. + n_values : int + Number of input values. + """ + + spacing: FloatArray + power: FloatArray + best_spacing: float + best_power: float + n_values: int + + @property + def size(self) -> int: + """Number of trial spacings.""" + return int(self.spacing.size) + + def to_dict(self) -> dict[str, Any]: + """Flatten the summary (not the full arrays) to a plain dict.""" + return { + "best_spacing": self.best_spacing, + "best_power": self.best_power, + "n_values": self.n_values, + "n_trials": self.size, + } + + +@dataclass(frozen=True) +class PeriodSpacingSeries: + """A chain of modes following one (possibly tilted) period-spacing pattern. + + Attributes + ---------- + indices : tuple of int + Positions in the *input* array of the member modes, in ascending period. + periods : numpy.ndarray + Member periods (days), ascending. + spacings : numpy.ndarray + Observed consecutive differences ``P[i+1] - P[i]`` (days). + multiplicity : numpy.ndarray + How many radial orders each observed step spans — 1 for a consecutive pair, 2 if + one mode is missing, and so on. + midpoints : numpy.ndarray + ``(P[i] + P[i+1]) / 2``, the period each spacing is plotted against. + mean_spacing : float + Amplitude-unweighted mean of ``spacings / multiplicity`` (days). + slope, intercept : float + The fitted tilt ``dP(P) = intercept + slope * P``. A non-zero slope is the + signature of rotation in the asymptotic g-mode pattern. + rms : float + RMS of ``spacings/multiplicity`` about the tilted model (days). + ell : int + Spherical degree assumed when converting to a buoyancy radius. + buoyancy_radius : float + ``Pi_0 = mean_spacing * sqrt(l(l+1))`` in **seconds**. + """ + + indices: tuple[int, ...] + periods: FloatArray + spacings: FloatArray + multiplicity: FloatArray + midpoints: FloatArray + mean_spacing: float + slope: float + intercept: float + rms: float + ell: int + buoyancy_radius: float + + @property + def n_modes(self) -> int: + """Number of modes in the series.""" + return len(self.indices) + + def predicted_spacing(self, period: FloatArray) -> FloatArray: + """The tilted model spacing at ``period``.""" + return self.intercept + self.slope * np.asarray(period, dtype=np.float64) + + def to_dict(self) -> dict[str, Any]: + """Flatten to a plain, JSON-friendly dict.""" + return { + "n_modes": self.n_modes, + "indices": list(self.indices), + "periods": self.periods.tolist(), + "spacings": self.spacings.tolist(), + "multiplicity": self.multiplicity.astype(int).tolist(), + "mean_spacing": self.mean_spacing, + "slope": self.slope, + "intercept": self.intercept, + "rms": self.rms, + "ell": self.ell, + "buoyancy_radius": self.buoyancy_radius, + } + + def summary(self) -> str: + """A one-paragraph human-readable report.""" + return ( + f"Period spacing: {self.n_modes} modes, " + f" = {self.mean_spacing * _SECONDS_PER_DAY:.1f} s " + f"({self.mean_spacing:.6g} d), slope {self.slope:+.4g}, " + f"rms {self.rms * _SECONDS_PER_DAY:.1f} s, " + f"Pi_0(l={self.ell}) = {self.buoyancy_radius:.0f} s" + ) + + +def buoyancy_radius(mean_spacing: float, ell: int = 1) -> float: + """Asymptotic buoyancy travel time ``Pi_0`` in seconds. + + In the asymptotic limit ``dP_l = Pi_0 / sqrt(l(l+1))``, so a measured spacing fixes + ``Pi_0`` once the degree is known. Dipole modes (``l = 1``) dominate γ Dor and SPB + spectra. + + Parameters + ---------- + mean_spacing : float + Mean period spacing in days. + ell : int, default 1 + Spherical degree. + + Returns + ------- + float + ``Pi_0`` in seconds. + """ + if ell < 1: + raise ValueError("ell must be >= 1") + return float(mean_spacing * np.sqrt(ell * (ell + 1)) * _SECONDS_PER_DAY) + + +def echelle( + values: FloatArray, spacing: float, *, reference: float = 0.0 +) -> tuple[FloatArray, FloatArray]: + """Échelle coordinates ``(value mod spacing, value)``. + + Parameters + ---------- + values : numpy.ndarray + Periods (or frequencies) to fold. + spacing : float + The folding spacing, in the same units. + reference : float, default 0.0 + Offset subtracted before folding — useful to centre the ridge in the panel. + + Returns + ------- + tuple of numpy.ndarray + ``(x, y)``: the folded coordinate and the original value. + """ + if spacing <= 0.0: + raise ValueError("spacing must be positive") + v = np.asarray(values, dtype=np.float64) + return np.mod(v - reference, spacing), v + + +def _default_spacing_range(sorted_values: FloatArray) -> tuple[float, float]: + """``(minimum, maximum)`` trial spacing from the data alone. + + The upper bound is the full range (a two-tooth comb); the lower bound is half the + smallest observed gap, floored at a tenth of the mean gap so an accidental near-pair + of modes cannot drag the search into a decade of meaningless fine spacings. + """ + n = int(sorted_values.size) + span = float(sorted_values[-1] - sorted_values[0]) + gaps = np.diff(sorted_values) + gaps = gaps[gaps > 0.0] + smallest = float(gaps.min()) if gaps.size else span + return max(0.5 * smallest, span / (10.0 * n)), span + + +def spacing_spectrum( + values: FloatArray, + *, + weights: FloatArray | None = None, + minimum_spacing: float | None = None, + maximum_spacing: float | None = None, + oversample: int = 20, +) -> SpacingSpectrum: + """Scan trial spacings for a regular comb in ``values``. + + The response at trial spacing ``dP`` is the squared normalised resultant of the + phasors ``exp(2 pi i P_j / dP)``: it reaches 1 when every value sits on one comb + and averages ``1/n`` for values with no common spacing. Because it never looks at + *consecutive* differences, a missing radial order costs it nothing — the surviving + modes still land on the comb. + + Parameters + ---------- + values : numpy.ndarray + Periods in days (or frequencies; the tool is unit-agnostic). + weights : numpy.ndarray, optional + Per-value weights, normally the mode amplitudes, so strong modes dominate. + minimum_spacing, maximum_spacing : float, optional + Trial-spacing bounds. Default to half the smallest gap and the full range. + oversample : int, default 20 + Trial-grid oversampling relative to the natural resolution ``1/range``. + + Returns + ------- + SpacingSpectrum + + Examples + -------- + >>> periods = 0.5 + 0.03 * np.arange(12) # doctest: +SKIP + >>> spacing_spectrum(periods).best_spacing # doctest: +SKIP + 0.03 + """ + v = np.ascontiguousarray(np.asarray(values, dtype=np.float64)).ravel() + v = v[np.isfinite(v)] + if v.size < 3: + raise ValueError("spacing_spectrum needs at least 3 finite values") + order = np.argsort(v, kind="stable") + v = v[order] + if weights is None: + a = np.ones(v.size, dtype=np.float64) + else: + a = np.asarray(weights, dtype=np.float64).ravel() + if a.size != order.size: + raise ValueError("weights and values must have the same length") + a = np.abs(a[order]) + if not np.any(a > 0.0): + a = np.ones(v.size, dtype=np.float64) + + span = float(v[-1] - v[0]) + if span <= 0.0: + raise ValueError("spacing_spectrum needs values with a non-zero range") + lo, hi = _default_spacing_range(v) + if minimum_spacing is not None: + lo = float(minimum_spacing) + if maximum_spacing is not None: + hi = float(maximum_spacing) + if not 0.0 < lo < hi: + raise ValueError("require 0 < minimum_spacing < maximum_spacing") + + # Uniform in inverse spacing: that is the variable the comb response is periodic in, + # so a uniform step there resolves every trial equally well. + step = 1.0 / (max(oversample, 1) * span) + u_lo, u_hi = 1.0 / hi, 1.0 / lo + n_trials = int(np.ceil((u_hi - u_lo) / step)) + 1 + if n_trials > _MAX_GRID: + # Cover the whole requested range at reduced resolution rather than silently + # truncating it. + n_trials = _MAX_GRID + step = (u_hi - u_lo) / (n_trials - 1) + u = u_lo + step * np.arange(n_trials, dtype=np.float64) + u = u[u > 0.0] + + power = _comb_response(u, v, a) + best = _pick_spacing(u, power, v, oversample) + return SpacingSpectrum( + spacing=(1.0 / u)[::-1], + power=power[::-1], + best_spacing=float(1.0 / u[best]), + best_power=float(power[best]), + n_values=int(v.size), + ) + + +def _comb_response( + inverse_spacing: FloatArray, values: FloatArray, weights: FloatArray +) -> FloatArray: + """``|sum_j a_j exp(2 pi i u x_j)|^2 / (sum_j a_j)^2`` on the trial grid.""" + total = float(weights.sum()) + power = np.empty(inverse_spacing.size, dtype=np.float64) + block = max(1, _BLOCK_ELEMS // max(1, values.size)) + for start in range(0, inverse_spacing.size, block): + stop = min(start + block, inverse_spacing.size) + angle = (2.0 * np.pi) * inverse_spacing[start:stop, None] * values[None, :] + real = (np.cos(angle) * weights).sum(axis=1) + imag = (np.sin(angle) * weights).sum(axis=1) + power[start:stop] = (real * real + imag * imag) / (total * total) + return power + + +def _comb_members( + values: FloatArray, inverse_spacing: float, tolerance: float +) -> FloatArray: + """The values that lie on the comb of spacing ``1/inverse_spacing``. + + The comb's own offset is read off the resultant's phase, so this does not assume the + teeth pass through zero, and membership is then a plain phase-residual cut. + """ + phase = values * inverse_spacing + offset = float(np.angle(np.sum(np.exp(2j * np.pi * phase)))) / (2.0 * np.pi) + residual = np.abs(((phase - offset + 0.5) % 1.0) - 0.5) + return values[residual < tolerance] + + +def _pick_spacing( + inverse_spacing: FloatArray, + power: FloatArray, + values: FloatArray, + oversample: int, +) -> int: + """Index of the reported comb peak, promoted past any sub-multiple of itself. + + Every value on a comb of spacing ``dP`` also sits on a comb of ``dP/m``, so a + regular pattern responds just as strongly at all its sub-multiples and a plain + ``argmax`` picks between them arbitrarily — reporting ``dP/2`` as the period spacing + would halve the inferred buoyancy radius. + + The ambiguity is broken by testing the integer *multiples* of the winning spacing. + Widening a comb by ``m`` keeps every tooth only if the true spacing was ``m`` + times wider; otherwise it drops all but every ``m``-th value and the response + collapses. So a response at ``m·dP`` still a large fraction of the peak + (:data:`_SUBMULTIPLE_RATIO`) means ``dP`` was the sub-multiple, and the widest such + spacing is the one reported. + + ``power`` selects the peak — amplitude-weighted if the caller weighted it, which is + what suppresses low-amplitude non-members. The promotion, though, is decided on the + *unweighted* response of that peak's **own members**: it asks "do the modes this + comb explains also land on the wider one?". Neither a wide amplitude spread — under + which a weighted response barely notices a widened comb dropping the weak teeth, and + would promote to a *multiple* of the truth — nor unrelated contaminating peaks, + which drag an all-values unweighted response around, can distort the decision. + """ + best = int(np.argmax(power)) + members = _comb_members(values, inverse_spacing[best], _COMB_MEMBER_TOL) + if members.size < 3: + return best + counting = _comb_response(inverse_spacing, members, np.ones_like(members)) + peak = float(counting[best]) + if peak <= 0.0: + return best + half_width = max(1, int(oversample)) + chosen = best + for multiple in range(2, _MAX_SUBMULTIPLE + 1): + target = inverse_spacing[best] / multiple + if target < inverse_spacing[0]: + break # a spacing that wide is outside the searched range + index = int(np.searchsorted(inverse_spacing, target)) + lo = max(0, index - half_width) + hi = min(int(inverse_spacing.size), index + half_width + 1) + if lo >= hi: + continue + local = lo + int(np.argmax(counting[lo:hi])) + if counting[local] >= _SUBMULTIPLE_RATIO * peak: + chosen = local + return chosen + + +def _fit_tilt( + midpoints: FloatArray, spacings: FloatArray +) -> tuple[float, float, float]: + """Least-squares ``dP = intercept + slope*P``; gives ``(intercept, slope, rms)``. + + Falls back to a flat pattern when there are too few points to constrain a tilt. + """ + if midpoints.size == 0: + return 0.0, 0.0, float("nan") + if midpoints.size < 3: + mean = float(np.mean(spacings)) + return mean, 0.0, float(np.std(spacings)) + design = np.stack([np.ones_like(midpoints), midpoints], axis=1) + solution, *_ = np.linalg.lstsq(design, spacings, rcond=None) + residual = spacings - design @ solution + return ( + float(solution[0]), + float(solution[1]), + float(np.sqrt(np.mean(residual**2))), + ) + + +def _step_counts(difference: FloatArray, predicted: FloatArray) -> FloatArray: + """How many radial orders each observed step spans, at least one. + + ``predicted`` is the tilted model ``a + b P`` evaluated at the step midpoints. Only + ``a + b P`` over the *observed* range has to be positive — ``a`` alone is a nuisance + parameter of the parameterisation and is legitimately negative for a steeply tilted + series — so a non-positive prediction is treated as "cannot tell" (one order) rather + than allowed to produce a negative step count. + """ + with np.errstate(divide="ignore", invalid="ignore"): + ratio = np.where(predicted > 0.0, difference / np.where( + predicted > 0.0, predicted, 1.0 + ), 1.0) + return np.maximum(np.round(ratio), 1.0) + + +def _longest_chain( + values: FloatArray, intercept: float, slope: float, tolerance: float, max_gap: int +) -> list[int]: + """Longest chain of ascending values consistent with ``dP = intercept + slope*P``. + + A dynamic programme over the sorted values: ``score[j]`` is the length of the best + chain ending at ``j``, and a step ``i -> j`` is admissible when the observed + difference is within ``tolerance`` (a fraction of the local spacing) of an integer + multiple ``m <= max_gap`` of it. Bridging a missing radial order therefore costs a + step but not a member. + """ + n = int(values.size) + score = np.ones(n, dtype=np.int64) + parent = np.full(n, -1, dtype=np.int64) + for j in range(1, n): + for i in range(j): + difference = float(values[j] - values[i]) + if difference <= 0.0: + continue + predicted = intercept + slope * 0.5 * float(values[i] + values[j]) + if predicted <= 0.0: + continue + steps = int(round(difference / predicted)) + if steps < 1 or steps > max_gap: + continue + if abs(difference - steps * predicted) > tolerance * predicted: + continue + if score[i] + 1 > score[j]: + score[j] = score[i] + 1 + parent[j] = i + end = int(np.argmax(score)) + chain: list[int] = [] + while end >= 0: + chain.append(end) + end = int(parent[end]) + chain.reverse() + return chain + + +def find_period_spacing( + periods: FloatArray, + amplitudes: FloatArray | None = None, + *, + settings: SpacingSettings | None = None, + spacing: float | None = None, +) -> PeriodSpacingSeries | None: + """Extract the longest tilted period-spacing series from a list of periods. + + The spacing is first located with :func:`spacing_spectrum` (unless supplied), then + the chain search and the tilt fit are iterated: each pass re-fits + ``dP(P) = a + b P`` to the current chain and re-runs the search with the improved + model, so a rotationally tilted pattern is recovered even though the initial guess + was a single constant spacing. + + Parameters + ---------- + periods : numpy.ndarray + Mode periods in days (any order). + amplitudes : numpy.ndarray, optional + Mode amplitudes; used to weight the comb search. + settings : SpacingSettings, optional + Search controls (bounds, tolerance, bridged gap, minimum length, degree). + spacing : float, optional + Skip the comb search and start from this spacing (days). + + Returns + ------- + PeriodSpacingSeries or None + ``None`` when no chain reaches ``settings.min_length``. + + Examples + -------- + >>> series = find_period_spacing(solution.period) # doctest: +SKIP + >>> print(series.summary()) # doctest: +SKIP + """ + cfg = settings or SpacingSettings() + p = np.ascontiguousarray(np.asarray(periods, dtype=np.float64)).ravel() + finite = np.isfinite(p) & (p > 0.0) + weights = None + if amplitudes is not None: + amp = np.asarray(amplitudes, dtype=np.float64).ravel() + if amp.size != p.size: + raise ValueError("amplitudes and periods must have the same length") + finite &= np.isfinite(amp) + weights = amp[finite] + original = np.flatnonzero(finite) + p = p[finite] + if p.size < cfg.min_length: + return None + order = np.argsort(p, kind="stable") + p = p[order] + original = original[order] + if weights is not None: + weights = weights[order] + + guess = spacing + if guess is None: + comb = spacing_spectrum( + p, + weights=weights if cfg.amplitude_weighted else None, + minimum_spacing=cfg.minimum_spacing, + maximum_spacing=cfg.maximum_spacing, + oversample=cfg.oversample, + ) + guess = comb.best_spacing + if not np.isfinite(guess) or guess <= 0.0: + return None + + intercept, slope = float(guess), 0.0 + chain: list[int] = [] + for _ in range(4): + candidate = _longest_chain(p, intercept, slope, cfg.tolerance, cfg.max_gap) + if len(candidate) < 2: + break + chain = candidate + members = p[chain] + difference = np.diff(members) + midpoints = 0.5 * (members[:-1] + members[1:]) + steps = _step_counts(difference, intercept + slope * midpoints) + if float(steps.min()) >= 2.0: + # Not one pair in the chain is a consecutive radial order, which no real + # series looks like: the working spacing is a sub-multiple of the true one. + factor = float(steps.min()) + intercept *= factor + slope *= factor + continue + intercept, slope, _ = _fit_tilt(midpoints, difference / steps) + if len(chain) < cfg.min_length: + return None + + members = p[chain] + difference = np.diff(members) + midpoints = 0.5 * (members[:-1] + members[1:]) + steps = _step_counts(difference, intercept + slope * midpoints) + unit = difference / steps + intercept, slope, rms = _fit_tilt(midpoints, unit) + mean_spacing = float(np.mean(unit)) + return PeriodSpacingSeries( + indices=tuple(int(original[i]) for i in chain), + periods=members, + spacings=difference, + multiplicity=steps, + midpoints=midpoints, + mean_spacing=mean_spacing, + slope=slope, + intercept=intercept, + rms=rms, + ell=cfg.ell, + buoyancy_radius=buoyancy_radius(mean_spacing, cfg.ell), + ) + + +__all__ = [ + "PeriodSpacingSeries", + "SpacingSpectrum", + "buoyancy_radius", + "echelle", + "find_period_spacing", + "spacing_spectrum", +] diff --git a/src/cuperiod/prewhiten/spectrum.py b/src/cuperiod/prewhiten/spectrum.py new file mode 100644 index 0000000..4011d76 --- /dev/null +++ b/src/cuperiod/prewhiten/spectrum.py @@ -0,0 +1,912 @@ +"""Amplitude spectra — the search statistic that drives pre-whitening. + +Classical-pulsator work is done in *amplitude*, not power: a δ Scuti mode is quoted in +millimagnitudes, and the Breger signal-to-noise criterion compares a peak's amplitude +with the mean amplitude of the surrounding residual spectrum. This module computes the +least-squares amplitude spectrum + +.. math:: + + y(t) \\approx c_0 + a\\cos(2\\pi f \\Delta t) + b\\sin(2\\pi f \\Delta t), + \\qquad A(f) = \\sqrt{a^2 + b^2}, + +on a uniform frequency grid, reusing cuPeriod's NUFFT machinery: the six weighted +trigonometric sums of the Zechmeister-Kürster normal equations are exactly the sums the +GLS periodogram already evaluates with one type-1 transform each. + +The load-bearing observation for pre-whitening is that **three of those sums do not +depend on the data**. ``cc``, ``ss`` and ``cs`` are properties of the sampling and the +weights alone, so :class:`SpectrumEngine` computes them once and every subsequent +iteration of the extraction loop costs a *single* NUFFT of the current residuals. A +50-frequency solution therefore costs ~52 transforms rather than ~150. + +Backends +-------- +cufinufft + NVIDIA fast path; the plan and its ``setpts`` are built once and reused across every + pre-whitening iteration (only the strengths change). +finufft + CPU fast path, same plan reuse. The default when no CUDA device is present. +torch + Portable direct trig-sum path (AMD/Intel/Apple/CPU), ``O(N \\cdot n_f)`` but + device-agnostic. +numpy + The same direct path on the host — the transparent reference implementation. +""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Final, Literal + +import numpy as np + +from cuperiod.core._arrayapi import ( + array_namespace, + device_ref, + resolve_precision, + resolve_torch_device, + to_device_array, + to_host, +) +from cuperiod.core._typing import FloatArray, IntArray +from cuperiod.core.backend import ( + available_backends, + ensure_cuda_dll_path, + torch_available, + torch_gpu_available, +) +from cuperiod.core.errors import BackendUnavailableError, InsufficientDataError +from cuperiod.core.grid import GridSpec +from cuperiod.core.peaks import local_maxima + +#: How the trigonometric sums are turned into an amplitude. +Normalization = Literal["lsq", "dft"] + +#: Robust/classical estimators for the local noise level of a spectrum. +NoiseEstimator = Literal["mean", "median"] + +#: Concrete backends the amplitude spectrum can run on. +SPECTRUM_BACKENDS: Final = ("finufft", "cufinufft", "torch", "numpy") + +#: Elements per transient ``(chunk, N)`` matrix in the direct path (64 MB float64). +_DIRECT_CHUNK_ELEMS: Final = 1 << 23 + +#: Default NUFFT relative tolerance (matches the GLS default). +DEFAULT_EPS: Final = 1e-9 + + +def weighted_epoch(time: FloatArray, weight: FloatArray | None = None) -> float: + """The reference epoch that decorrelates phase from frequency. + + A sinusoid's phase and frequency are correlated through the reference epoch: + shifting + the epoch by ``dt`` shifts the phase by ``2 pi f dt``, so an epoch far from the data + makes the phase uncertainty balloon with the frequency uncertainty. The correlation + vanishes exactly at the weighted mean of the observation times, which is therefore + the epoch cuPeriod references phases to (and, incidentally, the one that keeps + ``t - t_ref`` smallest for real-scale Julian dates). + + Parameters + ---------- + time : numpy.ndarray + Observation times (days). + weight : numpy.ndarray, optional + Per-point weights; uniform when omitted. + + Returns + ------- + float + The reference epoch in days. + """ + t = np.asarray(time, dtype=np.float64) + if t.size == 0: + return 0.0 + if weight is None: + return float(np.mean(t)) + w = np.asarray(weight, dtype=np.float64) + total = float(w.sum()) + return float(np.dot(w, t) / total) if total > 0.0 else float(np.mean(t)) + + +def resolve_spectrum_backend(requested: str = "auto") -> str: + """Resolve ``auto``/``cpu``/``gpu``/concrete to a runnable spectrum backend. + + Mirrors :meth:`cuperiod.methods.base.PeriodogramMethod.resolve_backend`: ``"auto"`` + prefers the NVIDIA cufinufft fast path, then a non-CPU torch device, then the + finufft CPU path, and finally the pure-numpy reference. + + Parameters + ---------- + requested : str, default "auto" + ``"auto"``, ``"cpu"``, ``"gpu"``, ``"torch"``, ``"torch:"``, or one of + :data:`SPECTRUM_BACKENDS`. + + Returns + ------- + str + A concrete, available backend name. + + Raises + ------ + BackendUnavailableError + If the request cannot be satisfied here. + """ + available = available_backends() + if requested == "auto": + if "cufinufft" in available: + return "cufinufft" + if torch_gpu_available(): + return "torch" + return "finufft" if "finufft" in available else "numpy" + if requested == "cpu": + return "finufft" if "finufft" in available else "numpy" + if requested == "gpu": + if "cufinufft" in available: + return "cufinufft" + if torch_gpu_available(): + return "torch" + raise BackendUnavailableError( + "pre-whitening: no GPU backend available (need the [gpu] extra and a CUDA " + "device, or the [torch] extra and a CUDA/ROCm/MPS/XPU device)" + ) + if requested == "torch" or requested.startswith("torch:"): + if not torch_available(): + raise BackendUnavailableError( + "pre-whitening: backend 'torch' needs the [torch] extra " + "(pip install 'cuperiod[torch]')" + ) + return requested + # GLS names astropy as its exact-but-slow reference; the amplitude spectrum's + # equivalent is the direct numpy path. + if requested == "astropy": + return "numpy" + if requested not in SPECTRUM_BACKENDS: + raise BackendUnavailableError( + f"pre-whitening: unknown backend {requested!r}; " + f"choose from {SPECTRUM_BACKENDS}" + ) + if requested in {"finufft", "cufinufft"} and requested not in available: + raise BackendUnavailableError( + f"pre-whitening: backend {requested!r} is not available here" + ) + return requested + + +# --- noise / peak utilities --------------------------------------------------- + + +def noise_level( + frequency: FloatArray, + amplitude: FloatArray, + at: float, + *, + window: float = 1.0, + estimator: NoiseEstimator = "mean", + min_samples: int = 25, +) -> float: + """Local noise level of an amplitude spectrum around ``at``. + + The Breger et al. (1993) signal-to-noise criterion divides a peak amplitude by the + *average amplitude* of the residual spectrum in a box centred on that frequency; + this is that average. When the box holds fewer than ``min_samples`` grid points (a + narrow window on a coarse grid, or a box clipped by the edge of the grid), the + nearest ``min_samples`` samples are used instead so the estimate never rests on a + handful of points. + + Parameters + ---------- + frequency, amplitude : numpy.ndarray + The spectrum, ascending in frequency. + at : float + Centre of the box (cycles/day). + window : float, default 1.0 + Half-width of the box (cycles/day). + estimator : {"mean", "median"}, default "mean" + ``"mean"`` reproduces the classical Breger noise; ``"median"`` is robust to + residual peaks left inside the box. + min_samples : int, default 25 + Minimum number of grid samples averaged. + + Returns + ------- + float + The local noise amplitude (NaN if the spectrum is empty). + """ + n = int(frequency.size) + if n == 0: + return float("nan") + lo = int(np.searchsorted(frequency, at - window, side="left")) + hi = int(np.searchsorted(frequency, at + window, side="right")) + if hi - lo < min(min_samples, n): + centre = int(np.searchsorted(frequency, at)) + half = max(1, min(min_samples, n) // 2) + lo = max(0, min(centre - half, n - min(min_samples, n))) + hi = min(n, lo + min(min_samples, n)) + box = amplitude[lo:hi] + box = box[np.isfinite(box)] + if box.size == 0: + return float("nan") + return float(np.mean(box) if estimator == "mean" else np.median(box)) + + +def _blocked_mask( + frequency: FloatArray, exclude: FloatArray, separation: float +) -> np.ndarray: + """Boolean mask of grid samples within ``separation`` of any excluded frequency.""" + blocked = np.zeros(frequency.size, dtype=bool) + if exclude.size == 0 or separation <= 0.0: + return blocked + lo = np.searchsorted(frequency, exclude - separation, side="left") + hi = np.searchsorted(frequency, exclude + separation, side="right") + for a, b in zip(lo, hi, strict=True): + blocked[int(a) : int(b)] = True + return blocked + + +def _candidate_indices(amplitude: FloatArray) -> IntArray: + """Interior local maxima plus boundary samples that exceed their one neighbour.""" + candidates = local_maxima(amplitude) + n = int(amplitude.size) + edges: list[int] = [] + if n == 1: + edges.append(0) + elif n >= 2: + if amplitude[0] >= amplitude[1]: + edges.append(0) + if amplitude[-1] > amplitude[-2]: + edges.append(n - 1) + if edges: + candidates = np.concatenate([candidates, np.asarray(edges, dtype=np.int64)]) + return candidates + + +@dataclass(frozen=True) +class AmplitudeSpectrum: + """A least-squares amplitude spectrum on a uniform frequency grid. + + Attributes + ---------- + frequency : numpy.ndarray + Trial frequencies (cycles/day), ascending and uniformly spaced. + amplitude : numpy.ndarray + Best-fit sinusoid amplitude at each frequency, in the units of the input. + phase : numpy.ndarray + Best-fit phase in radians for the convention + ``A * sin(2*pi*f*(t - t_ref) + phase)``, wrapped to ``[0, 2*pi)``. + power : numpy.ndarray + The equivalent normalized Lomb-Scargle power (0-1), handy for false-alarm + probabilities. Approximate when ``normalization="dft"``. + t_ref : float + Time origin the phases are referenced to (days). + backend : str + Concrete backend that produced the spectrum. + normalization : {"lsq", "dft"} + Amplitude convention (see :class:`SpectrumEngine`). + n_samples : int + Number of light-curve points used. + baseline : float + Time span of the light curve (days). + """ + + frequency: FloatArray + amplitude: FloatArray + phase: FloatArray + power: FloatArray + t_ref: float + backend: str + normalization: str + n_samples: int + baseline: float + + @property + def size(self) -> int: + """Number of grid samples.""" + return int(self.frequency.size) + + @property + def period(self) -> FloatArray: + """The grid as periods in days.""" + with np.errstate(divide="ignore"): + return 1.0 / self.frequency + + @property + def rayleigh(self) -> float: + """Rayleigh frequency resolution ``1/baseline`` (cycles/day).""" + return 1.0 / self.baseline if self.baseline > 0.0 else float("inf") + + def peak_index( + self, + *, + exclude: FloatArray | None = None, + separation: float = 0.0, + ) -> int | None: + """Index of the highest peak, skipping neighbourhoods of ``exclude``. + + Parameters + ---------- + exclude : numpy.ndarray, optional + Frequencies whose ``+/- separation`` neighbourhood is off limits (the + already-extracted components). + separation : float, default 0.0 + Exclusion half-width in cycles/day. + + Returns + ------- + int or None + Grid index of the tallest admissible peak, or ``None`` if there is none. + """ + if self.size == 0: + return None + candidates = _candidate_indices(self.amplitude) + if candidates.size == 0: + candidates = np.arange(self.size, dtype=np.int64) + finite = np.isfinite(self.amplitude[candidates]) + candidates = candidates[finite] + if candidates.size == 0: + return None + if exclude is not None and exclude.size and separation > 0.0: + blocked = _blocked_mask(self.frequency, exclude, separation) + candidates = candidates[~blocked[candidates]] + if candidates.size == 0: + return None + return int(candidates[int(np.argmax(self.amplitude[candidates]))]) + + def refine_peak(self, index: int) -> tuple[float, float]: + """Sub-grid ``(frequency, amplitude)`` at ``index`` by parabolic interpolation. + + A three-point parabola through the peak sample and its neighbours locates the + apex to a small fraction of the grid step, which is a much better starting + point for the non-linear fit than the grid sample itself. + """ + i = int(index) + f = float(self.frequency[i]) + a = float(self.amplitude[i]) + if i <= 0 or i >= self.size - 1: + return f, a + y0, y1, y2 = (float(self.amplitude[j]) for j in (i - 1, i, i + 1)) + denom = y0 - 2.0 * y1 + y2 + if denom >= 0.0 or not np.isfinite(denom): + return f, a + shift = 0.5 * (y0 - y2) / denom + if not (-1.0 < shift < 1.0): + return f, a + step = float(self.frequency[i + 1] - self.frequency[i]) + apex = y1 - 0.25 * (y0 - y2) * shift + return f + shift * step, max(apex, a) + + def amplitude_at(self, frequency: FloatArray | float) -> Any: + """Amplitude at the grid sample(s) nearest ``frequency``. + + The direct, single-frequency reading of the spectrum — what a marker drawn on + this curve sits at, and the reference the extraction compares each fitted + amplitude against (see :attr:`~cuperiod.Sinusoid.amplitude_ratio`). + + Parameters + ---------- + frequency : float or numpy.ndarray + Frequencies in cycles/day. Values outside the grid clamp to its ends. + + Returns + ------- + float or numpy.ndarray + Matching the input's scalar-or-array shape. + """ + wanted = np.asarray(frequency, dtype=np.float64) + if self.size == 0: + empty = np.full(wanted.shape, np.nan) + return empty if np.ndim(frequency) else float("nan") + right = np.clip(np.searchsorted(self.frequency, wanted), 0, self.size - 1) + left = np.clip(right - 1, 0, self.size - 1) + nearer_left = np.abs(self.frequency[left] - wanted) <= np.abs( + self.frequency[right] - wanted + ) + out = self.amplitude[np.where(nearer_left, left, right)] + return out if np.ndim(frequency) else float(out) + + def noise_at( + self, + frequency: float, + *, + window: float = 1.0, + estimator: NoiseEstimator = "mean", + min_samples: int = 25, + ) -> float: + """Local noise amplitude around ``frequency`` (see :func:`noise_level`).""" + return noise_level( + self.frequency, + self.amplitude, + frequency, + window=window, + estimator=estimator, + min_samples=min_samples, + ) + + def downsample(self, n_points: int = 2000) -> tuple[FloatArray, FloatArray]: + """Peak-preserving ``(frequency, amplitude)`` downsample for plots/storage.""" + from cuperiod.core.peaks import peak_preserving_downsample + + freq, amp = peak_preserving_downsample( + self.frequency, self.amplitude, n_points + ) + return freq.astype(np.float64), amp.astype(np.float64) + + +# --- trig-sum kernels --------------------------------------------------------- + + +def _wrapped_angles(xp: Any, tau: Any, df: float) -> Any: + """``2*pi*df*tau`` wrapped to ``[-pi, pi)`` — the NUFFT nonuniform points.""" + x = (2.0 * np.pi * df) * tau + return xp.mod(x + np.pi, 2.0 * np.pi) - np.pi + + +def _direct_trig_sums( + xp: Any, tau: Any, strengths: Any, f0: float, df: float, nf: int, chunk: int +) -> tuple[Any, Any]: + """``(sum_j s_j cos(2*pi*f_k*tau_j), sum_j s_j sin(...))`` by direct evaluation. + + Pure array-API, so it runs unchanged on numpy, cupy and torch (any device). The + frequency loop is chunked so the transient ``(chunk, N)`` angle matrix stays bounded + regardless of the light-curve length. + """ + dtype = tau.dtype + dev = device_ref(tau) + n_points = int(tau.shape[0]) + chunk = max(1, min(chunk, _DIRECT_CHUNK_ELEMS // max(1, n_points))) + freqs = f0 + df * xp.arange(nf, dtype=dtype, device=dev) + cos_sum = xp.empty(nf, dtype=dtype, device=dev) + sin_sum = xp.empty(nf, dtype=dtype, device=dev) + row = strengths[None, :] + two_pi = 2.0 * float(np.pi) + for start in range(0, nf, chunk): + stop = min(start + chunk, nf) + ang = (two_pi * freqs[start:stop])[:, None] * tau[None, :] + cos_sum[start:stop] = xp.sum(row * xp.cos(ang), axis=1) + sin_sum[start:stop] = xp.sum(row * xp.sin(ang), axis=1) + return cos_sum, sin_sum + + +class SpectrumEngine: + """Reusable amplitude-spectrum evaluator for one light curve's sampling. + + The sampling (``time``), the weights (``error``) and the frequency grid are fixed at + construction; :meth:`spectrum` then evaluates any number of *value* arrays on them. + Everything that depends only on the sampling — the NUFFT plan and its point sort, + and the ``cc``/``ss``/``cs`` window sums of the normal equations — is computed once, + so each call costs a single transform. That is what makes iterative pre-whitening + cheap. + + Parameters + ---------- + time : numpy.ndarray + Observation times in days (finite, at least three points spanning a non-zero + baseline). + error : numpy.ndarray, optional + 1-sigma uncertainties. ``None`` gives uniform weights. + grid : GridSpec + A **uniform frequency** grid (``kind="frequency"``, ``uniform=True``). + normalization : {"lsq", "dft"}, default "lsq" + ``"lsq"`` solves the weighted least-squares normal equations at every trial + frequency — the statistically correct amplitude for irregular sampling. + ``"dft"`` is the classical Deeming amplitude ``2|sum w y e^{2 pi i f t}|`` used + by Period04; cheaper to set up and identical for even, unweighted sampling. + backend : str, default "auto" + See :func:`resolve_spectrum_backend`. + device, precision : str + Torch device and compute precision (see :class:`cuperiod.GLSSettings`). + eps : float, default 1e-9 + NUFFT relative tolerance. + freq_batch : int, default 4096 + Frequency chunk of the direct (torch/numpy) path. + t_ref : float, optional + Phase reference epoch. Defaults to :func:`weighted_epoch`. + + Notes + ----- + One instance is not thread-safe (a cufinufft plan holds device state). Build one per + worker. + """ + + def __init__( + self, + time: FloatArray, + error: FloatArray | None = None, + *, + grid: GridSpec, + normalization: Normalization = "lsq", + backend: str = "auto", + device: str = "auto", + precision: str = "auto", + eps: float = DEFAULT_EPS, + freq_batch: int = 4096, + t_ref: float | None = None, + ) -> None: + t = np.ascontiguousarray(np.asarray(time, dtype=np.float64)) + if t.ndim != 1 or t.size < 3: + raise InsufficientDataError( + "pre-whitening: need at least 3 finite points to build a spectrum" + ) + if grid.kind != "frequency" or not grid.uniform: + raise ValueError( + "SpectrumEngine needs a uniform frequency grid; build one with " + "cuperiod.uniform_frequency_grid(...)" + ) + f0, df, nf = grid.uniform_frequency_params() + if nf <= 0 or df <= 0.0: + raise ValueError("SpectrumEngine needs a non-empty, increasing grid") + + self.n_samples = int(t.size) + self.baseline = float(t.max() - t.min()) + self.normalization: Normalization = normalization + self.backend = resolve_spectrum_backend(backend) + self.frequency: FloatArray = f0 + df * np.arange(nf, dtype=np.float64) + self._f0, self._df, self._nf = f0, df, int(nf) + self._eps = float(eps) + self._freq_batch = int(freq_batch) + + if error is None: + w = np.full(t.shape, 1.0 / t.size, dtype=np.float64) + else: + dy = np.ascontiguousarray(np.asarray(error, dtype=np.float64)) + if dy.shape != t.shape: + raise ValueError("error and time must have the same length") + w = 1.0 / (dy * dy) + w /= w.sum() + self.t_ref = weighted_epoch(t, w) if t_ref is None else float(t_ref) + self._tau = t - self.t_ref + self._weight: FloatArray = w + + self._plan: Any = None + self._plan_mod: Any = None + self._xp: Any = None + self._tau_dev: Any = None + self._torch_dtype: Any = None + self._device = "cpu" + self._precision = "float64" + self._window_sums: tuple[FloatArray, FloatArray] | None = None + self._setup(device, precision) + # The weights sum to 1, so a well-conditioned frequency has det ~ 0.25 and + # rounding noise ~eps. Anything far below that is a degenerate design (a zero + # frequency, or sampling that cannot separate cosine from sine there) and is + # reported as zero amplitude rather than as a huge spurious peak. + self._det_floor = 1e-10 if self._precision == "float64" else 1e-4 + self._cc, self._ss, self._cs, self._det = self._window_terms() + + # -- setup ------------------------------------------------------------------- + def _setup(self, device: str, precision: str) -> None: + """Build the per-backend state that depends only on the sampling.""" + backend = self.backend + if backend in {"finufft", "cufinufft"}: + self._plan, self._plan_mod = self._make_plan(self._df, self._f0) + return + if backend == "numpy": + self._tau_dev = self._tau + self._xp = array_namespace(self._tau) + return + # torch (any device) + import torch + + self._device = resolve_torch_device(backend, device) + self.backend = f"torch:{self._device}" + self._precision = resolve_precision(precision, self._device) + self._torch_dtype = ( + torch.float32 if self._precision == "float32" else torch.float64 + ) + self._tau_dev = to_device_array( + self._tau, device=self._device, dtype=self._torch_dtype + ) + self._xp = array_namespace(self._tau_dev) + + def _import_nufft(self) -> tuple[Any, Any]: + """``(plan_factory, array_namespace)`` for the resolved NUFFT backend.""" + if self.backend == "finufft": + import finufft + + return finufft.Plan, np + ensure_cuda_dll_path() + import cufinufft + import cupy as cp + + return cufinufft.Plan, cp + + def _make_plan(self, df: float, f0: float) -> tuple[Any, Any]: + """A type-1 NUFFT plan with ``setpts`` done, plus its modulation array. + + finufft puts output index ``k`` at mode ``m = k - nf//2``; modulating the + strengths by ``exp(2j*pi*f_center*tau)`` with ``f_center = f0 + (nf//2)*df`` + maps index ``k`` onto frequency ``f0 + k*df``. + """ + nf = self._nf + plan_factory, xp = self._import_nufft() + if self._tau_dev is None: + self._xp = xp + self._tau_dev = xp.asarray(self._tau) + plan = plan_factory( + 1, (nf,), n_trans=1, eps=self._eps, isign=1, dtype="complex128" + ) + plan.setpts(_wrapped_angles(xp, self._tau_dev, df)) + mod = xp.exp(2j * np.pi * (f0 + (nf // 2) * df) * self._tau_dev) + return plan, mod + + def _plan_sums( + self, plan: Any, mod: Any, strengths: FloatArray + ) -> tuple[FloatArray, FloatArray]: + """Execute ``plan`` for ``strengths`` and split the result into cos/sin sums.""" + out = plan.execute((self._xp.asarray(strengths) * mod).astype(np.complex128)) + out = out[0] if out.ndim == 2 else out + return to_host(out.real), to_host(out.imag) + + def _base_sums(self, strengths: FloatArray) -> tuple[FloatArray, FloatArray]: + """Cos/sin sums of ``strengths`` on the base grid, returned on the host.""" + if self._plan is not None: + return self._plan_sums(self._plan, self._plan_mod, strengths) + cos_sum, sin_sum = _direct_trig_sums( + self._xp, + self._tau_dev, + self._to_dev(strengths), + self._f0, + self._df, + self._nf, + self._freq_batch, + ) + return to_host(cos_sum), to_host(sin_sum) + + def _doubled_sums(self, strengths: FloatArray) -> tuple[FloatArray, FloatArray]: + """Cos/sin sums of ``strengths`` on the doubled grid ``2*f_k`` (host).""" + if self._plan is not None: + plan, mod = self._make_plan(2.0 * self._df, 2.0 * self._f0) + return self._plan_sums(plan, mod, strengths) + cos_sum, sin_sum = _direct_trig_sums( + self._xp, + self._tau_dev, + self._to_dev(strengths), + 2.0 * self._f0, + 2.0 * self._df, + self._nf, + self._freq_batch, + ) + return to_host(cos_sum), to_host(sin_sum) + + def _to_dev(self, host: FloatArray) -> Any: + """Move a host float64 array onto the compute device at the working dtype.""" + if self._torch_dtype is not None: + return to_device_array(host, device=self._device, dtype=self._torch_dtype) + return self._xp.asarray(host) + + def _window_terms( + self, + ) -> tuple[FloatArray, FloatArray, FloatArray, FloatArray]: + """The data-independent ``cc``, ``ss``, ``cs`` sums and their determinant. + + These are the Gram entries of the floating-mean design at every trial frequency + — functions of the observation times and weights only — so the extraction loop + pays for them exactly once. + """ + nf = self._nf + if self.normalization == "dft": + zero = np.zeros(nf, dtype=np.float64) + return zero, zero, zero, zero + c, s = self._base_sums(self._weight) + self._window_sums = (c, s) # exactly the spectral window; see :meth:`window` + c2, s2 = self._doubled_sums(self._weight) + cc = 0.5 * (1.0 + c2) - c * c + ss = 0.5 * (1.0 - c2) - s * s + cs = 0.5 * s2 - c * s + det = cc * ss - cs * cs + return cc, ss, cs, det + + # -- evaluation -------------------------------------------------------------- + def spectrum(self, values: FloatArray) -> AmplitudeSpectrum: + """Amplitude spectrum of ``values`` on this engine's sampling and grid. + + Parameters + ---------- + values : numpy.ndarray + Brightness values aligned with the ``time`` this engine was built from — + typically the current pre-whitening residuals. + + Returns + ------- + AmplitudeSpectrum + """ + y = np.ascontiguousarray(np.asarray(values, dtype=np.float64)) + if y.shape != self._tau.shape: + raise ValueError( + f"values length {y.size} does not match the engine's " + f"{self._tau.size} time samples" + ) + w = self._weight + y_mean = float(np.dot(w, y)) + centred = y - y_mean + yy = float(np.dot(w, centred * centred)) + yc, ys = self._base_sums(w * centred) + + if self.normalization == "dft": + a = 2.0 * yc + b = 2.0 * ys + else: + det = self._det + safe = det > self._det_floor + inv = np.where(safe, 1.0 / np.where(safe, det, 1.0), 0.0) + a = (self._ss * yc - self._cs * ys) * inv + b = (self._cc * ys - self._cs * yc) * inv + + amplitude = np.hypot(a, b) + phase = np.mod(np.arctan2(a, b), 2.0 * np.pi) + if yy > 0.0: + power = np.clip((a * yc + b * ys) / yy, 0.0, 1.0) + else: + power = np.zeros_like(amplitude) + bad = ~np.isfinite(amplitude) + if bad.any(): + amplitude = np.where(bad, 0.0, amplitude) + phase = np.where(bad, 0.0, phase) + power = np.where(bad, 0.0, power) + return AmplitudeSpectrum( + frequency=self.frequency, + amplitude=amplitude, + phase=phase, + power=power, + t_ref=self.t_ref, + backend=self.backend, + normalization=self.normalization, + n_samples=self.n_samples, + baseline=self.baseline, + ) + + def window(self) -> AmplitudeSpectrum: + """The spectral window ``|W(f)|`` of this sampling, on the engine's grid. + + The window function :math:`W(f) = \\sum_j w_j e^{2\\pi i f \\Delta t_j}` + is what convolves the true spectrum when the sampling is irregular: every real + peak is dressed with the window's sidelobes, so a candidate frequency sitting + where a stronger component's window has a lobe (classically at ±1 cycle/day for + single-site ground-based data) is suspect. Period04 displays it for exactly + this reason, and comparing a doubtful peak against the window is the standard + alias check before believing a close pair. + + The returned object reuses :class:`AmplitudeSpectrum`: ``amplitude`` is + ``|W(f)|`` (dimensionless, ``|W| <= 1``, and ``|W| -> 1`` as ``f -> 0``), + ``phase`` is ``arg W(f)``, and ``power`` is ``|W(f)|^2``. Costs nothing beyond + construction for the default ``"lsq"`` normalization — the sums are already + part of the cached normal equations; ``"dft"`` engines compute them on first + call (one transform, then cached). + + Returns + ------- + AmplitudeSpectrum + """ + if self._window_sums is None: + self._window_sums = self._base_sums(self._weight) + c, s = self._window_sums + amplitude = np.hypot(c, s) + return AmplitudeSpectrum( + frequency=self.frequency, + amplitude=amplitude, + phase=np.mod(np.arctan2(s, c), 2.0 * np.pi), + power=amplitude * amplitude, + t_ref=self.t_ref, + backend=self.backend, + normalization=self.normalization, + n_samples=self.n_samples, + baseline=self.baseline, + ) + + +def amplitude_spectrum( + time: FloatArray, + value: FloatArray, + error: FloatArray | None = None, + *, + grid: GridSpec, + normalization: Normalization = "lsq", + backend: str = "auto", + device: str = "auto", + precision: str = "auto", + eps: float = DEFAULT_EPS, + freq_batch: int = 4096, + t_ref: float | None = None, +) -> AmplitudeSpectrum: + """One-shot amplitude spectrum (a :class:`SpectrumEngine` used once). + + Use the engine directly when evaluating many value arrays on the same sampling — + that is what the pre-whitening loop does. + + Parameters + ---------- + time, value : numpy.ndarray + The light curve (finite points only). + error : numpy.ndarray, optional + 1-sigma uncertainties; ``None`` gives uniform weights. + grid : GridSpec + A uniform frequency grid. + normalization, backend, device, precision, eps, freq_batch, t_ref + See :class:`SpectrumEngine`. + + Returns + ------- + AmplitudeSpectrum + """ + engine = SpectrumEngine( + time, + error, + grid=grid, + normalization=normalization, + backend=backend, + device=device, + precision=precision, + eps=eps, + freq_batch=freq_batch, + t_ref=t_ref, + ) + return engine.spectrum(value) + + +def spectral_window( + time: FloatArray, + error: FloatArray | None = None, + *, + grid: GridSpec, + backend: str = "auto", + device: str = "auto", + precision: str = "auto", + eps: float = DEFAULT_EPS, + freq_batch: int = 4096, + t_ref: float | None = None, +) -> AmplitudeSpectrum: + """One-shot spectral window of a sampling (see :meth:`SpectrumEngine.window`). + + The window depends only on the observation times and weights — no brightness + values enter — so this is the diagnostic to run when deciding whether a peak in an + amplitude spectrum is real or an alias of a stronger one. + + Parameters + ---------- + time : numpy.ndarray + Observation times in days (finite points only). + error : numpy.ndarray, optional + 1-sigma uncertainties; the window is weighted exactly as the spectrum is. + grid : GridSpec + A uniform frequency grid. + backend, device, precision, eps, freq_batch, t_ref + See :class:`SpectrumEngine`. + + Returns + ------- + AmplitudeSpectrum + ``amplitude`` holds ``|W(f)| <= 1``. + + Examples + -------- + >>> grid = cup.uniform_frequency_grid(t.max() - t.min(), # doctest: +SKIP + ... maximum_frequency=5.0) + >>> window = cup.spectral_window(t, dy, grid=grid) # doctest: +SKIP + """ + engine = SpectrumEngine( + time, + error, + grid=grid, + backend=backend, + device=device, + precision=precision, + eps=eps, + freq_batch=freq_batch, + t_ref=t_ref, + ) + return engine.window() + + +__all__ = [ + "DEFAULT_EPS", + "SPECTRUM_BACKENDS", + "AmplitudeSpectrum", + "NoiseEstimator", + "Normalization", + "SpectrumEngine", + "amplitude_spectrum", + "noise_level", + "resolve_spectrum_backend", + "spectral_window", + "weighted_epoch", +] diff --git a/src/cuperiod/prewhiten/uncertainty.py b/src/cuperiod/prewhiten/uncertainty.py new file mode 100644 index 0000000..5ef1235 --- /dev/null +++ b/src/cuperiod/prewhiten/uncertainty.py @@ -0,0 +1,296 @@ +"""Uncertainties on extracted frequencies, amplitudes and phases. + +Three estimators, in increasing order of cost and decreasing order of assumption: + +``"covariance"`` (the default) + The linearised least-squares covariance ``s^2 (J^T W J)^{-1}`` of the *joint* fit, + computed by :mod:`cuperiod.prewhiten.fit`. It is the only one of the three that + accounts for correlations *between* components, which matters as soon as two + frequencies sit within a few Rayleigh widths of each other — exactly the situation + in a dense δ Scuti or g-mode spectrum. +``"analytic"`` + The closed-form expressions of Montgomery & O'Donoghue (1999) — the numbers most + pulsation papers quote. They assume an isolated sinusoid in white noise, so they are + a lower bound; useful for comparison with the literature. +``"bootstrap"`` + Resample the residuals, re-fit, and take the scatter. Makes no linearity assumption + and needs no error bars, at the price of ``n_resamples`` extra fits. + +The covariance and analytic errors can be inflated by the Schwarzenberg-Czerny (1991) +correlation factor: real photometry has residuals that are correlated point-to-point +(instrumental drifts, unresolved modes), so the *effective* number of independent +samples is smaller than ``N`` and the formal errors are optimistic. The bootstrap is +never inflated — it already resamples the residuals as they are. +""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any, Literal + +import numpy as np + +from cuperiod.core._typing import FloatArray +from cuperiod.prewhiten.fit import MultiSineFit, Refinement, fit_multisine + +#: How component uncertainties are estimated. +UncertaintyMethod = Literal["covariance", "analytic", "bootstrap"] + + +@dataclass(frozen=True) +class Uncertainties: + """1-sigma uncertainties for every component of a multi-sine solution. + + Attributes + ---------- + frequency, amplitude, phase : numpy.ndarray + Per-component 1-sigma errors (cycles/day, input units, radians). + method : str + Which estimator produced them. + correlation_factor : float + The Schwarzenberg-Czerny ``D``; errors were multiplied by ``sqrt(D)`` + (1.0 when the correction is off or the estimator is the bootstrap). + """ + + frequency: FloatArray + amplitude: FloatArray + phase: FloatArray + method: str + correlation_factor: float + + +def correlation_factor(residuals: FloatArray) -> float: + """Schwarzenberg-Czerny (1991) correlation factor ``D`` from residual sign runs. + + Counts the mean length of a run of same-sign residuals. Independent residuals give a + mean run length of exactly 2, so the return value is normalised by that: white noise + yields ``D = 1`` and correlated residuals yield ``D > 1``. Formal uncertainties are + then multiplied by ``sqrt(D)``, which is the standard prescription for reporting + realistic frequency errors from ground- and space-based photometry. + + Parameters + ---------- + residuals : numpy.ndarray + Fit residuals in observation order (they must not be re-sorted). + + Returns + ------- + float + ``D >= 1``. Returns 1.0 for fewer than three usable residuals. + """ + r = np.asarray(residuals, dtype=np.float64) + signs = np.sign(r[np.isfinite(r) & (r != 0.0)]) + if signs.size < 3: + return 1.0 + n_runs = 1 + int(np.count_nonzero(np.diff(signs) != 0.0)) + mean_run = float(signs.size) / float(n_runs) + return max(mean_run / 2.0, 1.0) + + +def analytic_uncertainties( + n_samples: int, + baseline: float, + residual_sigma: float, + amplitude: FloatArray, +) -> tuple[FloatArray, FloatArray, FloatArray]: + """Montgomery & O'Donoghue (1999) analytic errors for isolated sinusoids. + + .. math:: + + \\sigma_A = \\sqrt{2/N}\\,\\sigma, \\qquad + \\sigma_\\phi = \\sqrt{2/N}\\,\\sigma/A, \\qquad + \\sigma_f = \\sqrt{6/N}\\,\\frac{\\sigma}{\\pi T A} + + Parameters + ---------- + n_samples : int + Number of data points. + baseline : float + Total time span ``T`` in days. + residual_sigma : float + Standard deviation of the residuals after the fit. + amplitude : numpy.ndarray + Component amplitudes. + + Returns + ------- + tuple of numpy.ndarray + ``(sigma_f, sigma_A, sigma_phase)`` in cycles/day, input units, and radians. + """ + amp = np.asarray(amplitude, dtype=np.float64) + if n_samples <= 0 or not np.isfinite(residual_sigma): + nan = np.full(amp.shape, np.nan, dtype=np.float64) + return nan, nan.copy(), nan.copy() + sigma_a = np.full(amp.shape, np.sqrt(2.0 / n_samples) * residual_sigma) + with np.errstate(divide="ignore", invalid="ignore"): + safe_amp = np.where(amp > 0.0, amp, np.nan) + sigma_phase = sigma_a / safe_amp + sigma_f = ( + np.sqrt(6.0 / n_samples) + * residual_sigma + / (np.pi * baseline * safe_amp) + if baseline > 0.0 + else np.full(amp.shape, np.nan) + ) + return np.asarray(sigma_f), sigma_a, np.asarray(sigma_phase) + + +def bootstrap_uncertainties( + time: FloatArray, + error: FloatArray | None, + fit: MultiSineFit, + *, + n_resamples: int = 200, + seed: int = 0, + refine: Refinement = "cyclic", + sweeps: int = 1, + frequency_bounds: tuple[Any, Any] | None = None, +) -> tuple[FloatArray, FloatArray, FloatArray]: + """Residual-resampling bootstrap errors for a fitted solution. + + Each replicate adds a resampling (with replacement) of the fit residuals back onto + the best-fit model and re-fits from the current solution. The scatter of the + replicate parameters is the uncertainty. This makes no linearity assumption, and + needs no error bars, but it does assume the residuals are exchangeable — if they are + strongly correlated, prefer the correlation-factor-inflated covariance errors. + + Phases are combined on the unit circle so the wrap at ``2*pi`` cannot inflate the + scatter of a phase that happens to sit near zero. + + Parameters + ---------- + time : numpy.ndarray + Observation times (days). + error : numpy.ndarray, optional + 1-sigma uncertainties, used to weight the replicate fits. + fit : MultiSineFit + The solution to bootstrap around. + n_resamples : int, default 200 + Number of replicates. + seed : int, default 0 + Seed for the resampling RNG (results are reproducible). + refine, sweeps + Refinement policy for the replicate fits. ``"none"`` and ``"last"`` are + extraction-loop policies that pin some or all frequencies, which would report + exactly zero frequency scatter for the pinned components — they are promoted to + a full ``"cyclic"`` sweep here. + frequency_bounds : (lower, upper), optional + Per-frequency refinement boxes for the replicate fits (see + :func:`~cuperiod.prewhiten.fit.fit_multisine`). Keeps a replicate from sliding + onto a close neighbour, exactly as in the fit being characterised. + + Returns + ------- + tuple of numpy.ndarray + ``(sigma_f, sigma_A, sigma_phase)``. + """ + k = fit.n_components + if k == 0 or n_resamples < 2: + empty = np.full(k, np.nan, dtype=np.float64) + return empty, empty.copy(), empty.copy() + policy: Refinement = "cyclic" if refine in {"none", "last"} else refine + t = np.asarray(time, dtype=np.float64) + model = fit.model(t) + residuals = np.asarray(fit.residuals, dtype=np.float64) + rng = np.random.default_rng(seed) + freqs = np.empty((n_resamples, k), dtype=np.float64) + amps = np.empty((n_resamples, k), dtype=np.float64) + phasors = np.empty((n_resamples, k), dtype=np.complex128) + for i in range(n_resamples): + sample = model + rng.choice(residuals, size=residuals.size, replace=True) + replicate = fit_multisine( + t, + sample, + error, + fit.frequency, + fit_mean=fit.fit_mean, + t_ref=fit.t_ref, + refine=policy, + sweeps=sweeps, + frequency_bounds=frequency_bounds, + covariance=False, + ) + freqs[i] = replicate.frequency + amps[i] = replicate.amplitude + phasors[i] = np.exp(1j * replicate.phase) + sigma_f = np.std(freqs, axis=0, ddof=1) + sigma_a = np.std(amps, axis=0, ddof=1) + # Circular standard deviation: sqrt(-2 ln R) with R the mean resultant length. + resultant = np.clip(np.abs(np.mean(phasors, axis=0)), 1e-12, 1.0) + sigma_phase = np.sqrt(-2.0 * np.log(resultant)) + return sigma_f, sigma_a, sigma_phase + + +def component_uncertainties( + time: FloatArray, + error: FloatArray | None, + fit: MultiSineFit, + *, + method: UncertaintyMethod = "covariance", + correlation_correction: bool = True, + n_resamples: int = 200, + seed: int = 0, + refine: Refinement = "cyclic", + sweeps: int = 1, + frequency_bounds: tuple[Any, Any] | None = None, +) -> Uncertainties: + """Per-component 1-sigma errors by the requested estimator. + + Parameters + ---------- + time : numpy.ndarray + Observation times (days). + error : numpy.ndarray, optional + 1-sigma uncertainties. + fit : MultiSineFit + The solution to characterise. + method : {"covariance", "analytic", "bootstrap"}, default "covariance" + Estimator (see the module docstring). + correlation_correction : bool, default True + Multiply the errors by ``sqrt(D)`` with ``D`` from :func:`correlation_factor`. + Never applied to the bootstrap, which already samples the residuals as they are. + n_resamples, seed, refine, sweeps, frequency_bounds + Bootstrap controls (see :func:`bootstrap_uncertainties`). + + Returns + ------- + Uncertainties + """ + if method == "analytic": + sigma_f, sigma_a, sigma_phase = analytic_uncertainties( + fit.n_samples, + float(np.ptp(time)) if np.size(time) else 0.0, + float(np.std(fit.residuals)) if fit.residuals.size else float("nan"), + fit.amplitude, + ) + elif method == "bootstrap": + sigma_f, sigma_a, sigma_phase = bootstrap_uncertainties( + time, error, fit, + n_resamples=n_resamples, seed=seed, refine=refine, sweeps=sweeps, + frequency_bounds=frequency_bounds, + ) + else: + sigma_f = fit.frequency_error + sigma_a = fit.amplitude_error + sigma_phase = fit.phase_error + + factor = 1.0 + if correlation_correction and method != "bootstrap": + factor = float(np.sqrt(correlation_factor(fit.residuals))) + return Uncertainties( + frequency=np.asarray(sigma_f, dtype=np.float64) * factor, + amplitude=np.asarray(sigma_a, dtype=np.float64) * factor, + phase=np.asarray(sigma_phase, dtype=np.float64) * factor, + method=method, + correlation_factor=factor**2, + ) + + +__all__ = [ + "UncertaintyMethod", + "Uncertainties", + "analytic_uncertainties", + "bootstrap_uncertainties", + "component_uncertainties", + "correlation_factor", +] diff --git a/tests/gui/test_main_window.py b/tests/gui/test_main_window.py index 9d2ff1e..f234eaf 100644 --- a/tests/gui/test_main_window.py +++ b/tests/gui/test_main_window.py @@ -220,3 +220,96 @@ def test_placeholder_text_uses_straight_quotes(qtbot: QtBot) -> None: text = window._placeholder.text() assert "“" not in text and "”" not in text assert '"Compute periodogram"' in text + + +def test_analysis_switch_swaps_the_result_docks(qtbot: QtBot) -> None: + window = _window(qtbot) + assert window._peaks_dock.isVisible() + assert not window._solution_dock.isVisible() + window._controls.set_analysis("prewhiten") + assert window._solution_dock.isVisible() + assert window._spacing_dock.isVisible() + assert not window._peaks_dock.isVisible() + window._controls.set_analysis("periodogram") + assert window._peaks_dock.isVisible() + assert not window._solution_dock.isVisible() + window._controller.shutdown() + + +def test_analysis_switch_keeps_the_loaded_light_curve(qtbot: QtBot) -> None: + # Regression: switching analysis used to clear the phased view's light curve, + # leaving an empty panel until the next file load. + window = _window(qtbot) + window._controller.set_light_curve(_light_curve(), "star") + window._controls.set_analysis("prewhiten") + assert window._phased._lc is not None + assert window._controls.can_compute() + window._controller.shutdown() + + +def test_prewhiten_run_populates_every_panel(qtbot: QtBot) -> None: + from cuperiod.core.config import PreWhitenSettings + from cuperiod.gui.widgets.spectrum_view import PREWHITEN_METHOD + from synth import synthetic_pulsator + + window = _window(qtbot) + time, value, error = synthetic_pulsator(n=600, span=20.0) + window._controller.set_light_curve( + LightCurve.from_arrays(time, value, error), "pulsator" + ) + window._controls.set_analysis("prewhiten") + settings = PreWhitenSettings( + backend="finufft", max_frequencies=3, samples_per_peak=6 + ) + with qtbot.waitSignal(window._controller.solution_ready, timeout=60000): + window._controller.run_prewhiten("finufft", settings) + solution = window._controller.state.current_solution + assert solution is not None and solution.n_components >= 1 + assert window._solution_panel._table.rowCount() == solution.n_components + assert window._spectrum._pg is not None + assert window._spectrum._pg.method == PREWHITEN_METHOD + assert window._spectrum._overlay_xy is not None + assert window._stack.currentIndex() == 1 + window._controller.shutdown() + + +def test_component_markers_are_drawn_on_the_spectrum_curve(qtbot: QtBot) -> None: + # Regression: markers were placed at the component's *fitted* amplitude while the + # curve shows the single-frequency amplitude spectrum. The two diverge as soon as + # components are correlated (a HADS harmonic and its yearly alias sidelobes trade + # amplitude in the joint fit), leaving dots floating in empty space above the + # curve — a peak the spectrum does not have. + from dataclasses import replace + + from cuperiod.core.config import PreWhitenSettings + from cuperiod.prewhiten import prewhiten + from synth import synthetic_pulsator + + window = _window(qtbot) + time, value, error = synthetic_pulsator(n=600, span=20.0) + solution = prewhiten( + (time, value, error), + settings=PreWhitenSettings( + backend="finufft", max_frequencies=3, samples_per_peak=6 + ), + ) + assert solution.spectrum is not None and solution.n_components >= 2 + # Force the pathological case rather than hoping for it: an amplitude nothing like + # the spectrum at that frequency, in both directions. + components = list(solution.components) + components[0] = replace(components[0], amplitude=components[0].amplitude * 5.0) + components[1] = replace(components[1], amplitude=components[1].amplitude * 0.1) + solution = replace(solution, components=tuple(components)) + + window._show_solution_spectrum(solution) + grid, curve = solution.spectrum.frequency, solution.spectrum.amplitude + peaks = window._spectrum._peaks + assert len(peaks) == solution.n_components + for peak in peaks: + nearest = int(np.argmin(np.abs(grid - peak.frequency))) + assert peak.power == pytest.approx(float(curve[nearest])) + assert peak.power <= float(curve.max()) + # The fitted amplitude is not lost — it moves to the hover readout. + assert peaks[0].extra["amplitude"] == pytest.approx(components[0].amplitude) + assert peaks[0].power != pytest.approx(components[0].amplitude) + window._controller.shutdown() diff --git a/tests/gui/test_meta.py b/tests/gui/test_meta.py index 7163a65..163f3e9 100644 --- a/tests/gui/test_meta.py +++ b/tests/gui/test_meta.py @@ -12,7 +12,10 @@ def test_multiband_method_names() -> None: multiband = set(multiband_method_names()) - assert multiband == {"GLS", "BLS", "MHAOV"} + # The joint-fit methods plus the pooled fold statistics; TLS is single-band only. + assert multiband == { + "GLS", "BLS", "MHAOV", "PDM", "CE", "STRINGLENGTH", "SUPERSMOOTHER" + } assert multiband.issubset(method_display_names()) diff --git a/tests/gui/test_prewhiten_gui.py b/tests/gui/test_prewhiten_gui.py new file mode 100644 index 0000000..7023c5b --- /dev/null +++ b/tests/gui/test_prewhiten_gui.py @@ -0,0 +1,541 @@ +"""GUI pre-whitening: analysis switching, off-thread runs, and the new panels. + +The point of these tests is that adding pre-whitening did not cost the periodogram +workflow anything: the same controller, the same spectrum/phased views, the same source +browser, with the result panels swapped underneath. +""" + +from __future__ import annotations + +import numpy as np +import pytest +from pytestqt.qtbot import QtBot + +from cuperiod.core.config import GLSSettings, PreWhitenSettings +from cuperiod.core.lightcurve import LightCurve +from cuperiod.gui.compute import ComputeManager +from cuperiod.gui.meta import prewhiten_backend_options, resolved_prewhiten_backend +from cuperiod.gui.models import ResultCache, ResultKey +from cuperiod.gui.state import PREWHITEN_KEY, AppController +from cuperiod.gui.widgets.controls_panel import ( + _PREWHITEN_CACHE_KEY, + ControlsPanel, +) +from cuperiod.gui.widgets.solution_panel import SolutionPanel +from cuperiod.gui.widgets.spacing_panel import SpacingPanel +from cuperiod.gui.widgets.spectrum_view import PREWHITEN_METHOD, SpectrumView +from cuperiod.prewhiten import prewhiten +from cuperiod.prewhiten.result import PreWhitenResult +from synth import synthetic_gmode, synthetic_pulsator + +_SETTINGS = PreWhitenSettings( + backend="finufft", max_frequencies=3, samples_per_peak=6 +) + + +def _curve(n: int = 600) -> LightCurve: + time, value, error = synthetic_pulsator(n=n, span=20.0) + return LightCurve.from_arrays(time, value, error) + + +def _solution(n: int = 600) -> PreWhitenResult: + return prewhiten(_curve(n), settings=_SETTINGS) + + +# --- controls ---------------------------------------------------------------- + + +def test_analysis_picker_swaps_the_settings_model(qtbot: QtBot) -> None: + panel = ControlsPanel() + qtbot.addWidget(panel) + assert panel.analysis == "periodogram" + with qtbot.waitSignal(panel.analysis_changed, timeout=2000) as blocker: + panel.set_analysis("prewhiten") + assert blocker.args == ["prewhiten"] + assert panel.analysis == "prewhiten" + assert isinstance(panel._form.build(), PreWhitenSettings) + panel.set_analysis("periodogram") + assert isinstance(panel._form.build(), GLSSettings) + + +def test_compute_emits_the_analysis_specific_signal(qtbot: QtBot) -> None: + panel = ControlsPanel() + qtbot.addWidget(panel) + panel.set_enabled(True) + with qtbot.waitSignal(panel.run_requested, timeout=2000): + panel.request_compute() + panel.set_analysis("prewhiten") + with qtbot.waitSignal(panel.prewhiten_requested, timeout=2000) as blocker: + panel.request_compute() + backend, settings = blocker.args + assert backend in prewhiten_backend_options() + assert isinstance(settings, PreWhitenSettings) + + +def test_settings_are_remembered_across_analysis_switches(qtbot: QtBot) -> None: + panel = ControlsPanel() + qtbot.addWidget(panel) + # Seed the pre-whitening slot while the periodogram form is up, so switching to + # pre-whitening has to rebuild its form from the cache rather than from defaults. + panel._settings_cache[_PREWHITEN_CACHE_KEY] = PreWhitenSettings(max_frequencies=7) + panel.set_analysis("prewhiten") + assert panel._form.build().max_frequencies == 7 + # Switching away stashes whatever the form currently holds, per analysis. + panel.set_analysis("periodogram") + assert isinstance(panel._settings_cache[_PREWHITEN_CACHE_KEY], PreWhitenSettings) + assert isinstance(panel._settings_cache["GLS"], GLSSettings) + + +def test_prewhiten_backend_helpers() -> None: + options = prewhiten_backend_options() + assert "auto" in options and "numpy" in options + resolved = resolved_prewhiten_backend("cpu") + assert resolved is not None + assert resolved[0] in {"finufft", "numpy"} and resolved[1] is False + assert resolved_prewhiten_backend("nonsense") is None + + +# --- controller -------------------------------------------------------------- + + +def test_controller_runs_prewhiten_off_thread(qtbot: QtBot) -> None: + controller = AppController() + controller.set_light_curve(_curve(), "star") + with qtbot.waitSignal(controller.solution_ready, timeout=60000) as blocker: + controller.run_prewhiten("finufft", _SETTINGS) + (result,) = blocker.args + assert isinstance(result, PreWhitenResult) + assert result.n_components >= 1 + assert controller.state.current_solution is result + assert controller.state.method == PREWHITEN_KEY + # The strongest component becomes the active period for the phased view. + assert controller.state.selected_period == pytest.approx( + result.components[0].period + ) + controller.shutdown() + + +def test_a_repeat_run_is_served_from_the_cache(qtbot: QtBot) -> None: + controller = AppController() + controller.set_light_curve(_curve(), "star") + with qtbot.waitSignal(controller.solution_ready, timeout=60000): + controller.run_prewhiten("finufft", _SETTINGS) + with qtbot.waitSignal(controller.solution_ready, timeout=2000): + controller.run_prewhiten("finufft", _SETTINGS) + assert controller.state.last_from_cache + assert controller.state.last_compute_ms == 0.0 + controller.shutdown() + + +def test_switching_analysis_keeps_both_caches(qtbot: QtBot) -> None: + controller = AppController() + controller.set_light_curve(_curve(), "star") + with qtbot.waitSignal(controller.periodogram_ready, timeout=60000): + controller.run("GLS", "finufft", GLSSettings(), 5) + controller.set_analysis("prewhiten") + with qtbot.waitSignal(controller.solution_ready, timeout=60000): + controller.run_prewhiten("finufft", _SETTINGS) + controller.set_analysis("periodogram") + with qtbot.waitSignal(controller.periodogram_ready, timeout=2000): + controller.run("GLS", "finufft", GLSSettings(), 5) + assert controller.state.last_from_cache # the earlier spectrum survived + controller.shutdown() + + +def test_analysis_change_emits_once_and_is_idempotent(qtbot: QtBot) -> None: + controller = AppController() + with qtbot.waitSignal(controller.analysis_changed, timeout=2000): + controller.set_analysis("prewhiten") + assert controller.state.analysis == "prewhiten" + with qtbot.assertNotEmitted(controller.analysis_changed): + controller.set_analysis("prewhiten") + + +def test_a_failed_prewhiten_run_surfaces_as_a_message(qtbot: QtBot) -> None: + controller = AppController() + flat = LightCurve.from_arrays( + np.full(60, 2458000.0), np.ones(60), np.full(60, 0.01) + ) + controller.set_light_curve(flat, "flat") + with qtbot.waitSignal(controller.compute_failed, timeout=30000) as blocker: + controller.run_prewhiten("finufft", _SETTINGS) + assert "InsufficientDataError" in blocker.args[0] + controller.shutdown() + + +def test_compute_manager_gates_superseded_prewhiten_tasks(qtbot: QtBot) -> None: + manager = ComputeManager() + key = ResultKey("star", PREWHITEN_KEY, "hash", "finufft") + manager.cancel_all() # bump the generation so the next submit is stale on arrival + manager.submit_prewhiten(key, _curve(200), _SETTINGS, "finufft") + manager.cancel_all() + assert manager.wait_for_done(30000) + + +def test_result_cache_is_generic_over_its_value_type() -> None: + cache: ResultCache[PreWhitenResult] = ResultCache(maxsize=1) + key_a = ResultKey("a", PREWHITEN_KEY, "h", "cpu") + key_b = ResultKey("b", PREWHITEN_KEY, "h", "cpu") + solution = _solution(300) + cache.put(key_a, solution) + assert cache.get(key_a) is solution + cache.put(key_b, solution) + assert cache.get(key_a) is None # evicted + + +# --- panels ------------------------------------------------------------------ + + +def test_solution_table_shows_formatted_numbers_and_still_sorts_numerically( + qtbot: QtBot, +) -> None: + # Regression: the sort key was written to EditRole, which QTableWidgetItem stores + # in the same slot as DisplayRole — so every numeric column silently rendered Qt's + # 6-significant-digit default instead of the per-column format (a frequency needs + # more digits than that, an uncertainty fewer). + panel = SolutionPanel() + qtbot.addWidget(panel) + panel.set_solution(_solution()) + headers = [ + panel._table.horizontalHeaderItem(i).text() + for i in range(panel._table.columnCount()) + ] + row_of = {panel._table.item(r, 0).text(): r for r in range(panel._table.rowCount())} + component = next(c for c in panel._components if c.label in row_of) + row = row_of[component.label] + + shown = panel._table.item(row, headers.index("frequency")).text() + assert shown == f"{component.frequency:.9g}" + assert panel._table.item(row, headers.index("± f")).text() == ( + f"{component.frequency_error:.3g}" + ) + # And sorting still orders by value, not by the string. + panel._table.sortItems(headers.index("frequency")) + ordered = [ + float(panel._table.item(r, headers.index("frequency")).text()) + for r in range(panel._table.rowCount()) + ] + assert ordered == sorted(ordered) + + +def test_blended_components_are_marked_in_the_table(qtbot: QtBot) -> None: + from dataclasses import replace + + panel = SolutionPanel() + qtbot.addWidget(panel) + solution = _solution() + components = list(solution.components) + components[0] = replace( + components[0], spectrum_amplitude=components[0].amplitude / 5.0, blended=True + ) + solution = replace(solution, components=tuple(components)) + panel.set_solution(solution) + + headers = [ + panel._table.horizontalHeaderItem(i).text() + for i in range(panel._table.columnCount()) + ] + column = headers.index("A/Asp") + marked = [ + panel._table.item(r, column).text() + for r in range(panel._table.rowCount()) + if "✱" in panel._table.item(r, column).text() + ] + assert len(marked) == 1 and marked[0].startswith("5.0") + assert "blended" in panel._summary.text() + # The mark must not be there when nothing is blended. + panel.set_solution(_solution()) + assert all( + "✱" not in panel._table.item(r, column).text() + for r in range(panel._table.rowCount()) + ) + assert "blended" not in panel._summary.text() + + +def test_solution_panel_lists_components_and_emits_selection(qtbot: QtBot) -> None: + panel = SolutionPanel() + qtbot.addWidget(panel) + solution = _solution() + panel.set_solution(solution) + assert panel._table.rowCount() == solution.n_components + assert panel._table.item(0, 0).text() == "F1" + assert "stopped" in panel._summary.text() + with qtbot.waitSignal(panel.component_selected, timeout=2000) as blocker: + panel._table.selectRow(1) + assert blocker.args[0].rank == 2 + panel.clear() + assert panel._table.rowCount() == 0 + + +def test_solution_panel_exports_full_precision_csv(qtbot: QtBot, tmp_path) -> None: + panel = SolutionPanel() + qtbot.addWidget(panel) + solution = _solution() + panel.set_solution(solution) + path = tmp_path / "frequencies.csv" + panel.export_csv(str(path)) + text = path.read_text(encoding="utf-8").splitlines() + assert text[0].startswith("rank,label,frequency") + assert len(text) == solution.n_components + 1 + + +def test_spacing_panel_finds_a_series(qtbot: QtBot) -> None: + time, value, error, periods = synthetic_gmode(n=1500, n_modes=12) + solution = prewhiten( + LightCurve.from_arrays(time, value, error), + settings=PreWhitenSettings(backend="finufft", max_frequencies=14), + ) + panel = SpacingPanel() + qtbot.addWidget(panel) + panel.set_solution(solution) + assert panel._search_btn.isEnabled() + panel.search() + assert "modes in one series" in panel._summary.text() + assert panel._echelle_points.data.size > 0 + + +def test_spacing_panel_declines_a_short_solution(qtbot: QtBot) -> None: + panel = SpacingPanel() + qtbot.addWidget(panel) + panel.set_solution(_solution()) # only three components + assert not panel._search_btn.isEnabled() + assert "at least" in panel._summary.text() + panel.search() # a no-op, must not raise + panel.clear() + assert "Run pre-whitening" in panel._summary.text() + + +def test_spectrum_view_overlays_the_residual_spectrum(qtbot: QtBot) -> None: + from cuperiod.core.result import Periodogram + + view = SpectrumView() + qtbot.addWidget(view) + solution = _solution() + assert solution.spectrum is not None and solution.residual_spectrum is not None + wrapped = Periodogram.from_spectrum( + method=PREWHITEN_METHOD, + backend=solution.backend, + frequency=solution.spectrum.frequency, + power=solution.spectrum.amplitude, + objective_sense="max", + n_samples=solution.n_samples, + baseline=solution.baseline, + ) + view.set_periodogram(wrapped) + assert not view._show_residual.isVisible() or view._overlay_xy is None + view.set_overlay( + solution.residual_spectrum.frequency, solution.residual_spectrum.amplitude + ) + assert view._overlay.isVisible() + # The residual spectrum must sit below the original everywhere it is drawn. + assert np.max(solution.residual_spectrum.amplitude) < np.max( + solution.spectrum.amplitude + ) + view.set_periodogram(wrapped) # a new result drops the stale overlay + assert view._overlay_xy is None + + +def test_spectrum_view_offers_the_spectral_window(qtbot: QtBot) -> None: + from cuperiod.core.result import Periodogram + + view = SpectrumView() + qtbot.addWidget(view) + solution = _solution() + assert solution.spectrum is not None and solution.window is not None + wrapped = Periodogram.from_spectrum( + method=PREWHITEN_METHOD, + backend=solution.backend, + frequency=solution.spectrum.frequency, + power=solution.spectrum.amplitude, + objective_sense="max", + n_samples=solution.n_samples, + baseline=solution.baseline, + ) + view.set_periodogram(wrapped) + scale = float(np.max(solution.spectrum.amplitude)) + view.set_window( + solution.window.frequency, solution.window.amplitude, scale=scale + ) + # Off by default: the window is a diagnostic the user opts into. + assert not view._window_curve.isVisible() + view._show_window.setChecked(True) + assert view._window_curve.isVisible() + assert view._window_xy is not None + # Scaled to the tallest peak, so it shares the spectrum's amplitude axis. + assert np.max(view._window_xy[1]) <= scale * (1.0 + 1e-9) + view.set_periodogram(wrapped) # a new result drops the stale window + assert view._window_xy is None and not view._window_curve.isVisible() + + +def test_data_curve_can_be_hidden_to_read_the_overlays(qtbot: QtBot) -> None: + from cuperiod.core.result import Periodogram + + view = SpectrumView() + qtbot.addWidget(view) + solution = _solution() + assert solution.spectrum is not None and solution.residual_spectrum is not None + wrapped = Periodogram.from_spectrum( + method=PREWHITEN_METHOD, + backend=solution.backend, + frequency=solution.spectrum.frequency, + power=solution.spectrum.amplitude, + objective_sense="max", + n_samples=solution.n_samples, + baseline=solution.baseline, + ) + view.set_periodogram(wrapped) + # A plain periodogram has nothing underneath, so the toggle is not offered. + assert not view._show_data.isVisibleTo(view) + view.set_overlay( + solution.residual_spectrum.frequency, solution.residual_spectrum.amplitude + ) + assert view._show_data.isVisibleTo(view) and view._show_data.isChecked() + assert view._curve.isVisible() + + view._show_data.setChecked(False) + assert not view._curve.isVisible() + assert view._overlay.isVisible() # the point of hiding it + + # Dropping the overlays must restore the curve rather than leave an empty plot. + view.clear_overlay() + assert view._show_data.isChecked() and not view._show_data.isVisibleTo(view) + view._redraw_curve() + assert view._curve.isVisible() + + +def test_double_click_restores_the_default_view(qtbot: QtBot) -> None: + from cuperiod.core.result import Periodogram + + view = SpectrumView() + qtbot.addWidget(view) + frequency = np.linspace(0.5, 20.0, 4000) + power = np.exp(-((frequency - 7.0) ** 2) / 0.01) + view.set_periodogram( + Periodogram.from_spectrum( + method="GLS", backend="numpy", frequency=frequency, power=power, + objective_sense="max", n_samples=400, baseline=30.0, + ) + ) + box = view._plot.getPlotItem().vb + box.setXRange(6.9, 7.1, padding=0.0) + zoomed = box.viewRange()[0] + assert zoomed[1] - zoomed[0] < 1.0 + + class _DoubleClick: + def __init__(self) -> None: + self.accepted = False + + def double(self) -> bool: + return True + + def accept(self) -> None: + self.accepted = True + + event = _DoubleClick() + view._on_scene_clicked(event) + assert event.accepted + restored = box.viewRange()[0] + assert restored[1] - restored[0] > 15.0 # back to the full spectrum + + # A single click must not steal the user's zoom. + box.setXRange(6.9, 7.1, padding=0.0) + view._on_scene_clicked(type("_Single", (), {"double": lambda self: False})()) + held = box.viewRange()[0] + assert held[1] - held[0] < 1.0 + + +def test_marker_hover_reports_the_fitted_amplitude(qtbot: QtBot) -> None: + # The marker sits at the height of the *curve*, so the component's fitted + # amplitude has to be readable from the hover text instead of its position. + from cuperiod.core.result import Peak + + component = Peak( + period=0.08, frequency=12.5, power=0.046, rank=1, + extra={"amplitude": 0.0855, "snr": 20.9}, + ) + detail = SpectrumView._peak_detail(component) + assert "0.0855" in detail and "20.9" in detail + assert "0.046" not in detail # that is where the marker sits, not what it is + assert "blended" not in detail + # A blended component says so, since its marker height is not its amplitude. + flagged = Peak( + period=0.08, frequency=12.5, power=0.046, rank=1, + extra={"amplitude": 0.0855, "snr": 20.9, "blended": 1.0}, + ) + assert "blended" in SpectrumView._peak_detail(flagged) + # A plain periodogram peak has no amplitude and keeps reporting its power. + plain = Peak(period=2.0, frequency=0.5, power=0.83, rank=1) + assert SpectrumView._peak_detail(plain) == "power=0.83" + # A missing/NaN S/N must not put "nan" in front of the user. + quiet = Peak( + period=0.08, frequency=12.5, power=0.046, rank=1, + extra={"amplitude": 0.0855, "snr": float("nan")}, + ) + assert "nan" not in SpectrumView._peak_detail(quiet).lower() + + +# --- regressions ------------------------------------------------------------- + + +def test_switching_analysis_mid_run_releases_the_busy_state(qtbot: QtBot) -> None: + # Regression: set_analysis() cleared the pending key, so the completion handler for + # the in-flight run never fired busy_changed(False) and Compute stayed disabled for + # the rest of the session. + controller = AppController() + panel = ControlsPanel() + qtbot.addWidget(panel) + panel.set_enabled(True) + controller.busy_changed.connect(panel.set_busy) + controller.set_light_curve(_curve(4000), "star") + with qtbot.waitSignal(controller.busy_changed, timeout=5000): + controller.run_prewhiten("finufft", _SETTINGS) + assert not panel.can_compute() # busy + with qtbot.waitSignal(controller.busy_changed, timeout=5000) as blocker: + controller.set_analysis("periodogram") + assert blocker.args == [False] + assert panel.can_compute() + controller.shutdown() + + +def test_prewhiten_defaults_to_one_band_for_a_multiband_curve(qtbot: QtBot) -> None: + # Regression: set_bands() passed the (hidden) method combo's text, so a multiband + # curve loaded *after* switching to pre-whitening offered and selected + # "combined (all bands)" and silently analysed a raw all-band stack. + panel = ControlsPanel() + qtbot.addWidget(panel) + panel.set_analysis("prewhiten") + panel.set_bands(["g", "r"]) + assert panel.current_band() == "g" + assert "combined" not in panel._band_combo.itemText(0) + # ...and the same is true whichever order the two happen in. + other = ControlsPanel() + qtbot.addWidget(other) + other.set_bands(["g", "r"]) + other.set_analysis("prewhiten") + assert other.current_band() == "g" + + +def test_a_stacked_multiband_prewhiten_removes_the_band_offsets(qtbot: QtBot) -> None: + from cuperiod.core.lightcurve import MultiBandLightCurve + + rng = np.random.default_rng(0) + time = np.sort(rng.uniform(0.0, 20.0, 900)) + 2458000.0 + signal = 0.01 * np.sin(2 * np.pi * 1.3 * (time - time.min())) + bands = { + "g": LightCurve.from_arrays( + time, 15.0 + signal + rng.normal(0, 5e-4, 900), np.full(900, 5e-4) + ), + "r": LightCurve.from_arrays( + time, 14.2 + signal + rng.normal(0, 5e-4, 900), np.full(900, 5e-4) + ), + } + mblc = MultiBandLightCurve.from_light_curves(bands) + controller = AppController() + controller.set_light_curve(mblc, "multiband") + with qtbot.waitSignal(controller.solution_ready, timeout=60000) as blocker: + controller.run_prewhiten("finufft", _SETTINGS, band="stacked") + (result,) = blocker.args + # A raw concatenation would bury the 0.01 mag signal under a 0.8 mag offset. + assert result.n_components >= 1 + assert result.components[0].frequency == pytest.approx(1.3, abs=0.01) + controller.shutdown() diff --git a/tests/gui/test_widget_polish.py b/tests/gui/test_widget_polish.py index b12bf45..93c5a6b 100644 --- a/tests/gui/test_widget_polish.py +++ b/tests/gui/test_widget_polish.py @@ -178,12 +178,125 @@ def test_spectrum_export_csv_writes_expected_columns(qtbot: QtBot, tmp_path) -> assert len(rows) == 1 + view._pg.size +class _HoveredPoint: + """Stand-in for the pyqtgraph spot under the cursor.""" + + def __init__(self, index: int | None) -> None: + self._index = index + + def data(self) -> int | None: + return self._index + + +def test_hiding_the_peaks_takes_their_hover_label_with_them(qtbot: QtBot) -> None: + # Regression: the hover label is anchored to a marker, but nothing hid it when the + # markers went away — so unchecking "peaks" (the natural move right after hovering + # one to read it) left the label stranded over an empty plot. + view = SpectrumView("dark") + qtbot.addWidget(view) + pg_result = _bump_periodogram() + view.set_periodogram(pg_result) + view.set_peaks(pg_result.best_periods(3)) + + view._on_peak_hovered(view._markers, [_HoveredPoint(0)]) + assert view._hover_text.isVisible() + + view._show_peaks.setChecked(False) + assert not view._hover_text.isVisible() + assert len(view._markers.data) == 0 + + # Same for a new result, and for an axis switch that moves the anchor. + view._show_peaks.setChecked(True) + view.set_peaks(pg_result.best_periods(3)) + view._on_peak_hovered(view._markers, [_HoveredPoint(0)]) + assert view._hover_text.isVisible() + view.set_periodogram(pg_result) + assert not view._hover_text.isVisible() + + view.set_peaks(pg_result.best_periods(3)) + view._on_peak_hovered(view._markers, [_HoveredPoint(0)]) + assert view._hover_text.isVisible() + view._xaxis_combo.setCurrentText("period") + assert not view._hover_text.isVisible() + + # A glow halo carries no index and must not leave another peak's label up. + view._on_peak_hovered(view._markers, [_HoveredPoint(0)]) + assert view._hover_text.isVisible() + view._on_peak_hovered(view._markers, [_HoveredPoint(None)]) + assert not view._hover_text.isVisible() + + +def test_peaks_toggle_hides_and_restores_every_marker(qtbot: QtBot) -> None: + view = SpectrumView("dark") + qtbot.addWidget(view) + frequency = np.linspace(0.2, 20.0, 6000) + power = sum( + a * np.exp(-((frequency - f) ** 2) / 0.002) + for f, a in ((3.0, 1.0), (7.0, 0.6), (11.0, 0.35)) + ) + pg_result = Periodogram.from_spectrum( + method="GLS", backend="numpy", frequency=frequency, power=power, + objective_sense="max", n_samples=500, baseline=40.0, + ) + peaks = pg_result.best_periods(3) + assert len(peaks) == 3 + view.set_periodogram(pg_result) + view.set_peaks(peaks) + view.set_selected_period(peaks[1].period) + populated = len(view._markers.data) + assert populated == 5 # three peaks plus the best-peak and selected halos + + view._show_peaks.setChecked(False) + assert len(view._markers.data) == 0 + # Nothing that happens while it is off may bring them back. + view.set_selected_period(peaks[2].period) + view.set_peaks(peaks) + view._logy.setChecked(True) + assert len(view._markers.data) == 0 + + view._show_peaks.setChecked(True) + assert len(view._markers.data) == populated + + +def test_selection_band_follows_the_peaks_toggle(qtbot: QtBot) -> None: + # The band shades a peak, so it belongs to the peak layer: leaving it behind was + # the one bit of clutter the toggle is usually turned off to be rid of. + view = SpectrumView("dark") + qtbot.addWidget(view) + pg_result = _bump_periodogram() + view.set_periodogram(pg_result) + peak = pg_result.best_periods(1)[0] + view.set_peaks([peak]) + view.set_selected_period(peak.period) + assert view._sel_band.isVisible() + + view._show_peaks.setChecked(False) + assert not view._sel_band.isVisible() + # The selection itself is not lost, so the fold does not change under the user. + assert view._sel_period == peak.period + # Nor does re-selecting while hidden bring the band back. + view.set_selected_period(peak.period) + assert not view._sel_band.isVisible() + + view._show_peaks.setChecked(True) + assert view._sel_band.isVisible() + + # With peaks shown but nothing selected there is still no band. + view.clear_selection() + assert not view._sel_band.isVisible() + view._show_peaks.setChecked(False) + view._show_peaks.setChecked(True) + assert not view._sel_band.isVisible() + + def test_spectrum_reset_button_label(qtbot: QtBot) -> None: + # "Reset", not "Reset view": with the pre-whitening overlay toggles shown the + # longer label pushed the toolbar past the dock width and Qt squeezed the buttons. view = SpectrumView("dark") qtbot.addWidget(view) buttons = view.findChildren(QtWidgets.QPushButton) labels = [b.text() for b in buttons] - assert "Reset view" in labels + assert "Reset" in labels def test_spectrum_selected_marker_is_highlighted(qtbot: QtBot) -> None: diff --git a/tests/gui/test_widgets.py b/tests/gui/test_widgets.py index 2bb4b1c..d713c51 100644 --- a/tests/gui/test_widgets.py +++ b/tests/gui/test_widgets.py @@ -5,7 +5,13 @@ import numpy as np from pytestqt.qtbot import QtBot -from cuperiod.core.config import BLSSettings, GLSSettings +from cuperiod.core.config import ( + BLSSettings, + GLSSettings, + MHAOVSettings, + PDMSettings, + PreWhitenSettings, +) from cuperiod.core.lightcurve import LightCurve from cuperiod.core.result import Periodogram from cuperiod.gui.compute import ComputeManager @@ -94,10 +100,20 @@ def test_auto_grid_tuning_for_sparse_data(qtbot: QtBot) -> None: time = np.sort(np.random.default_rng(0).uniform(0.0, 2000.0, 200)) lc = LightCurve.from_arrays(time, np.sin(time), np.full(200, 0.01)) - tuned = controller._tune_auto_grid(lc, GLSSettings()) - assert tuned.maximum_frequency is not None - assert tuned.maximum_frequency >= 10.0 # reaches at least P = 0.1 d - assert tuned.samples_per_peak >= 10 # densified default grid + # The frequency-domain analyses share the delta Scuti / HADS floor (50 c/d): a + # trial frequency costs them a trig sum, and the 10 c/d ceiling put the bundled + # HADS demo (f = 11.14 c/d) out of band, aliasing it to a wrong period. + for settings in (GLSSettings(), MHAOVSettings(), PreWhitenSettings()): + tuned = controller._tune_auto_grid(lc, settings) + assert tuned.maximum_frequency is not None + assert tuned.maximum_frequency >= 50.0, type(settings).__name__ + assert controller._tune_auto_grid(lc, GLSSettings()).samples_per_peak >= 10 + + # Fold-based methods pay a full fold per trial frequency and keep the 10 c/d + # floor; their sub-day coverage is unchanged. + pdm = controller._tune_auto_grid(lc, PDMSettings()) + assert pdm.maximum_frequency is not None + assert pdm.maximum_frequency == 10.0 # a method without frequency-grid fields (BLS) is returned unchanged bls = BLSSettings() diff --git a/tests/synth.py b/tests/synth.py index 6cc49ef..cc4e894 100644 --- a/tests/synth.py +++ b/tests/synth.py @@ -25,6 +25,99 @@ def synthetic_sine( return t, mag, err +def synthetic_pulsator( + *, + n: int = 1500, + span: float = 27.0, + frequencies: tuple[float, ...] = (12.34, 17.81, 24.68), + amplitudes: tuple[float, ...] = (0.012, 0.007, 0.004), + phases: tuple[float, ...] = (0.5, 2.0, 1.0), + noise: float = 0.0015, + base_jd: float = 2458000.0, + seed: int = 4, +) -> tuple[FloatArray, FloatArray, FloatArray]: + """A multiperiodic pulsator: several coherent sinusoids plus white noise. + + The default is a δ Scuti-like triple whose third frequency is deliberately the exact + second harmonic of the first, so combination-frequency identification has something + real to find. + """ + rng = np.random.default_rng(seed) + t = np.sort(rng.uniform(0.0, span, n)) + base_jd + mag = np.full(n, 10.0) + for freq, amp, phase in zip(frequencies, amplitudes, phases, strict=True): + mag += amp * np.sin(2 * np.pi * freq * (t - t.min()) + phase) + err = np.full(n, noise) + mag = mag + rng.normal(0.0, noise, n) + return t, mag, err + + +def synthetic_gmode( + *, + n: int = 2500, + span: float = 90.0, + n_modes: int = 14, + first_period: float = 0.55, + spacing: float = 0.028, + spacing_slope: float = 0.008, + amplitude: float = 0.006, + noise: float = 0.0006, + base_jd: float = 2458000.0, + seed: int = 9, +) -> tuple[FloatArray, FloatArray, FloatArray, FloatArray]: + """A γ Dor-like g-mode series with a rotationally tilted period spacing. + + Consecutive periods follow ``dP(P) = spacing + spacing_slope * P``. Returns + ``(time, mag, err, periods)`` so a test can compare against the planted comb. + """ + rng = np.random.default_rng(seed) + periods = [first_period] + for _ in range(n_modes - 1): + periods.append(periods[-1] + spacing + spacing_slope * periods[-1]) + period_array = np.asarray(periods, dtype=np.float64) + t = np.sort(rng.uniform(0.0, span, n)) + base_jd + mag = np.full(n, 9.0) + for index, period in enumerate(period_array): + amp = amplitude * (1.0 - 0.04 * index) + mag += amp * np.sin( + 2 * np.pi * (t - t.min()) / period + rng.uniform(0.0, 2 * np.pi) + ) + err = np.full(n, noise) + mag = mag + rng.normal(0.0, noise, n) + return t, mag, err, period_array + + +def synthetic_multiband_sine( + *, + band_points: tuple[int, ...] = (60, 45, 30), + period: float = 0.7365, + amplitudes: tuple[float, ...] = (0.30, 0.22, 0.15), + offsets: tuple[float, ...] = (15.0, 14.2, 13.9), + phase: float = 0.3, + span: float = 180.0, + noise: float = 0.05, + base_jd: float = 2458000.0, + seed: int = 0, +) -> dict[str, tuple[FloatArray, FloatArray, FloatArray]]: + """Several bands of one shared-phase sine: per-band ``(t, mag, err)`` arrays. + + Bands share the period and phase but differ in amplitude, mean magnitude, + sampling, and per-point noise — the sparse multi-band regime the joint models + are for. Band labels count up from ``"b0"``. + """ + out: dict[str, tuple[FloatArray, FloatArray, FloatArray]] = {} + for index, (n, amp, offset) in enumerate( + zip(band_points, amplitudes, offsets, strict=True) + ): + rng = np.random.default_rng(seed + index) + t = np.sort(rng.uniform(0.0, span, n)) + base_jd + err = noise * (0.8 + 0.4 * rng.random(n)) + mag = offset + amp * np.sin(2 * np.pi * t / period + phase) + mag = mag + rng.normal(0.0, err) + out[f"b{index}"] = (t, mag, err) + return out + + def synthetic_eclipser( *, n: int = 800, diff --git a/tests/test_cli.py b/tests/test_cli.py index bcf6382..547df8c 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -94,3 +94,89 @@ def test_grid_info_command(tmp_path: Path) -> None: result = runner.invoke(app, ["grid-info", str(csv), "--method", "GLS"]) assert result.exit_code == 0 assert "samples" in result.stdout + + +def _write_pulsator_csv(path: Path) -> Path: + from synth import synthetic_pulsator + + time, mag, err = synthetic_pulsator(n=600, span=20.0) + pd.DataFrame({"hjd": time, "mag": mag, "mag_err": err}).to_csv(path, index=False) + return path + + +def test_prewhiten_command(tmp_path: Path) -> None: + csv = _write_pulsator_csv(tmp_path / "pulsator.csv") + out = tmp_path / "solution.json" + table = tmp_path / "components.csv" + result = runner.invoke( + app, + [ + "prewhiten", str(csv), "--backend", "finufft", "-n", "4", + "--out", str(out), "--csv", str(table), + ], + ) + assert result.exit_code == 0, result.output + assert "Pre-whitening" in result.stdout and "F1" in result.stdout + payload = json.loads(out.read_text(encoding="utf-8")) + assert payload["n_components"] >= 1 + assert payload["components"][0]["label"] == "F1" + header = table.read_text(encoding="utf-8").splitlines()[0] + assert header.startswith("rank,label,frequency") + + +def test_prewhiten_command_saves_spectra(tmp_path: Path) -> None: + import numpy as np + + csv = _write_pulsator_csv(tmp_path / "pulsator.csv") + npz = tmp_path / "spectra.npz" + result = runner.invoke( + app, + ["prewhiten", str(csv), "--backend", "finufft", "-n", "2", + "--save-spectrum", str(npz)], + ) + assert result.exit_code == 0, result.output + with np.load(npz) as data: + assert { + "frequency", "amplitude", "residual_amplitude", "window_amplitude" + } <= set(data) + assert np.all(data["window_amplitude"] <= 1.0 + 1e-12) + + +def test_prewhiten_command_reports_a_period_spacing(tmp_path: Path) -> None: + from synth import synthetic_gmode + + time, mag, err, _ = synthetic_gmode(n=1500, n_modes=12) + csv = tmp_path / "gdor.csv" + pd.DataFrame({"hjd": time, "mag": mag, "mag_err": err}).to_csv(csv, index=False) + result = runner.invoke( + app, + ["prewhiten", str(csv), "--backend", "finufft", "-n", "14", "--spacing"], + ) + assert result.exit_code == 0, result.output + assert "Period spacing" in result.stdout + + +def test_prewhiten_command_rejects_a_bad_criterion(tmp_path: Path) -> None: + csv = _write_pulsator_csv(tmp_path / "pulsator.csv") + result = runner.invoke( + app, ["prewhiten", str(csv), "--stop", "nonsense", "--backend", "finufft"] + ) + assert result.exit_code != 0 + + +def test_batch_prewhiten_command(tmp_path: Path) -> None: + import pyarrow.parquet as pq + + for index in range(2): + _write_pulsator_csv(tmp_path / f"p{index}.csv") + out = tmp_path / "modes.parquet" + result = runner.invoke( + app, + ["batch-prewhiten", str(tmp_path / "*.csv"), "--out", str(out), + "--backend", "finufft", "-n", "3", "--workers", "1"], + ) + assert result.exit_code == 0, result.output + assert out.exists() + table = pq.read_table(out).to_pylist() + assert {row["key"] for row in table} + assert "frequency" in table[0] diff --git a/tests/test_config.py b/tests/test_config.py index 1c572c7..80581e2 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -17,6 +17,7 @@ def test_defaults_construct() -> None: cup.CESettings, cup.MHAOVSettings, cup.StringLengthSettings, + cup.SuperSmootherSettings, cup.TLSSettings, cup.BatchSettings, ): @@ -25,7 +26,8 @@ def test_defaults_construct() -> None: def test_frequency_bounds_validated() -> None: for cls in (cup.GLSSettings, cup.PDMSettings, cup.CESettings, - cup.MHAOVSettings, cup.StringLengthSettings): + cup.MHAOVSettings, cup.StringLengthSettings, + cup.SuperSmootherSettings): with pytest.raises(ValidationError, match="must be <"): cls(minimum_frequency=10.0, maximum_frequency=1.0) # a valid ordering is accepted diff --git a/tests/test_diagnostics.py b/tests/test_diagnostics.py new file mode 100644 index 0000000..781ebd5 --- /dev/null +++ b/tests/test_diagnostics.py @@ -0,0 +1,237 @@ +"""Alias diagnostics: measured window peaks, alias scoring, both objective senses.""" + +from __future__ import annotations + +import numpy as np +import pytest + +import cuperiod as cup +from cuperiod.core.grid import GridSpec +from cuperiod.core.result import Periodogram +from cuperiod.diagnostics import CLASSIC_WINDOW_FREQUENCIES, alias_diagnostics +from synth import synthetic_multiband_sine + +#: Planted frequency (cycles/day); its daily aliases at 1.7 and 3.7 are in the grid. +F_TRUE = 2.7 + + +def nightly_light_curve( + *, + n_nights: int = 90, + per_night: int = 6, + night_length: float = 0.3, + noise: float = 0.01, + seed: int = 3, +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """A sine observed only in nightly windows — the classic 1 c/d alias generator.""" + rng = np.random.default_rng(seed) + nights = np.repeat(np.arange(n_nights, dtype=float), per_night) + time = np.sort(nights + rng.uniform(0.0, night_length, nights.size)) + 2458000.0 + mag = ( + 12.0 + + 0.3 * np.sin(2 * np.pi * F_TRUE * time) + + rng.normal(0.0, noise, time.size) + ) + return time, mag, np.full(time.size, noise) + + +def make_grid(nf: int = 4001, f_max: float = 6.0) -> GridSpec: + """A small explicit grid spanning the daily aliases and the second harmonic.""" + return GridSpec(kind="frequency", values=np.linspace(0.05, f_max, nf), uniform=True) + + +def find_candidate(report: cup.AliasReport, target: float, tol: float = 0.05): + """The first candidate predicted within ``tol`` of ``target``, or None.""" + for candidate in report.candidates: + if abs(candidate.frequency - target) <= tol: + return candidate + return None + + +@pytest.fixture(scope="module") +def nightly() -> tuple[np.ndarray, np.ndarray, np.ndarray]: + return nightly_light_curve() + + +@pytest.fixture(scope="module") +def nightly_gls(nightly: tuple[np.ndarray, ...]) -> Periodogram: + pg = cup.periodogram(nightly, "GLS", grid=make_grid(), backend="cpu") + assert isinstance(pg, Periodogram) + return pg + + +@pytest.fixture(scope="module") +def nightly_report( + nightly: tuple[np.ndarray, ...], nightly_gls: Periodogram +) -> cup.AliasReport: + return alias_diagnostics(nightly_gls, nightly, backend="cpu") + + +# --- measured spectral window ------------------------------------------------- + + +def test_window_finds_the_daily_peak(nightly_report: cup.AliasReport) -> None: + """Nightly sampling puts the strongest non-DC window peak at 1 cycle/day.""" + peaks = nightly_report.window_peaks + assert peaks + assert min(abs(p.frequency - 1.0) for p in peaks) < 0.02 + # Sorted strongest-first and ratioed to that leading peak. + assert peaks[0].amplitude_ratio == pytest.approx(1.0) + assert all(p.amplitude_ratio <= 1.0 + 1e-12 for p in peaks) + assert all(np.isfinite(p.amplitude) for p in peaks) + # The DC lobe is excluded, and the grid stops at the default 5.5 c/d. + assert all(0.02 < p.frequency <= 5.5 for p in peaks) + + +def test_rayleigh_is_one_over_baseline( + nightly_report: cup.AliasReport, nightly_gls: Periodogram +) -> None: + assert nightly_report.rayleigh == pytest.approx(1.0 / nightly_gls.baseline) + + +# --- alias candidates --------------------------------------------------------- + + +def test_daily_alias_is_a_serious_competitor(nightly_report: cup.AliasReport) -> None: + """The +/-1 c/d aliases are matched in the periodogram and score well.""" + assert nightly_report.best_frequency == pytest.approx(F_TRUE, rel=2e-3) + upper = find_candidate(nightly_report, F_TRUE + 1.0) + lower = find_candidate(nightly_report, F_TRUE - 1.0) + assert upper is not None and lower is not None + for candidate in (upper, lower): + assert candidate.matched + assert np.isfinite(candidate.power) + assert candidate.score > 0.2 + assert candidate.separation_rayleigh < 3.0 + assert "m=" in candidate.kind and not candidate.is_harmonic + # Sparse nightly sampling of a single sine is exactly the ambiguous case. + assert nightly_report.ambiguous is True + # Sorted by score, descending. + scores = [c.score for c in nightly_report.candidates] + assert scores == sorted(scores, reverse=True) + + +def test_harmonic_candidate_is_reported(nightly_report: cup.AliasReport) -> None: + """A pure sine still gets its 2f entry — listed, but never called ambiguous.""" + harmonics = [c for c in nightly_report.candidates if c.kind == "harmonic n=2"] + assert len(harmonics) == 1 + assert harmonics[0].frequency == pytest.approx( + 2.0 * nightly_report.best_frequency + ) + assert harmonics[0].is_harmonic + + +def test_candidates_stay_inside_the_grid( + nightly_report: cup.AliasReport, nightly_gls: Periodogram +) -> None: + """Out-of-range predictions (e.g. 3*f_true = 8.1 c/d) are dropped silently.""" + low, high = nightly_gls.frequency[0], nightly_gls.frequency[-1] + assert all(low <= c.frequency <= high for c in nightly_report.candidates) + assert not any(c.kind == "harmonic n=3" for c in nightly_report.candidates) + # Nothing is a restatement of the frequency being diagnosed. + rayleigh = nightly_report.rayleigh + assert all( + abs(c.frequency - nightly_report.best_frequency) >= rayleigh + for c in nightly_report.candidates + ) + + +def test_explicit_frequency_is_diagnosed( + nightly: tuple[np.ndarray, ...], nightly_gls: Periodogram +) -> None: + """``frequency=`` overrides the periodogram's own best peak.""" + report = alias_diagnostics( + nightly_gls, nightly, frequency=F_TRUE / 2.0, backend="cpu" + ) + assert report.best_frequency == pytest.approx(F_TRUE / 2.0) + assert np.isfinite(report.best_power) + harmonic = next(c for c in report.candidates if c.kind == "harmonic n=2") + assert harmonic.frequency == pytest.approx(F_TRUE) + # The real peak, reached here as the harmonic, beats the half-frequency. + assert harmonic.score > 1.0 + + +# --- no light curve: the classic suspects ------------------------------------- + + +def test_classic_suspects_without_data(nightly_gls: Periodogram) -> None: + """Without a light curve the textbook alias spacings stand in for the window.""" + report = alias_diagnostics(nightly_gls) + assert [p.frequency for p in report.window_peaks] == [ + f for _label, f in CLASSIC_WINDOW_FREQUENCIES + ] + assert all(np.isnan(p.amplitude) for p in report.window_peaks) + assert all(np.isnan(p.amplitude_ratio) for p in report.window_peaks) + assert report.candidates + sidereal = find_candidate(report, F_TRUE + 1.0) + assert sidereal is not None + assert sidereal.kind.startswith("sidereal-day-alias m=+1") + assert sidereal.score > 0.2 + # The yearly spacing is unresolvable on a 90-day baseline: no candidate for it. + assert not any("year" in c.kind for c in report.candidates) + + +# --- minimized statistics ------------------------------------------------------ + + +def test_min_sense_periodogram(nightly: tuple[np.ndarray, ...]) -> None: + """PDM (smaller theta is better) is scored on the same 0-1 scale, no crash.""" + pg = cup.periodogram(nightly, "PDM", grid=make_grid(1001), backend="cpu") + assert isinstance(pg, Periodogram) + assert pg.objective_sense == "min" + report = alias_diagnostics(pg, nightly, backend="cpu") + assert report.best_frequency == pytest.approx(F_TRUE, rel=5e-3) + assert np.isfinite(report.best_power) + assert report.candidates + matched = [c for c in report.candidates if c.matched] + assert matched + assert all(np.isfinite(c.score) and np.isfinite(c.power) for c in matched) + assert all(c.score >= 0.0 for c in report.candidates) + alias = find_candidate(report, F_TRUE - 1.0) + assert alias is not None and alias.score > 0.2 + + +def test_summary_is_printable(nightly_report: cup.AliasReport) -> None: + text = nightly_report.summary() + assert text + assert len(text.splitlines()) >= 4 + assert f"{nightly_report.best_period:.8g}" in text + assert "AMBIGUOUS" in text + assert nightly_report.candidates[0].kind in text + + +# --- other inputs and guards --------------------------------------------------- + + +def test_multiband_input(nightly_gls: Periodogram) -> None: + """A MultiBandLightCurve's bands are stacked into one sampling for the window.""" + bands = synthetic_multiband_sine( + band_points=(80, 60), amplitudes=(0.30, 0.22), offsets=(15.0, 14.2), + period=1.0 / F_TRUE, + ) + mblc = cup.MultiBandLightCurve.from_light_curves( + {n: cup.LightCurve.from_arrays(t, m, e) for n, (t, m, e) in bands.items()} + ) + pg = cup.periodogram(mblc, "GLS", grid=make_grid(), backend="cpu") + assert isinstance(pg, Periodogram) + report = alias_diagnostics(pg, mblc, backend="cpu") + assert report.best_frequency == pytest.approx(F_TRUE, rel=2e-3) + assert report.window_peaks + assert report.candidates + assert np.isfinite(report.rayleigh) + # Stacking both bands gives the full 180-day baseline, not one band's. + assert report.rayleigh == pytest.approx(1.0 / pg.baseline) + + +def test_empty_periodogram_raises() -> None: + empty = Periodogram.from_spectrum( + method="GLS", + backend="finufft", + frequency=np.empty(0), + power=np.empty(0), + objective_sense="max", + n_samples=0, + baseline=10.0, + ) + with pytest.raises(ValueError, match="empty"): + alias_diagnostics(empty) diff --git a/tests/test_fast_backends.py b/tests/test_fast_backends.py index 79be5f1..39b25fe 100644 --- a/tests/test_fast_backends.py +++ b/tests/test_fast_backends.py @@ -82,7 +82,8 @@ def test_numba_tls_matches_numpy() -> None: @requires_numba def test_cpu_request_resolves_to_numba() -> None: - for name in ("PDM", "CE", "STRINGLENGTH", "MHAOV", "TLS", "BLS"): + for name in ("PDM", "CE", "STRINGLENGTH", "MHAOV", "TLS", "BLS", + "SUPERSMOOTHER"): assert cup.get_method(name).resolve_backend("cpu") == "numba" diff --git a/tests/test_interop.py b/tests/test_interop.py new file mode 100644 index 0000000..8ad7107 --- /dev/null +++ b/tests/test_interop.py @@ -0,0 +1,444 @@ +"""LINCC-stack interoperability: nested-pandas row-wise and partition-wise adapters.""" + +from __future__ import annotations + +import pickle + +import numpy as np +import pytest + +pytest.importorskip("nested_pandas") + +import pandas as pd # noqa: E402 +from nested_pandas import NestedFrame # noqa: E402 + +import cuperiod as cup # noqa: E402 +from cuperiod.core.errors import ColumnResolutionError # noqa: E402 +from cuperiod.interop import ( # noqa: E402 + COLUMN_PRESETS, + PRESET_KEYS, + nested_periodogram, + partition_periodogram, + resolve_nested_columns, +) + +PERIOD = 0.7 +F_TRUE = 1.0 / PERIOD +N_OBJECTS = 6 # the last one is the 3-point object that must come back NaN +N_POINTS = 60 +BASELINE = 30.0 + +Arrays = tuple[np.ndarray, np.ndarray, np.ndarray] + + +def make_grid(nf: int = 601, half_width: float = 0.35) -> cup.GridSpec: + """A narrow uniform frequency grid bracketing the planted frequency.""" + freq = np.linspace(F_TRUE - half_width, F_TRUE + half_width, nf) + return cup.GridSpec(kind="frequency", values=freq, uniform=True) + + +def _sine(rng: np.random.Generator, n: int, phase: float) -> Arrays: + time = np.sort(rng.uniform(0.0, BASELINE, n)) + mag = 15.0 + 0.3 * np.sin(2 * np.pi * time / PERIOD + phase) + return time, mag + rng.normal(0.0, 0.005, n), np.full(n, 0.01) + + +def make_objects(seed: int = 11) -> list[Arrays]: + """Per-object ``(time, mag, err)``; the last object has only 3 points.""" + rng = np.random.default_rng(seed) + return [ + _sine(rng, 3 if i == N_OBJECTS - 1 else N_POINTS, phase=0.3 * i) + for i in range(N_OBJECTS) + ] + + +def frame_from_objects(objects: list[Arrays]) -> NestedFrame: + """Nest ``(time, mag, err)`` per object as ``lc.hmjd``/``lc.mag``/``lc.magerr``.""" + flat = pd.DataFrame( + { + "id": np.concatenate( + [np.full(t.size, i) for i, (t, _, _) in enumerate(objects)] + ), + "hmjd": np.concatenate([t for t, _, _ in objects]), + "mag": np.concatenate([m for _, m, _ in objects]), + "magerr": np.concatenate([e for _, _, e in objects]), + } + ).set_index("id") + base = pd.DataFrame( + {"id": np.arange(len(objects)), "ra": np.arange(len(objects)) * 1.0} + ).set_index("id") + return NestedFrame(base).join_nested(flat, name="lc") + + +def make_frame(seed: int = 11) -> NestedFrame: + return frame_from_objects(make_objects(seed)) + + +def make_multiband_frame(seed: int = 5) -> NestedFrame: + """Two bands per object inside the nest (``lc.band``), same planted period.""" + rng = np.random.default_rng(seed) + ids, times, mags, errs, bands = [], [], [], [], [] + for i in range(4): + for offset, name in ((15.0, "g"), (14.2, "r")): + time, mag, err = _sine(rng, 40, phase=0.4 * i) + ids.append(np.full(time.size, i)) + times.append(time) + mags.append(mag - 15.0 + offset) + errs.append(err) + bands.append(np.full(time.size, name, dtype=object)) + flat = pd.DataFrame( + { + "id": np.concatenate(ids), + "hmjd": np.concatenate(times), + "mag": np.concatenate(mags), + "magerr": np.concatenate(errs), + "band": np.concatenate(bands), + } + ).set_index("id") + base = pd.DataFrame({"id": np.arange(4), "ra": np.arange(4) * 1.0}).set_index("id") + return NestedFrame(base).join_nested(flat, name="lc") + + +def make_rubin_frame(columns: tuple[str, ...] | None = None) -> NestedFrame: + """A synthetic frame with the verified Rubin DP1 names and negative fluxes.""" + rng = np.random.default_rng(3) + n = 40 + time = np.sort(rng.uniform(0.0, BASELINE, n)) + # Difference-imaging fluxes straddle zero: no magnitude exists for half of them. + flux = 5.0 + 20.0 * np.sin(2 * np.pi * time / PERIOD) + with np.errstate(invalid="ignore", divide="ignore"): + psf_mag = 31.4 - 2.5 * np.log10(flux) + nest = { + "midpointMjdTai": time, + "psfFlux": flux, + "psfFluxErr": np.full(n, 1.0), + "psfMag": psf_mag, + "band": np.array(["g", "r"] * (n // 2), dtype=object), + } + keep = nest if columns is None else {k: nest[k] for k in columns} + flat = pd.DataFrame({"id": np.zeros(n, dtype=int), **keep}).set_index("id") + base = pd.DataFrame({"id": [0], "ra": [1.0]}).set_index("id") + return NestedFrame(base).join_nested(flat, name="objectForcedSource") + + +# --- tier 1: row-wise --------------------------------------------------------- + + +def test_nested_periodogram_recovers_period() -> None: + """Every well-sampled row recovers the planted period; the tiny one is NaN.""" + out = nested_periodogram(make_frame(), "lc", grid=make_grid()) + assert isinstance(out, NestedFrame) + periods = out["best_period"].to_numpy() + assert periods.size == N_OBJECTS + assert np.allclose(periods[:-1], PERIOD, rtol=2e-2) + assert np.isnan(periods[-1]) + assert np.isnan(out["best_power"].to_numpy()[-1]) + assert np.all(np.isfinite(out["best_power"].to_numpy()[:-1])) + + +def test_nested_periodogram_appends_and_keeps_base_columns() -> None: + out = nested_periodogram(make_frame(), "lc", grid=make_grid(), append_columns=True) + assert "ra" in out.columns + assert "lc" in out.columns + assert {"best_period", "best_power", "fap"} <= set(out.columns) + + +def test_nested_periodogram_without_append_returns_results_only() -> None: + out = nested_periodogram(make_frame(), "lc", grid=make_grid(), append_columns=False) + assert list(out.columns) == ["best_period", "best_power", "fap"] + + +def test_prefix_and_n_best_column_names() -> None: + out = nested_periodogram( + make_frame(), "lc", grid=make_grid(), n_best=3, prefix="gls_", + append_columns=False, + ) + assert list(out.columns) == [ + "gls_best_period", "gls_best_power", "gls_fap", "gls_period_2", "gls_period_3", + ] + assert out["gls_best_period"].to_numpy()[0] == pytest.approx(PERIOD, rel=2e-2) + assert np.all(np.isnan(out.iloc[-1].to_numpy())) + + +def test_fap_column_is_populated_for_gls() -> None: + """GLS reports a false-alarm probability at the best peak.""" + out = nested_periodogram(make_frame(), "lc", grid=make_grid(), append_columns=False) + fap = out["fap"].to_numpy() + assert np.all(np.isfinite(fap[:-1])) + assert np.isnan(fap[-1]) + + +def test_fap_is_nan_when_the_method_reports_none() -> None: + out = nested_periodogram( + make_frame(), + "lc", + grid=make_grid(), + settings=cup.GLSSettings(fap_method="none"), + append_columns=False, + ) + assert np.all(np.isnan(out["fap"].to_numpy())) + assert out["best_period"].to_numpy()[0] == pytest.approx(PERIOD, rel=2e-2) + + +def test_dotted_and_bare_column_names_agree() -> None: + frame, grid = make_frame(), make_grid() + bare = nested_periodogram( + frame, "lc", time="hmjd", value="mag", error="magerr", + grid=grid, append_columns=False, + ) + dotted = nested_periodogram( + frame, "lc", time="lc.hmjd", value="lc.mag", error="lc.magerr", + grid=grid, append_columns=False, + ) + assert np.allclose( + bare["best_period"].to_numpy(), dotted["best_period"].to_numpy(), + rtol=1e-12, equal_nan=True, + ) + + +# --- multi-band --------------------------------------------------------------- + + +def test_multiband_in_nest_band_recovers_period() -> None: + out = nested_periodogram( + make_multiband_frame(), "lc", band="lc.band", grid=make_grid(), + append_columns=False, + ) + periods = out["best_period"].to_numpy() + assert periods.size == 4 + assert np.allclose(periods, PERIOD, rtol=2e-2) + + +def test_band_is_not_auto_detected() -> None: + """A nest with a band sub-column stays single-band unless band= is given.""" + frame = make_multiband_frame() + assert resolve_nested_columns(frame, "lc").band is None + assert resolve_nested_columns(frame, "lc", band="band").band == "lc.band" + + +def test_multiband_with_single_band_method_raises() -> None: + """TLS has no multi-band model: raise up front, never a frame of NaNs.""" + frame, grid = make_multiband_frame(), make_grid() + for run in (nested_periodogram, partition_periodogram): + with pytest.raises(ValueError, match="does not support multi-band"): + run(frame, "lc", band="lc.band", method="TLS", grid=grid) + + +def test_unknown_band_column_raises() -> None: + with pytest.raises(ColumnResolutionError, match="band column"): + nested_periodogram(make_frame(), "lc", band="filterid", grid=make_grid()) + + +# --- tier 2: partition-wise --------------------------------------------------- + + +def test_partition_matches_row_wise() -> None: + frame, grid = make_frame(), make_grid() + row_wise = nested_periodogram(frame, "lc", grid=grid, append_columns=False) + batched = partition_periodogram(frame, "lc", grid=grid) + assert isinstance(batched, pd.DataFrame) + assert list(batched.columns) == ["best_period", "best_power", "fap"] + assert np.allclose( + batched["best_period"].to_numpy(), row_wise["best_period"].to_numpy(), + rtol=1e-9, equal_nan=True, + ) + # The batched tier reuses one bucketed NUFFT plan for every object, so its powers + # agree with the per-object transforms to the NUFFT tolerance, not bit for bit. + assert np.allclose( + batched["best_power"].to_numpy(), row_wise["best_power"].to_numpy(), + rtol=1e-6, equal_nan=True, + ) + assert np.isnan(batched["best_period"].to_numpy()[-1]) + + +def test_partition_multiband_matches_row_wise() -> None: + frame, grid = make_multiband_frame(), make_grid() + row_wise = nested_periodogram( + frame, "lc", band="lc.band", grid=grid, append_columns=False + ) + batched = partition_periodogram(frame, "lc", band="lc.band", grid=grid) + assert np.allclose( + batched["best_period"].to_numpy(), row_wise["best_period"].to_numpy(), rtol=1e-9 + ) + + +def test_partition_preserves_index_and_n_best() -> None: + out = partition_periodogram( + make_frame(), "lc", grid=make_grid(), n_best=2, prefix="p_" + ) + assert list(out.columns) == ["p_best_period", "p_best_power", "p_fap", "p_period_2"] + assert out.index.equals(make_frame().index) + + +def test_partition_on_empty_frame_returns_typed_empty() -> None: + out = partition_periodogram(make_frame().iloc[:0], "lc", grid=make_grid()) + assert isinstance(out, pd.DataFrame) + assert len(out) == 0 + assert list(out.columns) == ["best_period", "best_power", "fap"] + assert all(dtype == np.float64 for dtype in out.dtypes) + + +def test_partition_slices_each_object_correctly() -> None: + """Ragged nests: every object's slice must carry exactly its own epochs.""" + objects, grid = make_objects(), make_grid() + batched = partition_periodogram(frame_from_objects(objects), "lc", grid=grid) + for i, (time, mag, err) in enumerate(objects[:-1]): + pg = cup.periodogram((time, mag, err), "GLS", grid=grid) + assert isinstance(pg, cup.Periodogram) + assert batched["best_period"].to_numpy()[i] == pytest.approx( + pg.best_period(), rel=1e-12 + ) + + +# --- the lsdb (lazy catalog) branch ------------------------------------------ + + +class _FakeCatalog: + """Duck-typed stand-in for a lazy lsdb ``Catalog`` (lsdb is not a test dep). + + Mirrors the two lsdb entry points the adapter uses: ``map_rows`` with a mandatory + ``meta`` keyword and ``map_partitions`` with an optional one. + """ + + def __init__(self, frame: NestedFrame) -> None: + self._frame = frame + self.meta: object = None + + @property + def dtypes(self) -> pd.Series: + return self._frame.dtypes + + def map_rows(self, func: object, columns: object = None, *, meta: object, + **kwargs: object) -> NestedFrame: + self.meta = meta + return self._frame.map_rows(func, columns, **kwargs) # type: ignore[arg-type] + + def map_partitions(self, func: object, *args: object, meta: object = None, + **kwargs: object) -> pd.DataFrame: + self.meta = meta + return func(self._frame) # type: ignore[operator] + + +_FakeCatalog.__module__ = "lsdb.catalog.catalog" + + +def test_catalog_path_passes_auto_built_meta() -> None: + catalog = _FakeCatalog(make_frame()) + out = nested_periodogram( + catalog, "lc", grid=make_grid(), n_best=2, append_columns=True + ) + assert catalog.meta == { + "best_period": float, "best_power": float, "fap": float, "period_2": float, + } + assert out["best_period"].to_numpy()[0] == pytest.approx(PERIOD, rel=2e-2) + + +def test_catalog_partition_path_passes_empty_typed_meta() -> None: + catalog = _FakeCatalog(make_frame()) + out = partition_periodogram(catalog, "lc", grid=make_grid()) + meta = catalog.meta + assert isinstance(meta, pd.DataFrame) + assert len(meta) == 0 + assert list(meta.columns) == ["best_period", "best_power", "fap"] + assert all(dtype == np.float64 for dtype in meta.dtypes) + assert out["best_period"].to_numpy()[0] == pytest.approx(PERIOD, rel=2e-2) + + +def test_explicit_meta_is_forwarded_unchanged() -> None: + catalog = _FakeCatalog(make_frame()) + custom = {"best_period": "float64", "best_power": "float64", "fap": "float64"} + nested_periodogram(catalog, "lc", grid=make_grid(), meta=custom) + assert catalog.meta is custom + + +def test_kernels_are_picklable() -> None: + """dask ships the kernel to workers; it must never carry a compute engine.""" + from cuperiod.interop.lincc import _PartitionKernel, _RowKernel + + columns = resolve_nested_columns(make_frame(), "lc") + for cls in (_RowKernel, _PartitionKernel): + kernel = cls( + columns=columns, method="GLS", settings=cup.GLSSettings(), + backend="cpu", grid=make_grid(), n_best=2, prefix="p_", + ) + kernel.prepare() + clone = pickle.loads(pickle.dumps(kernel)) + assert clone.out_columns == kernel.out_columns + assert clone.columns == columns + + +# --- presets and column resolution ------------------------------------------- + + +def test_presets_have_the_documented_keys() -> None: + assert set(COLUMN_PRESETS) == { + "ztf_dr22", "ztf_alerts", "rubin_dp1_object", "rubin_dp1_dia", + } + for name, entry in COLUMN_PRESETS.items(): + assert set(entry) == set(PRESET_KEYS), name + assert isinstance(entry["nested"], str) + assert isinstance(entry["time"], str) + assert isinstance(entry["value"], str) + assert entry["domain"] in (cup.Domain.MAGNITUDE, cup.Domain.FLUX) + + +def test_ztf_dr22_preset_has_no_in_nest_band() -> None: + """DR22 keeps the filter in the base column ``filterid`` (one row per filter).""" + assert COLUMN_PRESETS["ztf_dr22"]["band"] is None + assert COLUMN_PRESETS["ztf_alerts"]["band"] == "lc_fid" + + +def test_rubin_presets_search_in_flux() -> None: + for name in ("rubin_dp1_object", "rubin_dp1_dia"): + assert COLUMN_PRESETS[name]["domain"] is cup.Domain.FLUX + + +def test_rubin_preset_resolves_columns_and_flux_domain() -> None: + columns = resolve_nested_columns(make_rubin_frame(), preset="rubin_dp1_object") + assert columns.nested == "objectForcedSource" + assert columns.time == "objectForcedSource.midpointMjdTai" + assert columns.value == "objectForcedSource.psfFlux" + assert columns.error == "objectForcedSource.psfFluxErr" + assert columns.band == "objectForcedSource.band" + assert columns.domain is cup.Domain.FLUX + assert columns.subcolumns == ["midpointMjdTai", "psfFlux", "psfFluxErr", "band"] + + +def test_rubin_preset_runs_on_negative_fluxes() -> None: + """Difference-imaging flux straddles zero; the flux-domain search must not care.""" + out = nested_periodogram( + make_rubin_frame(), preset="rubin_dp1_object", grid=make_grid(), + append_columns=False, + ) + assert out["best_period"].to_numpy()[0] == pytest.approx(PERIOD, rel=2e-2) + + +def test_preset_error_and_band_are_dropped_when_absent() -> None: + """A preset must not demand columns the nest does not carry.""" + frame = make_rubin_frame(columns=("midpointMjdTai", "psfFlux")) + columns = resolve_nested_columns(frame, preset="rubin_dp1_object") + assert columns.error is None + assert columns.band is None + assert columns.domain is cup.Domain.FLUX + assert columns.read_columns == [ + "objectForcedSource.midpointMjdTai", "objectForcedSource.psfFlux", + ] + + +def test_missing_nested_column_raises() -> None: + with pytest.raises(ColumnResolutionError, match="no nested column"): + resolve_nested_columns(make_frame(), "sources") + + +def test_unknown_preset_raises() -> None: + with pytest.raises(ValueError, match="unknown preset"): + resolve_nested_columns(make_frame(), preset="nope") + + +def test_auto_detection_without_preset() -> None: + columns = resolve_nested_columns(make_frame(), "lc") + assert (columns.time, columns.value, columns.error) == ( + "lc.hmjd", "lc.mag", "lc.magerr", + ) + assert columns.domain is cup.Domain.MAGNITUDE + assert columns.read_columns == ["lc.hmjd", "lc.mag", "lc.magerr"] diff --git a/tests/test_multiband_fap.py b/tests/test_multiband_fap.py new file mode 100644 index 0000000..5a30423 --- /dev/null +++ b/tests/test_multiband_fap.py @@ -0,0 +1,124 @@ +"""Within-band bootstrap false-alarm statistics for the multi-band GLS.""" + +from __future__ import annotations + +import numpy as np +import pytest + +import cuperiod as cup +from conftest import requires_gpu +from cuperiod.core.grid import GridSpec +from synth import synthetic_multiband_sine + +PERIOD = 0.7365 + + +def make_grid(nf: int = 3001) -> GridSpec: + return GridSpec( + kind="frequency", values=np.linspace(0.05, 6.0, nf), uniform=True + ) + + +def signal_mblc() -> cup.MultiBandLightCurve: + bands = synthetic_multiband_sine(period=PERIOD) + return cup.MultiBandLightCurve.from_light_curves( + {n: cup.LightCurve.from_arrays(t, m, e) for n, (t, m, e) in bands.items()} + ) + + +def noise_mblc(seed: int = 5) -> cup.MultiBandLightCurve: + bands = synthetic_multiband_sine(amplitudes=(0.0, 0.0, 0.0), seed=seed) + return cup.MultiBandLightCurve.from_light_curves( + {n: cup.LightCurve.from_arrays(t, m, e) for n, (t, m, e) in bands.items()} + ) + + +def test_planted_signal_hits_resolution_floor() -> None: + grid = make_grid() + calib = cup.multiband_fap( + signal_mblc(), grid=grid, backend="finufft", n_bootstrap=100, seed=1 + ) + pg = cup.periodogram(signal_mblc(), "GLS", backend="finufft", grid=grid) + assert isinstance(pg, cup.Periodogram) + fap = calib.fap(float(pg.power.max())) + assert fap == pytest.approx(1.0 / 101.0) + + +def test_noise_is_not_flagged() -> None: + grid = make_grid() + calib = cup.multiband_fap( + noise_mblc(), grid=grid, backend="finufft", n_bootstrap=100, seed=1 + ) + pg = cup.periodogram(noise_mblc(), "GLS", backend="finufft", grid=grid) + assert isinstance(pg, cup.Periodogram) + assert calib.fap(float(pg.power.max())) > 0.02 + + +def test_seed_determinism_and_level() -> None: + grid = make_grid(1001) + a = cup.multiband_fap( + noise_mblc(), grid=grid, backend="finufft", n_bootstrap=60, seed=9 + ) + b = cup.multiband_fap( + noise_mblc(), grid=grid, backend="finufft", n_bootstrap=60, seed=9 + ) + assert np.array_equal(a.null_max, b.null_max) + level = a.level(0.1) + assert a.fap(level) <= 0.2 + with pytest.raises(ValueError, match="n_bootstrap"): + a.level(1e-4) + + +def test_settings_wire_fap_into_extras() -> None: + grid = make_grid(2001) + settings = cup.GLSSettings(mb_fap_bootstrap=50, mb_fap_seed=2) + pg = cup.periodogram( + signal_mblc(), "GLS", backend="finufft", grid=grid, settings=settings + ) + assert isinstance(pg, cup.Periodogram) + fap = pg.extras["fap"] + best = int(np.argmax(pg.power)) + assert np.isfinite(fap[best]) and fap[best] <= 1.0 / 51.0 + 1e-12 + assert np.isnan(fap).sum() > fap.size // 2 # NaN away from local maxima + assert pg.meta["fap_method"] == "bootstrap" + assert "fap_level_10pct" in pg.meta + + +@requires_gpu +def test_gpu_null_distribution_matches_cpu() -> None: + grid = make_grid(2001) + cpu = cup.multiband_fap( + signal_mblc(), grid=grid, backend="finufft", n_bootstrap=50, seed=3 + ) + gpu = cup.multiband_fap( + signal_mblc(), grid=grid, backend="cufinufft", n_bootstrap=50, seed=3 + ) + assert np.allclose(cpu.null_max, gpu.null_max, atol=1e-7) + + +def test_single_band_input_supported() -> None: + bands = synthetic_multiband_sine(band_points=(70,), amplitudes=(0.3,), + offsets=(14.0,)) + (t, m, e) = bands["b0"] + lc = cup.LightCurve.from_arrays(t, m, e) + calib = cup.multiband_fap( + lc, grid=make_grid(1001), backend="finufft", n_bootstrap=30, seed=0 + ) + assert calib.null_max.size == 30 + assert calib.model == "offsets" + + +def test_astropy_backend_rejected() -> None: + with pytest.raises(ValueError, match="native backend"): + cup.multiband_fap(signal_mblc(), backend="astropy", n_bootstrap=10) + + +def test_flex_model_uses_loop_path() -> None: + settings = cup.GLSSettings(mb_model="flex") + calib = cup.multiband_fap( + signal_mblc(), settings, grid=make_grid(501), backend="finufft", + n_bootstrap=5, seed=4, + ) + assert calib.model == "flex" + assert calib.null_max.size == 5 + assert np.all(calib.null_max > 0.0) diff --git a/tests/test_multiband_fold.py b/tests/test_multiband_fold.py new file mode 100644 index 0000000..8424a41 --- /dev/null +++ b/tests/test_multiband_fold.py @@ -0,0 +1,136 @@ +"""Pooled multi-band fold methods (PDM, CE, string-length). + +Period recovery across two filters, the single-band collapse (the pooling weights must +reduce to the single-band statistic exactly), the too-few-points guard, and parity of +the pooled statistic across every backend. +""" + +from __future__ import annotations + +import numpy as np +import pytest + +import cuperiod as cup +from conftest import requires_gpu, requires_numba, requires_torch +from cuperiod.core.errors import InsufficientDataError +from synth import synthetic_sine + +#: Planted period of the two-band synthetic (days); 1/0.6234 = 1.604 cycles/day. +PERIOD = 0.6234 + +#: Explicit trial grid bracketing the true frequency. Bounded above the first +#: subharmonic (as in the single-band string-length test, where overlaid copies of the +#: fold also shorten the string) and small enough to stay fast on every backend. +GRID = cup.GridSpec(kind="frequency", values=np.linspace(1.0, 2.5, 1200), uniform=True) + +#: The pooled fold methods, spelled as a user would. +FOLD_METHODS = ("PDM", "CE", "StringLength", "SuperSmoother") + + +def _two_band(period: float = PERIOD) -> cup.MultiBandLightCurve: + """Two bands of one star: different amplitude, offset mean, independent noise.""" + tg, mg, eg = synthetic_sine(n=300, period=period, amp=0.4, seed=2) + tr, mr, er = synthetic_sine(n=300, period=period, amp=0.25, seed=3) + return cup.MultiBandLightCurve.from_light_curves( + { + "g": cup.LightCurve.from_arrays(tg, mg, eg), + "r": cup.LightCurve.from_arrays(tr, mr + 1.3, er), + } + ) + + +# --- period recovery ---------------------------------------------------------- + + +@pytest.mark.parametrize("method", FOLD_METHODS) +def test_multiband_fold_recovers_period(method: str) -> None: + pg = cup.periodogram(_two_band(), method, grid=GRID) + assert pg.objective_sense == cup.get_method(method).objective_sense + assert pg.meta["bands"] == ("g", "r") + assert pg.n_samples == 600 # both bands' points + assert pg.best_period() == pytest.approx(PERIOD, rel=2e-2) + + +# --- single-band collapse ----------------------------------------------------- + + +@pytest.mark.parametrize("method", FOLD_METHODS) +def test_single_band_collapses_to_the_single_band_statistic(method: str) -> None: + # With one band the pooling weights cancel (w/w = 1), so the multi-band statistic + # must reproduce the single-band periodogram on the same grid to round-off. + t, mag, err = synthetic_sine(n=300, period=PERIOD, seed=2) + lc = cup.LightCurve.from_arrays(t, mag, err) + mb = cup.MultiBandLightCurve.from_light_curves({"g": lc}) + pooled = cup.periodogram(mb, method, grid=GRID, backend="numpy") + single = cup.periodogram(lc, method, grid=GRID, backend="numpy") + assert np.allclose(pooled.power, single.power, rtol=1e-12) + assert np.array_equal(pooled.frequency, single.frequency) + assert pooled.n_samples == single.n_samples + + +# --- guards ------------------------------------------------------------------- + + +@pytest.mark.parametrize("method", FOLD_METHODS) +def test_bands_below_the_minimum_point_count_raise(method: str) -> None: + # Five points per band is below every method's floor (n_bins + 2 for PDM, + # max(n_phase_bins, 8) for CE, 8 for string length). + rng = np.random.default_rng(0) + bands = { + name: cup.LightCurve.from_arrays( + np.sort(rng.uniform(0.0, 5.0, 5)), rng.normal(12.0, 0.1, 5) + ) + for name in ("g", "r") + } + mb = cup.MultiBandLightCurve.from_light_curves(bands) + with pytest.raises(InsufficientDataError): + cup.periodogram(mb, method, grid=GRID) + + +# --- backend parity ----------------------------------------------------------- +# +# ``precision="auto"`` is float64 on CUDA, so the fast backends agree with the +# vectorized numpy path to atomic-reordering round-off, not to float32 precision. + + +def _pooled_power(method: str, backend: str) -> np.ndarray: + pg = cup.periodogram(_two_band(), method, grid=GRID, backend=backend) + return pg.power + + +@requires_numba +@pytest.mark.parametrize("method", FOLD_METHODS) +def test_numba_multiband_matches_numpy(method: str) -> None: + cpu = _pooled_power(method, "numpy") + fast = _pooled_power(method, "numba") + assert np.allclose(cpu, fast, rtol=1e-6, atol=1e-9) + + +@requires_gpu +@pytest.mark.parametrize("method", FOLD_METHODS) +def test_cupy_multiband_matches_numpy(method: str) -> None: + cpu = _pooled_power(method, "numpy") + gpu = _pooled_power(method, "cupy") + assert np.allclose(cpu, gpu, rtol=1e-6, atol=1e-9) + + +@requires_torch +@pytest.mark.parametrize("method", FOLD_METHODS) +def test_torch_multiband_matches_numpy(method: str) -> None: + # A bare "torch" request must be normalized to "torch:" by the method's + # multiband_power, exactly as its single-band power does. + cpu = _pooled_power(method, "numpy") + pg = cup.periodogram(_two_band(), method, grid=GRID, backend="torch") + assert pg.backend.startswith("torch:") + assert np.allclose(cpu, pg.power, rtol=1e-6, atol=1e-9) + + +# --- registry ----------------------------------------------------------------- + + +def test_fold_methods_report_multiband_support() -> None: + support = {info.name: info.supports_multiband for info in cup.list_methods()} + assert support["PDM"] and support["CE"] and support["STRINGLENGTH"] + assert support["SUPERSMOOTHER"] + for name in FOLD_METHODS: + assert cup.get_method(name).supports_multiband diff --git a/tests/test_multiband_gls.py b/tests/test_multiband_gls.py new file mode 100644 index 0000000..7e9fa1c --- /dev/null +++ b/tests/test_multiband_gls.py @@ -0,0 +1,214 @@ +"""Native multi-band GLS: astropy parity, backend parity, and model behavior.""" + +from __future__ import annotations + +import numpy as np +import pytest + +import cuperiod as cup +from conftest import requires_gpu, requires_torch +from cuperiod.core.errors import InsufficientDataError +from cuperiod.core.grid import GridSpec +from cuperiod.multiband.gls_mb import gls_multiband_power +from synth import synthetic_multiband_sine + +PERIOD = 0.7365 +F_TRUE = 1.0 / PERIOD + + +def make_mblc(**kwargs: object) -> cup.MultiBandLightCurve: + bands = synthetic_multiband_sine(period=PERIOD, **kwargs) # type: ignore[arg-type] + return cup.MultiBandLightCurve.from_light_curves( + {name: cup.LightCurve.from_arrays(t, m, e) for name, (t, m, e) in bands.items()} + ) + + +def make_grid(nf: int = 4001, f_max: float = 6.0) -> GridSpec: + freq = np.linspace(0.05, f_max, nf) + return GridSpec(kind="frequency", values=freq, uniform=True) + + +# --- model math vs the astropy reference ------------------------------------- + + +def test_offsets_matches_astropy_flex_1_0() -> None: + """The closed-form offsets model equals astropy's ridge-regularized (1, 0).""" + mb, grid = make_mblc(), make_grid() + s = cup.GLSSettings() + native = gls_multiband_power(grid, mb, s, "finufft").power + reference = gls_multiband_power(grid, mb, s, "astropy").power + assert np.allclose(native, reference, atol=2e-4) + + +@pytest.mark.parametrize(("nb", "nk"), [(1, 1), (2, 1), (0, 1), (1, 0)]) +def test_flex_matches_astropy(nb: int, nk: int) -> None: + """The sufficient-statistics flex path reproduces astropy's flexible solver.""" + mb, grid = make_mblc(), make_grid() + s = cup.GLSSettings(mb_model="flex", mb_nterms_base=nb, mb_nterms_band=nk) + native = gls_multiband_power(grid, mb, s, "finufft").power + reference = gls_multiband_power(grid, mb, s, "astropy").power + assert np.allclose(native, reference, atol=1e-8) + + +def test_flex_absolute_ridge_matches_astropy() -> None: + """regularize_by_trace=False needs astropy's raw 1/dy^2 normal-matrix scale.""" + mb, grid = make_mblc(), make_grid() + s = cup.GLSSettings( + mb_model="flex", + mb_reg_base=1e-3, + mb_reg_band=1e-2, + mb_regularize_by_trace=False, + ) + native = gls_multiband_power(grid, mb, s, "finufft").power + reference = gls_multiband_power(grid, mb, s, "astropy").power + assert np.allclose(native, reference, atol=1e-8) + + +def test_perband_close_to_astropy_flex_0_1() -> None: + """The chi2_0-weighted per-band combination is the (0, 1) model up to ridge.""" + mb, grid = make_mblc(), make_grid() + s = cup.GLSSettings(mb_model="perband") + native = gls_multiband_power(grid, mb, s, "finufft").power + reference = gls_multiband_power(grid, mb, s, "astropy").power + assert np.allclose(native, reference, atol=5e-3) + + +def test_offsets_single_band_collapses_to_single_band_gls() -> None: + """With one band, the offsets model is exactly the floating-mean GLS.""" + bands = synthetic_multiband_sine(band_points=(80,), amplitudes=(0.25,), + offsets=(12.0,), seed=7) + (t, m, e) = bands["b0"] + lc = cup.LightCurve.from_arrays(t, m, e) + mb1 = cup.MultiBandLightCurve.from_light_curves({"g": lc}) + grid = make_grid() + pg_mb = gls_multiband_power(grid, mb1, cup.GLSSettings(), "finufft") + pg_sb = cup.periodogram(lc, "GLS", backend="finufft", grid=grid) + assert isinstance(pg_sb, cup.Periodogram) + assert np.allclose(pg_mb.power, pg_sb.power, atol=1e-9) + + +@pytest.mark.parametrize("model", ["offsets", "perband", "flex"]) +def test_models_recover_planted_period(model: str) -> None: + mb, grid = make_mblc(), make_grid() + s = cup.GLSSettings(mb_model=model) # type: ignore[arg-type] + pg = gls_multiband_power(grid, mb, s, "finufft") + assert pg.best_period() == pytest.approx(PERIOD, rel=2e-3) + + +def test_unweighted_bands_match_astropy() -> None: + """Bands without errors run unweighted and still match the reference.""" + bands = synthetic_multiband_sine() + mb = cup.MultiBandLightCurve.from_light_curves( + {name: cup.LightCurve.from_arrays(t, m) for name, (t, m, _) in bands.items()} + ) + grid = make_grid(2001) + s = cup.GLSSettings() + native = gls_multiband_power(grid, mb, s, "finufft").power + reference = gls_multiband_power(grid, mb, s, "astropy").power + assert np.allclose(native, reference, atol=2e-4) + + +# --- backend parity ---------------------------------------------------------- + + +@requires_gpu +@pytest.mark.parametrize("model", ["offsets", "perband", "flex"]) +def test_cufinufft_matches_finufft(model: str) -> None: + mb, grid = make_mblc(), make_grid() + s = cup.GLSSettings(mb_model=model) # type: ignore[arg-type] + cpu = gls_multiband_power(grid, mb, s, "finufft").power + gpu = gls_multiband_power(grid, mb, s, "cufinufft").power + assert np.allclose(gpu, cpu, atol=1e-8) + + +@requires_torch +@pytest.mark.parametrize("model", ["offsets", "perband", "flex"]) +def test_torch_cpu_matches_finufft(model: str) -> None: + mb, grid = make_mblc(), make_grid() + s = cup.GLSSettings(mb_model=model) # type: ignore[arg-type] + cpu = gls_multiband_power(grid, mb, s, "finufft").power + torch_power = gls_multiband_power(grid, mb, s, "torch:cpu").power + assert np.allclose(torch_power, cpu, atol=1e-8) + + +# --- batch engine reuse ------------------------------------------------------ + + +@pytest.mark.parametrize("model", ["offsets", "perband", "flex"]) +def test_foreign_engine_ignored_on_cpu(model: str) -> None: + """A non-cufinufft engine (any object) must not change the CPU result.""" + mb, grid = make_mblc(), make_grid(1001) + s = cup.GLSSettings(mb_model=model) # type: ignore[arg-type] + plain = gls_multiband_power(grid, mb, s, "finufft").power + with_engine = gls_multiband_power( + grid, mb, s, "finufft", engine=object() + ).power + np.testing.assert_array_equal(with_engine, plain) + + +@requires_gpu +@pytest.mark.parametrize("model", ["offsets", "perband", "flex"]) +def test_cufinufft_engine_matches_planless(model: str) -> None: + """The plan-cached engine path returns the plan-per-call cufinufft result.""" + from cuperiod.methods.gls import CufinufftGLS + + mb, grid = make_mblc(), make_grid() + s = cup.GLSSettings(mb_model=model) # type: ignore[arg-type] + engine = CufinufftGLS(eps=s.nufft_eps) + plain = gls_multiband_power(grid, mb, s, "cufinufft").power + reused = gls_multiband_power(grid, mb, s, "cufinufft", engine=engine).power + # A second run through the now-warm plan cache must be deterministic. + again = gls_multiband_power(grid, mb, s, "cufinufft", engine=engine).power + assert np.allclose(reused, plain, atol=1e-8) + np.testing.assert_array_equal(again, reused) + + +# --- API wiring and guards --------------------------------------------------- + + +def test_periodogram_api_uses_native_backend() -> None: + """cup.periodogram on a MultiBandLightCurve no longer falls back to astropy.""" + mb = make_mblc() + pg = cup.periodogram(mb, "GLS", backend="cpu") + assert isinstance(pg, cup.Periodogram) + assert pg.backend == "finufft" + assert pg.best_period() == pytest.approx(PERIOD, rel=2e-3) + assert pg.meta["mb_model"] == "offsets" + assert tuple(pg.meta["bands"]) == ("b0", "b1", "b2") + + +def test_astropy_backend_still_available() -> None: + mb = make_mblc() + pg = cup.periodogram(mb, "GLS", backend="astropy", grid=make_grid(1001)) + assert isinstance(pg, cup.Periodogram) + assert pg.backend == "astropy" + + +def test_non_uniform_grid_falls_back_to_astropy() -> None: + mb = make_mblc() + freq = np.geomspace(0.1, 6.0, 800) + grid = GridSpec(kind="frequency", values=freq, uniform=False) + pg = gls_multiband_power(grid, mb, cup.GLSSettings(), "finufft") + assert pg.backend == "astropy" + + +def test_empty_grid_raises() -> None: + mb = make_mblc() + grid = GridSpec(kind="frequency", values=np.empty(0), uniform=True) + with pytest.raises(InsufficientDataError): + gls_multiband_power(grid, mb, cup.GLSSettings(), "finufft") + + +def test_too_few_points_raises() -> None: + bands = synthetic_multiband_sine(band_points=(3, 2), amplitudes=(0.3, 0.2), + offsets=(15.0, 14.0)) + mb = cup.MultiBandLightCurve.from_light_curves( + {n: cup.LightCurve.from_arrays(t, m, e) for n, (t, m, e) in bands.items()} + ) + with pytest.raises(InsufficientDataError): + gls_multiband_power(make_grid(101), mb, cup.GLSSettings(), "finufft") + + +def test_flex_zero_terms_rejected() -> None: + with pytest.raises(ValueError, match="mb_nterms"): + cup.GLSSettings(mb_model="flex", mb_nterms_base=0, mb_nterms_band=0) diff --git a/tests/test_multiband_io.py b/tests/test_multiband_io.py new file mode 100644 index 0000000..6cc9d8b --- /dev/null +++ b/tests/test_multiband_io.py @@ -0,0 +1,131 @@ +"""Multi-band file loading: MultiBandLightCurve.from_file, CLI --band, batch.""" + +from __future__ import annotations + +from pathlib import Path + +import numpy as np +import pytest +from typer.testing import CliRunner + +import cuperiod as cup +from cuperiod.cli.app import app +from cuperiod.core.errors import ColumnResolutionError +from synth import synthetic_multiband_sine + +runner = CliRunner() +PERIOD = 0.7365 + + +def write_long_csv( + path: Path, band_points: tuple[int, ...] = (50, 40) +) -> dict[str, int]: + """A long-format two-band CSV; returns the per-band point counts.""" + bands = synthetic_multiband_sine( + band_points=band_points, amplitudes=(0.3, 0.2), offsets=(15.0, 14.2), + period=PERIOD, + ) + lines = ["jd,mag,mag_err,band"] + counts = {} + for name, (t, m, e) in bands.items(): + counts[name] = t.size + lines += [ + f"{ti},{mi},{ei},{name}" + for ti, mi, ei in zip(t, m, e, strict=True) + ] + path.write_text("\n".join(lines), encoding="utf-8") + return counts + + +def test_from_file_splits_bands(tmp_path: Path) -> None: + csv = tmp_path / "star.csv" + counts = write_long_csv(csv) + mb = cup.MultiBandLightCurve.from_file(csv, band_column="band") + assert mb.band_names == ("b0", "b1") + for name, lc in mb.bands.items(): + assert lc.n == counts[name] + assert lc.error is not None + assert lc.meta["band"] == name + assert mb.meta["source"] == str(csv) + + +def test_from_file_autodetects_band_column(tmp_path: Path) -> None: + csv = tmp_path / "star.csv" + write_long_csv(csv) + mb = cup.MultiBandLightCurve.from_file(csv) + assert mb.band_names == ("b0", "b1") + + +def test_from_file_parquet_roundtrip(tmp_path: Path) -> None: + import pyarrow as pa + import pyarrow.parquet as pq + + bands = synthetic_multiband_sine(band_points=(30, 20), amplitudes=(0.3, 0.2), + offsets=(15.0, 14.2)) + t = np.concatenate([bands["b0"][0], bands["b1"][0]]) + m = np.concatenate([bands["b0"][1], bands["b1"][1]]) + e = np.concatenate([bands["b0"][2], bands["b1"][2]]) + label = np.array(["g"] * 30 + ["r"] * 20) + table = pa.table({"mjd": t, "mag": m, "magerr": e, "filter": label}) + path = tmp_path / "star.parquet" + pq.write_table(table, path) + mb = cup.MultiBandLightCurve.from_file(path, band_column="filter") + assert mb.band_names == ("g", "r") + assert mb.bands["g"].n == 30 and mb.bands["r"].n == 20 + + +def test_from_dataframe_band_column_with_explicit_columns() -> None: + # band_column must survive an explicit ColumnMap that pins only time/value: + # the caller has no way to spell the band otherwise than the keyword. + import pandas as pd + + bands = synthetic_multiband_sine(band_points=(30, 20), amplitudes=(0.3, 0.2), + offsets=(15.0, 14.2)) + df = pd.DataFrame( + { + "t_obs": np.concatenate([bands["b0"][0], bands["b1"][0]]), + "brightness": np.concatenate([bands["b0"][1], bands["b1"][1]]), + "survey_filter": np.array(["g"] * 30 + ["r"] * 20), + } + ) + mb = cup.MultiBandLightCurve.from_dataframe( + df, + band_column="survey_filter", + columns=cup.ColumnMap(time="t_obs", value="brightness"), + ) + assert mb.band_names == ("g", "r") + assert mb.bands["g"].n == 30 and mb.bands["r"].n == 20 + + +def test_from_file_without_band_column_raises(tmp_path: Path) -> None: + csv = tmp_path / "noband.csv" + csv.write_text("jd,mag\n1.0,12.0\n2.0,12.1\n", encoding="utf-8") + with pytest.raises(ColumnResolutionError): + cup.MultiBandLightCurve.from_file(csv) + + +def test_cli_run_with_band_is_multiband(tmp_path: Path) -> None: + csv = tmp_path / "star.csv" + write_long_csv(csv) + result = runner.invoke(app, ["run", str(csv), "--band", "band", "-m", "GLS"]) + assert result.exit_code == 0, result.output + # 90 stacked points prove both bands entered the fit. + assert "n=90" in result.output + + +def test_batch_file_inputs_go_multiband(tmp_path: Path) -> None: + # Dense enough that the default pseudo-Nyquist grid reaches the true + # frequency (1.36 c/d needs > 90 points over the 180-day span). + for star in range(2): + write_long_csv(tmp_path / f"star{star}.csv", band_points=(90, 70)) + summary = cup.batch_periodograms( + str(tmp_path / "*.csv"), + method="GLS", + backend="cpu", + band_column="band", + ) + assert summary.n_done == 2 and summary.n_failed == 0 + assert summary.rows is not None + for row in summary.rows: + assert row["n_samples"] == 160 + assert row["best_period"] == pytest.approx(PERIOD, rel=2e-3) diff --git a/tests/test_prewhiten_batch.py b/tests/test_prewhiten_batch.py new file mode 100644 index 0000000..606bd6b --- /dev/null +++ b/tests/test_prewhiten_batch.py @@ -0,0 +1,180 @@ +"""Batch pre-whitening: row layout, sinks, resume, and per-curve error isolation.""" + +from __future__ import annotations + +from pathlib import Path + +import numpy as np +import pandas as pd +import pytest + +import cuperiod as cup +from cuperiod.prewhiten.batch import batch_prewhiten, prewhiten_to_rows +from cuperiod.prewhiten.engine import prewhiten +from synth import synthetic_pulsator + + +def _settings(**overrides) -> cup.PreWhitenSettings: + defaults = {"backend": "finufft", "max_frequencies": 3, "store_spectra": False} + return cup.PreWhitenSettings(**{**defaults, **overrides}) + + +def _curves(n: int = 3) -> list[tuple[str, cup.LightCurve]]: + out = [] + for index in range(n): + time, value, error = synthetic_pulsator(n=500, span=20.0, seed=index) + out.append((f"star{index}", cup.LightCurve.from_arrays(time, value, error))) + return out + + +def test_rows_are_one_per_component_with_a_repeated_summary() -> None: + time, value, error = synthetic_pulsator(n=600) + solution = prewhiten((time, value, error), settings=_settings()) + rows = prewhiten_to_rows("star", solution) + assert len(rows) == solution.n_components + assert {row["key"] for row in rows} == {"star"} + assert all(row["n_components"] == solution.n_components for row in rows) + assert rows[0]["label"] == "F1" + assert rows[0]["frequency"] == pytest.approx(solution.components[0].frequency) + + +def test_a_curve_with_no_components_still_produces_a_row() -> None: + rng = np.random.default_rng(7) + time = np.sort(rng.uniform(0.0, 27.0, 800)) + 2458000.0 + noise = 10.0 + rng.normal(0.0, 0.002, 800) + solution = prewhiten( + (time, noise, np.full(800, 0.002)), settings=_settings(snr_threshold=6.0) + ) + assert solution.n_components == 0 + (row,) = prewhiten_to_rows("quiet", solution) + assert row["key"] == "quiet" and row["n_components"] == 0 + # Missing cells are NaN / "" rather than None, so a Parquet part written from an + # all-quiet chunk infers the same column types as any other chunk. + assert np.isnan(row["frequency"]) and row["combination"] == "" + + +def test_max_components_truncates_the_rows() -> None: + time, value, error = synthetic_pulsator(n=600) + solution = prewhiten((time, value, error), settings=_settings()) + rows = prewhiten_to_rows("star", solution, max_components=1) + assert len(rows) == 1 and rows[0]["label"] == "F1" + + +def test_in_memory_batch_covers_every_input() -> None: + summary = batch_prewhiten(_curves(), settings=_settings(), workers=1) + assert summary.n_inputs == 3 + assert summary.n_failed == 0 + assert summary.methods == ("PREWHITEN",) + assert summary.rows is not None + assert {row["key"] for row in summary.rows} == {"star0", "star1", "star2"} + + +def test_parquet_sink_round_trips(tmp_path: Path) -> None: + sink = tmp_path / "modes.parquet" + summary = batch_prewhiten(_curves(2), settings=_settings(), workers=1, sink=sink) + assert sink.exists() and summary.n_done > 0 + frame = pd.read_parquet(sink) + assert set(frame["key"]) == {"star0", "star1"} + assert {"frequency", "frequency_error", "snr", "stop_reason"} <= set(frame.columns) + + +def test_directory_sink_is_resumable(tmp_path: Path) -> None: + sink = tmp_path / "parts" + first = batch_prewhiten( + _curves(2), settings=_settings(), workers=1, sink=sink, chunk_size=1 + ) + assert first.n_skipped == 0 + assert len(list(sink.glob("part-*.parquet"))) == 2 + second = batch_prewhiten( + _curves(2), settings=_settings(), workers=1, sink=sink, chunk_size=1 + ) + assert second.n_skipped == 2 and second.n_done == 0 + + +def test_a_bad_light_curve_is_reported_not_raised() -> None: + good = _curves(1) + broken = cup.LightCurve.from_arrays( + np.full(40, 2458000.0), np.ones(40), np.full(40, 0.01) + ) + summary = batch_prewhiten( + [*good, ("broken", broken)], settings=_settings(), workers=1 + ) + assert summary.n_failed == 1 + assert summary.errors[0][0] == "broken" + assert summary.rows is not None and len(summary.rows) > 0 # the good one survived + + +def test_multiband_input_is_reported_as_an_error() -> None: + time, value, error = synthetic_pulsator(n=300) + mblc = cup.MultiBandLightCurve.from_light_curves( + {"V": cup.LightCurve.from_arrays(time, value, error)} + ) + summary = batch_prewhiten([("mb", mblc)], settings=_settings(), workers=1) + assert summary.n_failed == 1 + assert "single-band" in summary.errors[0][1] + + +def test_an_invalid_device_is_rejected() -> None: + with pytest.raises(ValueError, match="cpu"): + batch_prewhiten(_curves(1), device="tpu") + + +def test_top_level_batch_entry_point_exists() -> None: + summary = cup.batch_prewhiten(_curves(1), settings=_settings(), workers=1) + assert summary.n_inputs == 1 + + +def test_directory_sink_parts_share_one_schema(tmp_path: Path) -> None: + # Regression: component fields were emitted as Python None, so a chunk in which no + # star had an identified combination typed that column `null` while a later chunk + # typed it `string` — and a pyarrow dataset takes its schema from the first + # fragment, making the whole directory unreadable. + import pyarrow as pa + import pyarrow.dataset as ds + import pyarrow.parquet as pq + + rng = np.random.default_rng(3) + quiet_time = np.sort(rng.uniform(0.0, 27.0, 600)) + 2458000.0 + quiet = cup.LightCurve.from_arrays( + quiet_time, 10.0 + rng.normal(0.0, 0.002, 600), np.full(600, 0.002) + ) + time, value, error = synthetic_pulsator(n=600, span=20.0) + loud = cup.LightCurve.from_arrays(time, value, error) + + sink = tmp_path / "parts" + # Chunk 0 yields no components at all; chunk 1 yields several with a combination. + summary = batch_prewhiten( + [("quiet", quiet), ("loud", loud)], + settings=_settings(snr_threshold=8.0), + workers=1, + sink=sink, + chunk_size=1, + ) + assert summary.n_failed == 0 + parts = sorted(sink.glob("part-*.parquet")) + assert len(parts) == 2 + schemas = [pq.read_schema(p) for p in parts] + assert schemas[0] == schemas[1] + assert pa.types.is_string(schemas[0].field("combination").type) # never null-typed + assert pa.types.is_floating(schemas[0].field("frequency").type) + table = ds.dataset(sink, format="parquet").to_table() + assert set(table.column("key").to_pylist()) == {"quiet", "loud"} + + +def test_component_cells_are_stably_typed() -> None: + time, value, error = synthetic_pulsator(n=600) + solution = prewhiten((time, value, error), settings=_settings()) + (filled,) = prewhiten_to_rows("star", solution, max_components=1) + rng = np.random.default_rng(7) + quiet_time = np.sort(rng.uniform(0.0, 27.0, 600)) + 2458000.0 + empty_solution = prewhiten( + (quiet_time, 10.0 + rng.normal(0.0, 0.002, 600), np.full(600, 0.002)), + settings=_settings(snr_threshold=8.0), + ) + (empty,) = prewhiten_to_rows("quiet", empty_solution) + assert set(filled) == set(empty) + for name in filled: + assert type(filled[name]) is type(empty[name]), name + assert isinstance(filled["rank"], float) # float, so NaN can fill it + assert filled["combination"] == "" or isinstance(filled["combination"], str) + assert empty["label"] == "" and np.isnan(empty["frequency"]) diff --git a/tests/test_prewhiten_combinations.py b/tests/test_prewhiten_combinations.py new file mode 100644 index 0000000..4fcc5fc --- /dev/null +++ b/tests/test_prewhiten_combinations.py @@ -0,0 +1,132 @@ +"""Combination-frequency identification: correctness, ordering, and honesty.""" + +from __future__ import annotations + +import numpy as np +import pytest + +from cuperiod.prewhiten.combinations import _coefficient_vectors, identify_combinations + + +def _labels(matches) -> list[str]: + return [m.label for m in matches] + + +def test_identifies_a_harmonic_and_a_sum() -> None: + frequency = np.array([5.0, 7.3, 10.0, 12.3]) + amplitude = np.array([1.0, 0.7, 0.3, 0.2]) + matches = identify_combinations(frequency, amplitude, rayleigh=0.01) + assert _labels(matches) == ["F3 = 2F1", "F4 = F1 + F2"] + assert all(m.order == 2 for m in matches) + + +def test_identifies_a_difference_with_readable_ordering() -> None: + frequency = np.array([5.0, 7.3, 2.3]) + amplitude = np.array([1.0, 0.7, 0.1]) + (match,) = identify_combinations(frequency, amplitude, rayleigh=0.01) + assert match.label == "F3 = F2 - F1" + assert match.coefficients == (-1, 1) # aligned with parents (F1, F2) + assert match.parents == (0, 1) + + +def test_parents_must_be_stronger_than_the_child() -> None: + # The strongest peak can never be explained by weaker ones. + frequency = np.array([10.0, 5.0, 5.0000001]) + amplitude = np.array([1.0, 0.5, 0.4]) + matches = identify_combinations(frequency, amplitude, rayleigh=0.01) + assert all(m.index != 0 for m in matches) + + +def test_lowest_order_wins_ties() -> None: + # 10 = 2 x 5 (order 2) and also 5 + 5 ... the order-2 harmonic must be reported. + frequency = np.array([5.0, 10.0]) + amplitude = np.array([1.0, 0.4]) + (match,) = identify_combinations(frequency, amplitude, rayleigh=0.01, max_order=3) + assert match.order == 2 + assert match.label == "F2 = 2F1" + + +def test_tolerance_widens_with_the_propagated_uncertainty() -> None: + frequency = np.array([5.0, 7.3, 12.32]) # 0.02 off the exact sum + amplitude = np.array([1.0, 0.7, 0.2]) + tight = identify_combinations( + frequency, amplitude, rayleigh=1e-6, tolerance_rayleigh=0.25, n_sigma=3.0 + ) + assert tight == () + loose = identify_combinations( + frequency, + amplitude, + frequency_error=np.array([0.005, 0.005, 0.005]), + rayleigh=1e-6, + n_sigma=3.0, + ) + assert _labels(loose) == ["F3 = F1 + F2"] + + +def test_nan_uncertainties_do_not_break_the_search() -> None: + frequency = np.array([5.0, 7.3, 12.3]) + amplitude = np.array([1.0, 0.7, 0.2]) + matches = identify_combinations( + frequency, + amplitude, + frequency_error=np.array([np.nan, np.nan, np.nan]), + rayleigh=0.01, + ) + assert _labels(matches) == ["F3 = F1 + F2"] + + +def test_chance_rate_is_reported_and_grows_with_the_tolerance() -> None: + frequency = np.array([5.0, 7.3, 12.3]) + amplitude = np.array([1.0, 0.7, 0.2]) + (tight,) = identify_combinations( + frequency, amplitude, rayleigh=0.001, tolerance_rayleigh=1.0 + ) + (loose,) = identify_combinations( + frequency, amplitude, rayleigh=0.1, tolerance_rayleigh=1.0 + ) + assert 0.0 < tight.expected_false < loose.expected_false + + +def test_negative_predictions_are_not_matched() -> None: + # A coefficient vector predicting a non-positive frequency is meaningless. + frequency = np.array([5.0, 7.3, 0.0001]) + amplitude = np.array([1.0, 0.7, 0.1]) + matches = identify_combinations(frequency, amplitude, rayleigh=0.001) + assert all(m.predicted > 0.0 for m in matches) + + +def test_custom_labels_flow_into_the_identification() -> None: + frequency = np.array([5.0, 10.0]) + amplitude = np.array([1.0, 0.4]) + (match,) = identify_combinations( + frequency, amplitude, rayleigh=0.01, labels=("nu1", "nu2") + ) + assert match.label == "nu2 = 2nu1" + + +def test_degenerate_inputs_return_nothing() -> None: + assert identify_combinations(np.array([5.0]), np.array([1.0])) == () + assert ( + identify_combinations(np.array([5.0, 10.0]), np.array([1.0, 0.4]), max_order=0) + == () + ) + + +def test_coefficient_enumeration_is_complete_and_bounded() -> None: + vectors = list(_coefficient_vectors(2, 2)) + assert (2, 0) in vectors and (1, 1) in vectors and (-1, 1) in vectors + assert (0, 0) not in vectors + assert all(sum(abs(c) for c in v) <= 2 for v in vectors) + assert len(list(_coefficient_vectors(5, 2))) < 200 # not the naive 5^5 + + +def test_to_dict_is_json_friendly() -> None: + import json + + frequency = np.array([5.0, 10.0]) + amplitude = np.array([1.0, 0.4]) + (match,) = identify_combinations(frequency, amplitude, rayleigh=0.01) + payload = json.loads(json.dumps(match.to_dict())) + assert payload["label"] == "F2 = 2F1" + assert payload["coefficients"] == [2] + assert payload["predicted"] == pytest.approx(10.0) diff --git a/tests/test_prewhiten_engine.py b/tests/test_prewhiten_engine.py new file mode 100644 index 0000000..550b86e --- /dev/null +++ b/tests/test_prewhiten_engine.py @@ -0,0 +1,526 @@ +"""The extraction loop: recovery, stopping criteria, guards, and the result object.""" + +from __future__ import annotations + +import json + +import numpy as np +import pytest + +import cuperiod as cup +from conftest import requires_gpu +from cuperiod.core.errors import InsufficientDataError +from cuperiod.core.grid import uniform_frequency_grid +from cuperiod.prewhiten import correlation_factor, default_prewhiten_grid, prewhiten +from synth import synthetic_pulsator, synthetic_sine + + +def _settings(**overrides) -> cup.PreWhitenSettings: + defaults = {"backend": "finufft", "max_frequencies": 8} + return cup.PreWhitenSettings(**{**defaults, **overrides}) + + +def _noise_only(n: int = 1500, seed: int = 7): + rng = np.random.default_rng(seed) + time = np.sort(rng.uniform(0.0, 27.0, n)) + 2458000.0 + return time, 10.0 + rng.normal(0.0, 0.002, n), np.full(n, 0.002) + + +# --- recovery ---------------------------------------------------------------- + + +def test_recovers_every_planted_frequency() -> None: + time, value, error = synthetic_pulsator() + solution = prewhiten((time, value, error), settings=_settings()) + assert solution.n_components == 3 + recovered = np.sort(solution.frequency) + assert np.allclose(recovered, [12.34, 17.81, 24.68], atol=2e-3) + assert np.allclose(np.sort(solution.amplitude)[::-1], [0.012, 0.007, 0.004], + rtol=0.1) + assert np.all(solution.snr > 4.0) + assert np.all(solution.frequency_error > 0.0) + + +def test_components_are_ranked_by_extraction_order() -> None: + time, value, error = synthetic_pulsator() + solution = prewhiten((time, value, error), settings=_settings()) + assert [c.rank for c in solution.components] == [1, 2, 3] + assert [c.label for c in solution.components] == ["F1", "F2", "F3"] + # The strongest planted mode is extracted first. + assert solution.components[0].amplitude == max(solution.amplitude) + + +def test_residuals_are_consistent_with_the_reported_model() -> None: + time, value, error = synthetic_pulsator() + solution = prewhiten((time, value, error), settings=_settings()) + assert np.allclose(solution.residuals, value - solution.model(time), atol=1e-10) + assert solution.rms < 2.0 * 0.0015 + assert solution.reduced_chi2 == pytest.approx(1.0, rel=0.2) + + +def test_works_without_error_bars() -> None: + time, value, _ = synthetic_pulsator() + solution = prewhiten((time, value), settings=_settings()) + assert solution.n_components >= 3 + assert np.all(np.isfinite(solution.frequency_error)) + + +def test_a_light_curve_object_and_a_tuple_agree() -> None: + time, value, error = synthetic_pulsator(n=800) + settings = _settings(max_frequencies=2) + from_tuple = prewhiten((time, value, error), settings=settings) + from_object = prewhiten( + cup.LightCurve.from_arrays(time, value, error), settings=settings + ) + assert np.allclose(from_tuple.frequency, from_object.frequency) + + +# --- stopping criteria ------------------------------------------------------- + + +def test_pure_noise_yields_no_components() -> None: + solution = prewhiten(_noise_only(), settings=_settings(snr_threshold=4.5)) + assert solution.n_components == 0 + assert "S/N" in solution.stop_reason + assert solution.components == () + + +def test_max_frequencies_caps_the_run() -> None: + time, value, error = synthetic_pulsator() + solution = prewhiten((time, value, error), settings=_settings(max_frequencies=2)) + assert solution.n_components == 2 + assert "max_frequencies" in solution.stop_reason + + +def test_zero_max_frequencies_returns_an_offset_only_solution() -> None: + time, value, error = synthetic_pulsator(n=400) + solution = prewhiten((time, value, error), settings=_settings(max_frequencies=0)) + assert solution.n_components == 0 + assert solution.stop_reason == "max_frequencies is 0" + assert np.isfinite(solution.offset) + + +def test_a_high_snr_threshold_stops_earlier() -> None: + time, value, error = synthetic_pulsator() + strict = prewhiten((time, value, error), settings=_settings(snr_threshold=80.0)) + lenient = prewhiten((time, value, error), settings=_settings(snr_threshold=4.0)) + assert strict.n_components < lenient.n_components + + +def test_bic_criterion_rejects_noise() -> None: + solution = prewhiten( + _noise_only(), + settings=_settings(stop_criteria=("bic",), min_delta_bic=10.0), + ) + assert solution.n_components == 0 + assert "BIC" in solution.stop_reason + + +def test_fap_criterion_accepts_a_strong_signal_and_rejects_noise() -> None: + time, value, error = synthetic_pulsator(frequencies=(12.34,), amplitudes=(0.02,), + phases=(0.5,)) + strong = prewhiten( + (time, value, error), settings=_settings(stop_criteria=("fap",)) + ) + assert strong.n_components >= 1 + assert strong.components[0].fap < 1e-3 + quiet = prewhiten(_noise_only(), settings=_settings(stop_criteria=("fap",))) + assert quiet.n_components == 0 + + +def test_amplitude_floor_is_enforced() -> None: + time, value, error = synthetic_pulsator() + solution = prewhiten( + (time, value, error), + settings=_settings(stop_criteria=("amplitude",), min_amplitude=0.010), + ) + assert solution.n_components == 1 # only the 0.012 mag mode clears the floor + assert "amplitude" in solution.stop_reason + + +# --- guards ------------------------------------------------------------------ + + +def test_no_two_components_are_unresolved_from_each_other() -> None: + time, value, error = synthetic_pulsator(n=3000, span=27.0) + solution = prewhiten((time, value, error), settings=_settings(max_frequencies=12)) + frequencies = np.sort(solution.frequency) + if frequencies.size > 1: + rayleigh = 1.0 / solution.baseline + assert np.min(np.diff(frequencies)) >= 1.5 * rayleigh * 0.999 + + +def test_amplitudes_stay_physical() -> None: + # Regression: an unbounded refinement could slide one frequency onto another and + # produce a pair of enormous, mutually cancelling components. + time, value, error = synthetic_pulsator(n=4000, span=40.0) + solution = prewhiten((time, value, error), settings=_settings(max_frequencies=15)) + assert np.max(solution.amplitude) < 10.0 * 0.012 + + +def test_pruning_leaves_only_significant_components() -> None: + time, value, error = synthetic_pulsator(n=2000, span=27.0) + solution = prewhiten( + (time, value, error), settings=_settings(max_frequencies=12, prune=True) + ) + assert np.all(solution.snr >= 4.0) + assert solution.n_pruned >= 0 + + +def test_too_few_points_raises() -> None: + time, value, error = synthetic_sine(n=8) + with pytest.raises(InsufficientDataError, match="min_detections"): + prewhiten((time, value, error), settings=_settings(min_detections=20)) + + +def test_zero_baseline_raises() -> None: + time = np.full(50, 2458000.0) + with pytest.raises(InsufficientDataError): + prewhiten((time, np.ones(50), np.full(50, 0.01)), settings=_settings()) + + +def test_multiband_input_is_rejected_with_a_useful_message() -> None: + time, value, error = synthetic_pulsator(n=200) + mblc = cup.MultiBandLightCurve.from_light_curves( + {"V": cup.LightCurve.from_arrays(time, value, error)} + ) + with pytest.raises(ValueError, match="single band"): + prewhiten(mblc, settings=_settings()) + + +# --- knobs and plumbing ------------------------------------------------------ + + +def test_custom_grid_is_honoured() -> None: + time, value, error = synthetic_pulsator() + grid = uniform_frequency_grid( + float(time.max() - time.min()), + maximum_frequency=15.0, minimum_frequency=1.0, samples_per_peak=8, + ) + solution = prewhiten((time, value, error), settings=_settings(), grid=grid) + assert np.all(solution.frequency < 15.1) # 17.81 and 24.68 are out of band + assert solution.spectrum is not None + assert solution.spectrum.frequency[-1] == pytest.approx(grid.values[-1]) + + +def test_default_grid_spans_one_over_baseline_to_pseudo_nyquist() -> None: + time, value, error = synthetic_pulsator() + lc = cup.LightCurve.from_arrays(time, value, error) + grid = default_prewhiten_grid(lc) + assert grid.uniform and grid.kind == "frequency" + assert grid.values[0] == pytest.approx(1.0 / lc.baseline, rel=1e-6) + assert grid.values[-1] > 24.68 + + +def _nightly_hads(n_nights: int = 220, seed: int = 11): + """A HADS-like curve with ground-based nightly sampling (median gap ~1 d).""" + rng = np.random.default_rng(seed) + time = np.sort( + np.concatenate( + [night + rng.uniform(0.0, 0.25, 2) for night in range(n_nights)] + ) + ) + frequency = 11.2354 # P = 0.089004 d — above any median-gap pseudo-Nyquist + value = ( + 13.0 + + 0.30 * np.sin(2 * np.pi * frequency * time + 0.7) + + 0.12 * np.sin(2 * np.pi * 2 * frequency * time + 1.9) + + rng.normal(0.0, 0.02, time.size) + ) + return time, value, np.full(time.size, 0.02), frequency + + +def test_default_band_reaches_short_period_pulsators_on_sparse_sampling() -> None: + # Regression: the auto band topped out at the median-gap pseudo-Nyquist, which for + # nightly ground-based cadence is ~0.5-2.5 c/d — the entire delta Scuti / HADS + # regime sat out of band and the extraction fitted the *daily aliases* instead + # (the bundled ASAS-SN HADS demo, P = 0.0898 d, came out as P = 0.123 d). + time, value, error, frequency = _nightly_hads() + lc = cup.LightCurve.from_arrays(time, value, error) + from cuperiod.core.grid import pseudo_nyquist_frequency + from cuperiod.prewhiten.engine import ( + DEFAULT_MAX_FREQUENCY_FLOOR, + default_maximum_frequency, + ) + + assert pseudo_nyquist_frequency(time, 5) < frequency # the trap this guards + assert default_maximum_frequency(time) == DEFAULT_MAX_FREQUENCY_FLOOR + # The grid builder rounds up to a whole number of steps, hence the tolerance. + assert default_prewhiten_grid(lc).values[-1] == pytest.approx( + DEFAULT_MAX_FREQUENCY_FLOOR, abs=0.01 + ) + # Dense sampling is governed by the pseudo-Nyquist itself, not the floor. + dense = np.linspace(0.0, 27.0, 20_000) + assert default_maximum_frequency(dense) == pytest.approx( + pseudo_nyquist_frequency(dense, 5), rel=1e-9 + ) + + +def test_sparse_hads_is_recovered_not_its_daily_alias() -> None: + time, value, error, frequency = _nightly_hads() + solution = prewhiten((time, value, error), settings=_settings()) + assert solution.n_components >= 2 + strongest = solution.components[0] + assert strongest.frequency == pytest.approx(frequency, abs=2e-4) + labels = [c.combination for c in solution.components if c.combination] + assert any("2F1" in label for label in labels) # the harmonic is in band too + assert solution.rms < 0.05 # the aliased fit left ~0.25 mag of signal behind + + +def test_store_spectra_false_drops_the_big_arrays() -> None: + time, value, error = synthetic_pulsator(n=400) + solution = prewhiten( + (time, value, error), settings=_settings(store_spectra=False, max_frequencies=1) + ) + assert solution.spectrum is None and solution.residual_spectrum is None + assert solution.window is None + + +def test_solution_carries_the_spectral_window() -> None: + time, value, error = synthetic_pulsator(n=400) + solution = prewhiten((time, value, error), settings=_settings(max_frequencies=1)) + assert solution.window is not None + assert solution.spectrum is not None + assert np.array_equal(solution.window.frequency, solution.spectrum.frequency) + assert np.all(solution.window.amplitude <= 1.0 + 1e-12) + # |W| -> 1 towards zero frequency; the grid starts at 1/T where it is already low, + # but it must never exceed 1 and must peak below the lowest trial frequency's lobe. + assert float(solution.window.amplitude.max()) <= 1.0 + 1e-12 + + +def test_backend_argument_overrides_the_setting() -> None: + time, value, error = synthetic_pulsator(n=400) + solution = prewhiten( + (time, value, error), settings=_settings(max_frequencies=1), backend="numpy" + ) + assert solution.backend == "numpy" + + +def test_uncertainty_estimators_are_all_selectable() -> None: + time, value, error = synthetic_pulsator(n=600, span=20.0) + for method in ("covariance", "analytic", "bootstrap"): + solution = prewhiten( + (time, value, error), + settings=_settings( + max_frequencies=1, uncertainty=method, n_resamples=10 + ), + ) + assert solution.uncertainty_method == method + assert solution.components[0].frequency_error > 0.0 + + +def test_bootstrap_errors_are_nonzero_for_every_component() -> None: + # Regression: the engine hands its per-iteration policy (default "last") to the + # bootstrap; the replicate fits then pinned every frequency except the newest, so + # all established components reported sigma_f == 0 exactly. The bootstrap must + # scatter *every* frequency, and roughly as much as the covariance says. + time, value, error = synthetic_pulsator(n=800, span=25.0) + boot = prewhiten( + (time, value, error), + settings=_settings(uncertainty="bootstrap", n_resamples=24), + ) + cova = prewhiten((time, value, error), settings=_settings()) + assert boot.n_components == cova.n_components >= 2 + assert np.all(boot.frequency_error > 0.1 * cova.frequency_error) + assert np.all(boot.frequency_error < 10.0 * cova.frequency_error) + + +def _drifting_pulsator(n: int = 600, span: float = 20.0, seed: int = 5): + # A random-walk drift on top of the planted modes, so whatever the extraction leaves + # behind is correlated point to point and D comes out well above 1. + time, value, error = synthetic_pulsator(n=n, span=span) + drift = np.cumsum(np.random.default_rng(seed).normal(0.0, 2e-4, time.size)) + return time, value + drift - drift.mean(), error + + +def test_only_the_inflated_estimators_report_a_correlation_factor() -> None: + # Regression: the engine recomputed D from the residuals and stored it whatever the + # estimator was, so a bootstrap run reported (and wrote to every catalogue row) a D + # its error bars had never been multiplied by — the bootstrap is deliberately left + # uncorrected, since it resamples the residuals as they are. + time, value, error = _drifting_pulsator() + for method in ("covariance", "analytic"): + solution = prewhiten( + (time, value, error), settings=_settings(uncertainty=method) + ) + assert solution.correlation_factor > 1.0 + assert solution.correlation_factor == pytest.approx( + correlation_factor(solution.residuals) + ) + + boot = prewhiten( + (time, value, error), + settings=_settings(uncertainty="bootstrap", n_resamples=10), + ) + assert boot.correlation_factor == 1.0 + # ...and not because the residuals happen to be uncorrelated. + assert correlation_factor(boot.residuals) > 1.0 + + +def test_correlation_correction_off_reports_no_factor() -> None: + time, value, error = _drifting_pulsator() + plain = prewhiten( + (time, value, error), settings=_settings(correlation_correction=False) + ) + assert plain.correlation_factor == 1.0 + assert correlation_factor(plain.residuals) > 1.0 + + +def test_clean_components_agree_with_the_spectrum_and_are_not_blended() -> None: + time, value, error = synthetic_pulsator() + solution = prewhiten((time, value, error), settings=_settings()) + assert solution.n_components == 3 + for component in solution.components: + # Well-separated modes: the joint fit and the spectrum's own reading agree. + assert component.spectrum_amplitude > 0.0 + assert component.amplitude_ratio == pytest.approx(1.0, abs=0.25) + assert not component.blended + assert solution.n_blended == 0 + assert "*" not in solution.summary() + + +def test_a_correlated_pair_is_flagged_as_blended() -> None: + # Two modes a third of a Rayleigh width apart are hopelessly correlated: the joint + # fit gives them large, mutually cancelling amplitudes while the spectrum sees one + # blended bump. That is precisely what the flag exists to say out loud. + rng = np.random.default_rng(3) + n, span = 1500, 30.0 + time = np.sort(rng.uniform(0.0, span, n)) + rayleigh = 1.0 / span + pair = (9.0, 9.0 + rayleigh / 3.0) + value = ( + 10.0 + + 0.05 * np.sin(2 * np.pi * pair[0] * time + 0.3) + + 0.05 * np.sin(2 * np.pi * pair[1] * time + 2.6) + + rng.normal(0.0, 0.002, n) + ) + error = np.full(n, 0.002) + solution = prewhiten( + (time, value, error), + settings=_settings( + max_frequencies=4, min_separation_rayleigh=0.2, refine_bound_rayleigh=0.5 + ), + ) + assert solution.n_blended >= 1 + flagged = [c for c in solution.components if c.blended] + assert all( + c.amplitude_ratio > 2.0 or c.amplitude_ratio < 0.5 for c in flagged + ) + assert "*" in solution.summary() + assert "disagree with the spectrum" in solution.summary() + + +def test_blend_tolerance_controls_the_flag() -> None: + time, value, error = synthetic_pulsator() + strict = prewhiten( + (time, value, error), settings=_settings(blend_tolerance=1.001) + ) + assert strict.n_blended == strict.n_components # nothing agrees to 0.1% + lenient = prewhiten( + (time, value, error), settings=_settings(blend_tolerance=100.0) + ) + assert lenient.n_blended == 0 + + +def test_spectrum_amplitude_is_the_spectrum_read_at_the_component() -> None: + time, value, error = synthetic_pulsator() + solution = prewhiten((time, value, error), settings=_settings()) + spectrum = solution.spectrum + assert spectrum is not None + for component in solution.components: + nearest = int(np.argmin(np.abs(spectrum.frequency - component.frequency))) + assert component.spectrum_amplitude == pytest.approx( + float(spectrum.amplitude[nearest]) + ) + assert component.amplitude_ratio == pytest.approx( + component.amplitude / component.spectrum_amplitude + ) + # Still computed when the spectra themselves are not kept (batch mode). + lean = prewhiten((time, value, error), settings=_settings(store_spectra=False)) + assert lean.spectrum is None + assert all(np.isfinite(c.spectrum_amplitude) for c in lean.components) + + +def test_amplitude_ratio_edge_cases() -> None: + from cuperiod.prewhiten.result import amplitude_ratio + + assert amplitude_ratio(0.5, 0.25) == pytest.approx(2.0) + assert amplitude_ratio(0.5, 0.0) == float("inf") # fit claims what data lacks + assert np.isnan(amplitude_ratio(0.0, 0.0)) + assert np.isnan(amplitude_ratio(float("nan"), 0.25)) + + +def test_harmonic_is_flagged_as_a_combination() -> None: + # The default synthetic pulsator plants 24.68 = 2 x 12.34 exactly. + time, value, error = synthetic_pulsator() + solution = prewhiten((time, value, error), settings=_settings()) + labels = [c.combination for c in solution.components if c.combination] + assert any("2F1" in label for label in labels) + assert len(solution.independent()) == solution.n_components - len(labels) + + +def test_combinations_can_be_switched_off() -> None: + time, value, error = synthetic_pulsator() + solution = prewhiten((time, value, error), settings=_settings(combinations=False)) + assert solution.combinations == () + assert all(c.combination is None for c in solution.components) + + +# --- the result object ------------------------------------------------------- + + +def test_result_serialization_round_trips_through_json() -> None: + time, value, error = synthetic_pulsator(n=600) + solution = prewhiten((time, value, error), settings=_settings(max_frequencies=2)) + payload = json.loads(json.dumps(solution.to_dict())) + assert payload["n_components"] == solution.n_components + assert payload["components"][0]["label"] == "F1" + assert payload["stop_reason"] == solution.stop_reason + + +def test_result_table_and_dataframe_agree() -> None: + time, value, error = synthetic_pulsator(n=600) + solution = prewhiten((time, value, error), settings=_settings(max_frequencies=2)) + table = solution.to_table() + frame = solution.to_dataframe() + assert len(table) == len(frame) == solution.n_components + assert frame["frequency"].iloc[0] == pytest.approx(table[0]["frequency"]) + + +def test_result_sequence_protocol_and_summary() -> None: + time, value, error = synthetic_pulsator(n=600) + solution = prewhiten((time, value, error), settings=_settings(max_frequencies=2)) + assert len(solution) == solution.n_components + assert list(solution)[0] is solution[0] + text = solution.summary() + assert "Pre-whitening" in text and "F1" in text + assert "components" in repr(solution) + + +def test_period_and_its_uncertainty_are_derived_consistently() -> None: + time, value, error = synthetic_pulsator(n=600) + solution = prewhiten((time, value, error), settings=_settings(max_frequencies=1)) + component = solution.components[0] + assert component.period == pytest.approx(1.0 / component.frequency) + assert component.period_error == pytest.approx( + component.frequency_error / component.frequency**2 + ) + + +def test_top_level_api_exposes_prewhiten() -> None: + time, value, error = synthetic_pulsator(n=400) + solution = cup.prewhiten( + (time, value, error), settings=cup.PreWhitenSettings( + backend="finufft", max_frequencies=1 + ) + ) + assert isinstance(solution, cup.PreWhitenResult) + + +@requires_gpu +def test_gpu_and_cpu_solutions_agree() -> None: + time, value, error = synthetic_pulsator(n=2000) + cpu = prewhiten((time, value, error), settings=_settings()) + gpu = prewhiten((time, value, error), settings=_settings(backend="cufinufft")) + assert gpu.n_components == cpu.n_components + assert np.allclose(np.sort(gpu.frequency), np.sort(cpu.frequency), rtol=1e-9) diff --git a/tests/test_prewhiten_fap.py b/tests/test_prewhiten_fap.py new file mode 100644 index 0000000..3157d27 --- /dev/null +++ b/tests/test_prewhiten_fap.py @@ -0,0 +1,130 @@ +"""The native Baluev false-alarm probability: astropy parity and sane behaviour.""" + +from __future__ import annotations + +import numpy as np +import pytest + +from cuperiod.prewhiten.fap import baluev_fap + +_POWERS = (1e-4, 1e-3, 1e-2, 0.1, 0.3, 0.5, 0.9, 0.999) + + +def _sampling(n: int, seed: int = 0, weighted: bool = True, offset: float = 0.0): + rng = np.random.default_rng(seed) + time = np.sort(rng.uniform(0.0, 27.4, n)) + offset + error = rng.uniform(0.001, 0.004, n) if weighted else None + return time, error + + +@pytest.mark.parametrize("n", [20, 500, 5000]) +@pytest.mark.parametrize("weighted", [True, False]) +@pytest.mark.parametrize("f_max", [10.0, 73.2]) +def test_matches_astropy_to_machine_precision( + n: int, weighted: bool, f_max: float +) -> None: + astropy = pytest.importorskip("astropy.timeseries") + time, error = _sampling(n, weighted=weighted) + rng = np.random.default_rng(1) + value = rng.normal(10.0, 0.01, n) # the data values never enter the formula + ls = astropy.LombScargle(time, value, error, fit_mean=True) + # astropy quietly snaps the requested band onto its autofrequency grid; feed the + # band it *actually* used to our implementation so the statistic is compared 1:1. + _, f_max_used = ls.autofrequency( + maximum_frequency=f_max, return_freq_limits=True + ) + for power in _POWERS: + expected = float( + ls.false_alarm_probability( + power, method="baluev", maximum_frequency=f_max + ) + ) + assert baluev_fap( + power, time, error, maximum_frequency=float(f_max_used) + ) == pytest.approx(expected, rel=1e-12, abs=1e-300) + + +def test_is_invariant_to_the_time_zero_point() -> None: + # astropy's one-pass time variance loses ~11 digits on full Julian dates; the + # centred form must give the same FAP wherever the time axis starts. + time, error = _sampling(500) + reference = baluev_fap(0.02, time, error, maximum_frequency=25.0) + for offset in (2458000.0, 2460000.5, -59000.0): + shifted = baluev_fap(0.02, time + offset, error, maximum_frequency=25.0) + assert shifted == pytest.approx(reference, rel=1e-9) + + +def test_stays_close_to_astropy_even_on_raw_julian_dates() -> None: + # On full Julian dates astropy's one-pass time variance loses precision, so exact + # agreement is impossible (and ours is the more accurate value); the two must still + # agree far beyond any scientific use of a false-alarm probability. + astropy = pytest.importorskip("astropy.timeseries") + time, error = _sampling(500, offset=2458000.0) + value = np.random.default_rng(1).normal(10.0, 0.01, time.size) + ls = astropy.LombScargle(time, value, error, fit_mean=True) + _, f_max_used = ls.autofrequency( + maximum_frequency=25.0, return_freq_limits=True + ) + for power in (1e-3, 0.05, 0.3): + expected = float( + ls.false_alarm_probability( + power, method="baluev", maximum_frequency=25.0 + ) + ) + assert baluev_fap( + power, time, error, maximum_frequency=float(f_max_used) + ) == pytest.approx(expected, rel=1e-3) + + +def test_vectorizes_over_power_and_matches_the_scalar_path() -> None: + time, error = _sampling(300) + grid = np.asarray(_POWERS) + vectored = baluev_fap(grid, time, error, maximum_frequency=25.0) + assert isinstance(vectored, np.ndarray) + assert vectored.shape == grid.shape + scalars = [ + baluev_fap(float(p), time, error, maximum_frequency=25.0) for p in grid + ] + assert np.allclose(vectored, scalars, rtol=0.0, atol=0.0) + assert isinstance(scalars[0], float) + + +def test_is_monotone_in_power_and_bandwidth() -> None: + # Small n keeps even the strongest trial power representable (for n in the + # hundreds, (1 - 0.9)^((n-4)/2) underflows to exactly 0.0). Weak powers are not + # tested for strict order: there the bound saturates at exactly 1.0, because a + # weak peak in a wide band is always a false alarm. + time, error = _sampling(60) + faps = [ + baluev_fap(p, time, error, maximum_frequency=25.0) + for p in (0.2, 0.3, 0.5, 0.9, 0.999) + ] + assert all(a > b for a, b in zip(faps, faps[1:], strict=False)) # stronger->rarer + assert baluev_fap(0.05, time, error, maximum_frequency=25.0) == 1.0 + narrow = baluev_fap(0.4, time, error, maximum_frequency=5.0) + wide = baluev_fap(0.4, time, error, maximum_frequency=50.0) + assert 0.0 < narrow < wide < 1.0 # a wider band, more chances for a false alarm + + +def test_edge_cases() -> None: + time, error = _sampling(200) + assert baluev_fap(0.0, time, error, maximum_frequency=25.0) == pytest.approx(1.0) + assert baluev_fap(1.0, time, error, maximum_frequency=25.0) == pytest.approx(0.0) + # Out-of-range powers are clipped, not propagated as garbage. + assert baluev_fap(1.5, time, error, maximum_frequency=25.0) == pytest.approx(0.0) + assert baluev_fap(-0.5, time, error, maximum_frequency=25.0) == pytest.approx(1.0) + # Fewer than four points cannot constrain the statistic. + assert np.isnan(baluev_fap(0.5, time[:3], None, maximum_frequency=25.0)) + tiny = baluev_fap( + np.array([0.5]), time[:3], None, maximum_frequency=25.0 + ) + assert isinstance(tiny, np.ndarray) and np.isnan(tiny).all() + + +def test_strong_peaks_in_white_noise_are_calibrated() -> None: + # The bound must be usable as a stopping criterion: a planted signal's peak power + # in its own spectrum should give FAP ~ 0, and the tallest peak of pure noise + # should not look wildly significant. + time, error = _sampling(1000) + assert baluev_fap(0.25, time, error, maximum_frequency=30.0) < 1e-30 + assert baluev_fap(0.02, time, error, maximum_frequency=30.0) > 1e-4 diff --git a/tests/test_prewhiten_fit.py b/tests/test_prewhiten_fit.py new file mode 100644 index 0000000..4fc524d --- /dev/null +++ b/tests/test_prewhiten_fit.py @@ -0,0 +1,213 @@ +"""Multi-sinusoid fitting: recovery, refinement policies, and calibrated covariance.""" + +from __future__ import annotations + +import numpy as np +import pytest + +from cuperiod.prewhiten.fit import fit_multisine +from cuperiod.prewhiten.uncertainty import ( + analytic_uncertainties, + bootstrap_uncertainties, + component_uncertainties, + correlation_factor, +) +from synth import synthetic_pulsator + +_TRUTH = ((12.34, 0.012, 0.5), (17.81, 0.007, 2.0)) + + +def _two_mode(n: int = 1200, span: float = 30.0, noise: float = 0.002, seed: int = 0): + return synthetic_pulsator( + n=n, + span=span, + frequencies=tuple(f for f, _, _ in _TRUTH), + amplitudes=tuple(a for _, a, _ in _TRUTH), + phases=tuple(p for _, _, p in _TRUTH), + noise=noise, + seed=seed, + ) + + +def test_recovers_planted_frequencies_and_amplitudes() -> None: + time, value, error = _two_mode() + # Started within a fraction of a Rayleigh width, as the extraction loop always does. + fit = fit_multisine( + time, value, error, np.array([12.335, 17.818]), refine="simultaneous" + ) + assert fit.frequency[0] == pytest.approx(12.34, abs=5e-4) + assert fit.frequency[1] == pytest.approx(17.81, abs=5e-4) + assert fit.amplitude[0] == pytest.approx(0.012, rel=0.05) + assert fit.amplitude[1] == pytest.approx(0.007, rel=0.05) + assert fit.offset == pytest.approx(10.0, abs=1e-3) + assert fit.n_parameters == 3 * 2 + 1 + + +def test_model_reproduces_the_data_to_the_noise_level() -> None: + time, value, error = _two_mode(noise=0.001) + fit = fit_multisine( + time, value, error, np.array([12.34, 17.81]), refine="simultaneous" + ) + assert np.allclose(fit.residuals, value - fit.model(time), atol=1e-12) + assert fit.rms == pytest.approx(0.001, rel=0.15) + assert fit.reduced_chi2 == pytest.approx(1.0, rel=0.15) + + +def test_refinement_policies_reach_the_same_solution() -> None: + time, value, error = _two_mode() + start = np.array([12.33, 17.82]) + solutions = { + policy: fit_multisine(time, value, error, start, refine=policy, sweeps=3) + for policy in ("cyclic", "simultaneous") + } + assert np.allclose( + solutions["cyclic"].frequency, solutions["simultaneous"].frequency, atol=1e-6 + ) + # ...and both improve on doing nothing at all. + none_fit = fit_multisine(time, value, error, start, refine="none") + assert solutions["simultaneous"].rss < none_fit.rss + + +def test_last_policy_only_moves_the_newest_frequency() -> None: + time, value, error = _two_mode() + start = np.array([12.30, 17.82]) + fit = fit_multisine(time, value, error, start, refine="last") + assert fit.frequency[0] == start[0] # untouched + assert fit.frequency[1] != start[1] # refined + + +def test_refinement_respects_per_frequency_bounds() -> None: + time, value, error = _two_mode() + lower = np.array([12.30, 17.75]) + upper = np.array([12.32, 17.78]) + fit = fit_multisine( + time, value, error, np.array([12.31, 17.76]), + refine="simultaneous", frequency_bounds=(lower, upper), + ) + assert np.all(fit.frequency >= lower - 1e-12) + assert np.all(fit.frequency <= upper + 1e-12) + + +def test_offset_only_fit_is_the_weighted_mean() -> None: + time, value, error = _two_mode() + fit = fit_multisine(time, value, error, np.zeros(0)) + weight = 1.0 / error**2 + assert fit.n_components == 0 + assert fit.offset == pytest.approx(float(np.dot(weight, value) / weight.sum())) + + +def test_adding_a_real_component_lowers_the_bic() -> None: + time, value, error = _two_mode() + base = fit_multisine(time, value, error, np.zeros(0)) + one = fit_multisine(time, value, error, np.array([12.34])) + two = fit_multisine(time, value, error, np.array([12.34, 17.81])) + assert one.bic < base.bic - 10.0 + assert two.bic < one.bic - 10.0 + assert two.aic < one.aic + + +def test_unweighted_fit_uses_the_profiled_likelihood_bic() -> None: + time, value, _ = _two_mode() + fit = fit_multisine(time, value, None, np.array([12.34])) + assert not fit.weighted + expected = fit.n_samples * np.log(fit.rss / fit.n_samples) + fit.n_parameters * ( + np.log(fit.n_samples) + ) + assert fit.bic == pytest.approx(expected) + + +def test_covariance_errors_are_calibrated_against_monte_carlo() -> None: + # 60 noise realisations of the same planted signal: the reported 1-sigma errors + # should match the realised scatter to within tens of percent. + time, clean, error = _two_mode(noise=0.002) + truth = np.array([12.34, 17.81]) + dt = time - time.mean() + signal = np.full(time.size, 10.0) + for freq, amp, phase in _TRUTH: + signal += amp * np.sin(2 * np.pi * freq * (time - time.min()) + phase) + frequencies, reported = [], [] + rng = np.random.default_rng(12) + for _ in range(60): + noisy = signal + rng.normal(0.0, 0.002, time.size) + fit = fit_multisine(time, noisy, error, truth, refine="simultaneous") + frequencies.append(fit.frequency) + reported.append(fit.frequency_error) + empirical = np.std(np.asarray(frequencies), axis=0, ddof=1) + predicted = np.mean(np.asarray(reported), axis=0) + assert np.all(predicted / empirical > 0.6) + assert np.all(predicted / empirical < 1.6) + assert dt.size == time.size # (sanity: the epoch shift did not resize anything) + + +def test_correlation_factor_is_one_for_white_noise() -> None: + rng = np.random.default_rng(3) + assert correlation_factor(rng.normal(size=5000)) == pytest.approx(1.0, abs=0.05) + + +def test_correlation_factor_rises_for_correlated_residuals() -> None: + # A slow sinusoid has long same-sign runs — what the factor exists to catch. + correlated = np.sin(np.linspace(0.0, 6 * np.pi, 3000)) + assert correlation_factor(correlated) > 100.0 + assert correlation_factor(np.array([1.0, -1.0])) == 1.0 # too few points + + +def test_analytic_errors_match_the_covariance_for_isolated_modes() -> None: + time, value, error = _two_mode(noise=0.002) + fit = fit_multisine( + time, value, error, np.array([12.34, 17.81]), refine="simultaneous" + ) + sigma_f, sigma_a, sigma_phase = analytic_uncertainties( + fit.n_samples, float(np.ptp(time)), float(np.std(fit.residuals)), fit.amplitude + ) + assert np.allclose(sigma_f, fit.frequency_error, rtol=0.25) + assert np.allclose(sigma_a, fit.amplitude_error, rtol=0.25) + assert np.allclose(sigma_phase, fit.phase_error, rtol=0.25) + + +def test_bootstrap_errors_agree_with_the_covariance() -> None: + time, value, error = _two_mode(n=600, noise=0.002) + fit = fit_multisine( + time, value, error, np.array([12.34, 17.81]), refine="simultaneous" + ) + sigma_f, sigma_a, sigma_phase = bootstrap_uncertainties( + time, error, fit, n_resamples=40, seed=1 + ) + assert np.allclose(sigma_f, fit.frequency_error, rtol=0.5) + assert np.allclose(sigma_a, fit.amplitude_error, rtol=0.5) + assert np.all(sigma_phase > 0.0) + + +def test_bootstrap_promotes_frequency_pinning_policies_to_a_full_sweep() -> None: + # Regression: "none" pins every frequency and "last" pins all but the newest, so a + # replicate fit under either policy returns the start frequencies verbatim and the + # bootstrap scatter collapses to exactly zero for the pinned components. + time, value, error = _two_mode(n=600, noise=0.002) + fit = fit_multisine( + time, value, error, np.array([12.34, 17.81]), refine="simultaneous" + ) + for policy in ("none", "last"): + sigma_f, _, _ = bootstrap_uncertainties( + time, error, fit, n_resamples=24, seed=3, refine=policy + ) + assert np.all(sigma_f > 0.1 * fit.frequency_error), policy + + +def test_component_uncertainties_apply_the_correlation_correction() -> None: + time, value, error = _two_mode() + fit = fit_multisine(time, value, error, np.array([12.34, 17.81])) + plain = component_uncertainties( + time, error, fit, method="covariance", correlation_correction=False + ) + corrected = component_uncertainties( + time, error, fit, method="covariance", correlation_correction=True + ) + assert corrected.correlation_factor >= 1.0 + assert np.all(corrected.frequency >= plain.frequency - 1e-18) + + +def test_fit_rejects_mismatched_inputs() -> None: + time, value, error = _two_mode(n=100) + with pytest.raises(ValueError, match="same length"): + fit_multisine(time, value[:-1], error[:-1], np.array([12.0])) + with pytest.raises(ValueError, match="at least one frequency"): + fit_multisine(time, value, error, np.zeros(0), fit_mean=False) diff --git a/tests/test_prewhiten_spacing.py b/tests/test_prewhiten_spacing.py new file mode 100644 index 0000000..ca8b4af --- /dev/null +++ b/tests/test_prewhiten_spacing.py @@ -0,0 +1,270 @@ +"""g-mode period spacings: comb search, tilted series, échelle, buoyancy radius.""" + +from __future__ import annotations + +import numpy as np +import pytest + +import cuperiod as cup +from cuperiod.prewhiten import prewhiten +from cuperiod.prewhiten.spacing import ( + buoyancy_radius, + echelle, + find_period_spacing, + spacing_spectrum, +) +from synth import synthetic_gmode + +_SECONDS_PER_DAY = 86400.0 + + +def _comb(n: int = 14, first: float = 0.55, spacing: float = 0.03, + slope: float = 0.0) -> np.ndarray: + periods = [first] + for _ in range(n - 1): + periods.append(periods[-1] + spacing + slope * periods[-1]) + return np.asarray(periods) + + +# --- comb search ------------------------------------------------------------- + + +def test_comb_finds_a_perfect_spacing() -> None: + periods = _comb(spacing=0.03) + result = spacing_spectrum(periods) + assert result.best_spacing == pytest.approx(0.03, rel=0.02) + assert result.best_power > 0.95 + assert result.n_values == periods.size + assert result.spacing[0] < result.spacing[-1] # ascending + + +def test_comb_survives_missing_radial_orders() -> None: + periods = _comb(n=16, spacing=0.03) + thinned = np.delete(periods, [4, 9]) + assert spacing_spectrum(thinned).best_spacing == pytest.approx(0.03, rel=0.03) + + +def test_comb_prefers_the_true_spacing_over_its_sub_multiples() -> None: + # A comb of dP/2 fits every mode a comb of dP fits, so the two responses tie + # exactly; only the wider one can be the real spacing. + periods = _comb(n=14, spacing=0.03) + result = spacing_spectrum(periods) + assert result.best_spacing == pytest.approx(0.03, rel=0.02) + half = np.argmin(np.abs(result.spacing - 0.015)) + assert result.power[half] == pytest.approx(result.best_power, rel=0.01) + + +def test_comb_response_is_low_for_random_periods() -> None: + rng = np.random.default_rng(2) + random_periods = np.sort(rng.uniform(0.5, 1.2, 14)) + assert spacing_spectrum(random_periods).best_power < 0.7 + + +def test_comb_accepts_amplitude_weights() -> None: + periods = _comb(spacing=0.03) + weights = np.linspace(1.0, 0.2, periods.size) + weighted = spacing_spectrum(periods, weights=weights) + assert weighted.best_spacing == pytest.approx(0.03, rel=0.05) + assert weighted.to_dict()["n_trials"] == weighted.size + + +def test_comb_rejects_degenerate_input() -> None: + with pytest.raises(ValueError, match="at least 3"): + spacing_spectrum(np.array([1.0, 2.0])) + with pytest.raises(ValueError, match="non-zero range"): + spacing_spectrum(np.full(5, 1.0)) + with pytest.raises(ValueError, match="minimum_spacing"): + spacing_spectrum(_comb(), minimum_spacing=1.0, maximum_spacing=0.5) + with pytest.raises(ValueError, match="same length"): + spacing_spectrum(_comb(), weights=np.ones(3)) + + +# --- series extraction ------------------------------------------------------- + + +def test_extracts_a_flat_series() -> None: + periods = _comb(n=12, spacing=0.03) + series = find_period_spacing(periods) + assert series is not None + assert series.n_modes == 12 + assert series.mean_spacing == pytest.approx(0.03, rel=1e-3) + assert abs(series.slope) < 1e-3 + assert series.rms < 1e-6 + assert np.all(series.multiplicity == 1) + + +def test_extracts_a_tilted_series_and_recovers_the_slope() -> None: + periods = _comb(n=16, spacing=0.028, slope=0.008) + series = find_period_spacing(periods) + assert series is not None + assert series.n_modes == 16 + assert series.slope == pytest.approx(0.008, rel=0.05) + + +def test_bridges_missing_orders_and_records_the_multiplicity() -> None: + periods = _comb(n=16, spacing=0.03) + thinned = np.delete(periods, [5, 10]) + series = find_period_spacing(thinned) + assert series is not None + assert series.n_modes == 14 + assert 2 in set(series.multiplicity.astype(int)) + assert series.mean_spacing == pytest.approx(0.03, rel=0.02) + + +def test_intruder_modes_are_excluded_from_the_series() -> None: + periods = _comb(n=14, spacing=0.03) + polluted = np.concatenate([periods, [0.4137, 1.2916, 0.6231]]) + # As every caller does, weight by amplitude: the intruders are weak peaks. + amplitudes = np.concatenate([np.linspace(0.006, 0.002, 14), [3e-4] * 3]) + series = find_period_spacing(polluted, amplitudes) + assert series is not None + # Indices are into the *input* array; the intruders sit at the end. + assert max(series.indices) < periods.size + assert series.n_modes == periods.size + assert series.mean_spacing == pytest.approx(0.03, rel=0.01) + + +def test_a_chain_whose_every_step_skips_an_order_is_rescaled() -> None: + # Handed a spacing half the truth, the series search must notice that no pair in + # the chain is consecutive and widen the pattern rather than report dP/2. + periods = _comb(n=12, spacing=0.03) + series = find_period_spacing(periods, spacing=0.015) + assert series is not None + assert series.mean_spacing == pytest.approx(0.03, rel=1e-3) + assert np.all(series.multiplicity == 1) + + +def test_indices_point_back_into_the_unsorted_input() -> None: + periods = _comb(n=10, spacing=0.03) + rng = np.random.default_rng(0) + order = rng.permutation(periods.size) + series = find_period_spacing(periods[order]) + assert series is not None + assert np.allclose(np.sort(periods[order][list(series.indices)]), np.sort(periods)) + + +def test_returns_none_when_no_series_is_long_enough() -> None: + rng = np.random.default_rng(5) + assert find_period_spacing(np.sort(rng.uniform(0.5, 5.0, 6))) is None + assert find_period_spacing(np.array([0.5, 0.6])) is None + + +def test_an_explicit_spacing_skips_the_comb_search() -> None: + periods = _comb(n=12, spacing=0.03) + series = find_period_spacing(periods, spacing=0.03) + assert series is not None and series.n_modes == 12 + assert find_period_spacing(periods, spacing=-1.0) is None + + +def test_amplitudes_must_match_the_periods() -> None: + with pytest.raises(ValueError, match="same length"): + find_period_spacing(_comb(), np.ones(3)) + + +def test_settings_control_the_search() -> None: + periods = _comb(n=12, spacing=0.03) + strict = cup.SpacingSettings(min_length=20) + assert find_period_spacing(periods, settings=strict) is None + lenient = cup.SpacingSettings(min_length=4, ell=2) + series = find_period_spacing(periods, settings=lenient) + assert series is not None and series.ell == 2 + + +def test_series_reporting_helpers() -> None: + periods = _comb(n=12, spacing=0.03) + series = find_period_spacing(periods) + assert series is not None + assert "Period spacing" in series.summary() + payload = series.to_dict() + assert payload["n_modes"] == 12 + assert payload["multiplicity"] == [1] * 11 + predicted = series.predicted_spacing(series.midpoints) + assert np.allclose(predicted, series.spacings, rtol=0.05) + + +# --- helpers ----------------------------------------------------------------- + + +def test_buoyancy_radius_follows_the_asymptotic_relation() -> None: + assert buoyancy_radius(0.03, 1) == pytest.approx(0.03 * np.sqrt(2) * 86400.0) + assert buoyancy_radius(0.03, 2) == pytest.approx(0.03 * np.sqrt(6) * 86400.0) + with pytest.raises(ValueError): + buoyancy_radius(0.03, 0) + + +def test_echelle_folds_a_perfect_comb_onto_one_ridge() -> None: + periods = _comb(n=12, spacing=0.03) + x, y = echelle(periods, 0.03) + assert np.allclose(y, periods) + assert float(np.ptp(x)) < 1e-9 # every mode lands on the same phase + with pytest.raises(ValueError, match="positive"): + echelle(periods, 0.0) + + +# --- end to end -------------------------------------------------------------- + + +def test_spacing_recovered_from_a_pre_whitened_g_mode_star() -> None: + time, value, error, periods = synthetic_gmode(n_modes=14) + solution = prewhiten( + (time, value, error), + settings=cup.PreWhitenSettings(backend="finufft", max_frequencies=20), + ) + assert solution.n_components >= 12 + independent = solution.independent() + series = find_period_spacing( + np.asarray([c.period for c in independent]), + np.asarray([c.amplitude for c in independent]), + ) + assert series is not None + expected = float(np.mean(np.diff(periods))) + assert series.mean_spacing == pytest.approx(expected, rel=0.05) + assert series.slope == pytest.approx(0.008, abs=0.004) + assert series.n_modes >= 12 + + +# --- regressions ------------------------------------------------------------- + + +def test_a_steeply_tilted_series_is_not_discarded() -> None: + # Regression: the refit loop used to abort whenever the fitted *intercept* went + # non-positive. The intercept is a nuisance parameter of dP = a + b*P, not a + # spacing; only a + b*P over the observed range has to be positive, and it is. + periods = np.cumsum(0.02 + 0.0015 * np.arange(20)) + 0.5 + series = find_period_spacing(periods) + assert series is not None + assert series.n_modes == 20 + assert series.intercept <= 0.0 or series.slope > 0.0 + assert np.all(series.predicted_spacing(series.midpoints) > 0.0) + for gradient in (0.0005, 0.0010, 0.0012, 0.0015): + tilted = np.cumsum(0.02 + gradient * np.arange(20)) + 0.5 + assert find_period_spacing(tilted) is not None, gradient + + +def test_a_tilted_series_survives_realistic_scatter() -> None: + rng = np.random.default_rng(0) + found = 0 + for _ in range(40): + periods = np.cumsum(0.02 + 0.0015 * np.arange(20)) + 0.5 + periods = np.sort(periods + rng.normal(0.0, 20.0 / 86400.0, 20)) + if find_period_spacing(periods) is not None: + found += 1 + assert found == 40 + + +def test_a_wide_amplitude_spread_does_not_promote_past_the_true_spacing() -> None: + # Regression: the sub-multiple promotion was judged on the amplitude-weighted + # response, so dropping every other (weak) tooth barely lowered it and the search + # was promoted to 2x the true spacing — doubling the reported dP and Pi_0. + periods = 0.5 + 0.03 * np.arange(12) + amplitudes = np.where(np.arange(12) % 2 == 0, 10.0, 0.5) + assert spacing_spectrum(periods, weights=amplitudes).best_spacing == pytest.approx( + 0.03, rel=0.02 + ) + series = find_period_spacing(periods, amplitudes) + assert series is not None + assert series.mean_spacing == pytest.approx(0.03, rel=0.02) + assert series.n_modes == 12 + assert series.buoyancy_radius == pytest.approx( + buoyancy_radius(0.03, 1), rel=0.02 + ) diff --git a/tests/test_prewhiten_spectrum.py b/tests/test_prewhiten_spectrum.py new file mode 100644 index 0000000..81ac30f --- /dev/null +++ b/tests/test_prewhiten_spectrum.py @@ -0,0 +1,277 @@ +"""Amplitude spectrum: exactness against brute-force least squares, backend parity.""" + +from __future__ import annotations + +import numpy as np +import pytest + +from conftest import requires_gpu, requires_torch +from cuperiod.core.errors import BackendUnavailableError, InsufficientDataError +from cuperiod.core.grid import GridSpec, uniform_frequency_grid +from cuperiod.prewhiten.spectrum import ( + SpectrumEngine, + amplitude_spectrum, + noise_level, + resolve_spectrum_backend, + spectral_window, + weighted_epoch, +) +from synth import synthetic_pulsator + + +def _curve(n: int = 200, span: float = 10.0, seed: int = 1): + rng = np.random.default_rng(seed) + time = np.sort(rng.uniform(0.0, span, n)) + error = rng.uniform(0.01, 0.05, n) + value = 0.3 * np.sin(2 * np.pi * 1.7 * time + 0.9) + rng.normal(0.0, error) + return time, value, error + + +def _grid(time, *, maximum=5.0, samples=3) -> GridSpec: + return uniform_frequency_grid( + float(time.max() - time.min()), + maximum_frequency=maximum, + minimum_frequency=0.1, + samples_per_peak=samples, + ) + + +def _brute_force(time, value, error, frequency, t_ref): + """The weighted least-squares (amplitude, phase) at one frequency, transparently.""" + dt = time - t_ref + design = np.column_stack( + [np.cos(2 * np.pi * frequency * dt), np.sin(2 * np.pi * frequency * dt), + np.ones(time.size)] + ) + weight = 1.0 / error + beta, *_ = np.linalg.lstsq(design * weight[:, None], value * weight, rcond=None) + return float(np.hypot(beta[0], beta[1])), float( + np.mod(np.arctan2(beta[0], beta[1]), 2 * np.pi) + ) + + +def test_lsq_amplitude_matches_brute_force_least_squares() -> None: + time, value, error = _curve() + grid = _grid(time) + spectrum = amplitude_spectrum(time, value, error, grid=grid, backend="numpy") + for index in range(0, grid.size, 37): + amp, phase = _brute_force( + time, value, error, grid.values[index], spectrum.t_ref + ) + assert spectrum.amplitude[index] == pytest.approx(amp, abs=1e-12) + wrapped = np.angle(np.exp(1j * (phase - spectrum.phase[index]))) + assert abs(wrapped) < 1e-9 + + +def test_numpy_and_finufft_backends_agree() -> None: + time, value, error = _curve() + grid = _grid(time) + direct = amplitude_spectrum(time, value, error, grid=grid, backend="numpy") + nufft = amplitude_spectrum(time, value, error, grid=grid, backend="finufft") + assert np.max(np.abs(direct.amplitude - nufft.amplitude)) < 1e-9 + assert np.max(np.abs(direct.power - nufft.power)) < 1e-9 + + +def test_dft_normalization_matches_deeming() -> None: + time, value, _ = _curve() + grid = _grid(time) + spectrum = amplitude_spectrum( + time, value, None, grid=grid, backend="numpy", normalization="dft" + ) + centred = value - value.mean() + for index in range(0, grid.size, 53): + dt = time - spectrum.t_ref + phasor = np.exp(2j * np.pi * grid.values[index] * dt) + expected = 2.0 * abs(np.sum(centred * phasor)) / time.size + assert spectrum.amplitude[index] == pytest.approx(expected, rel=1e-9) + + +def test_engine_reuses_sampling_terms_across_calls() -> None: + # The window terms depend only on the times, so evaluating two different value + # arrays on one engine must match two independent one-shot spectra exactly. + time, value, error = _curve() + grid = _grid(time) + engine = SpectrumEngine(time, error, grid=grid, backend="numpy") + other = value * 2.0 + 1.0 + first, second = engine.spectrum(value), engine.spectrum(other) + assert np.array_equal( + first.amplitude, + amplitude_spectrum(time, value, error, grid=grid, backend="numpy").amplitude, + ) + # Amplitude is linear in the data and blind to an added constant. + assert np.allclose(second.amplitude, 2.0 * first.amplitude, rtol=1e-12) + + +def test_peak_index_honours_the_exclusion_zone() -> None: + time, value, error = synthetic_pulsator(n=600, span=20.0) + grid = _grid(time, maximum=30.0, samples=6) + spectrum = amplitude_spectrum(time, value, error, grid=grid, backend="finufft") + top = spectrum.peak_index() + assert top is not None + strongest = spectrum.frequency[top] + blocked = spectrum.peak_index( + exclude=np.asarray([strongest]), separation=1.0 + ) + assert blocked is not None + assert abs(spectrum.frequency[blocked] - strongest) >= 1.0 + + +def test_refine_peak_beats_the_grid_sample() -> None: + time, value, error = synthetic_pulsator( + n=800, span=20.0, frequencies=(7.1234,), amplitudes=(0.05,), phases=(0.3,) + ) + grid = _grid(time, maximum=12.0, samples=2) # deliberately coarse + spectrum = amplitude_spectrum(time, value, error, grid=grid, backend="finufft") + index = spectrum.peak_index() + assert index is not None + refined, apex = spectrum.refine_peak(index) + assert abs(refined - 7.1234) < abs(spectrum.frequency[index] - 7.1234) + assert apex >= spectrum.amplitude[index] + + +def test_noise_level_estimators() -> None: + frequency = np.linspace(0.0, 10.0, 1001) + amplitude = np.full_like(frequency, 2.0) + amplitude[500] = 100.0 # one huge peak inside the box + assert noise_level(frequency, amplitude, 5.0, window=1.0, estimator="median") == 2.0 + assert noise_level(frequency, amplitude, 5.0, window=1.0, estimator="mean") > 2.0 + + +def test_noise_level_widens_a_box_that_is_too_narrow() -> None: + frequency = np.linspace(0.0, 10.0, 101) + amplitude = np.arange(101, dtype=float) + # A box of half-width 0.01 holds one sample; the estimator must use min_samples. + value = noise_level(frequency, amplitude, 5.0, window=0.01, min_samples=25) + assert np.isfinite(value) + assert value == pytest.approx(np.mean(amplitude[38:63]), rel=1e-9) + + +# --- the spectral window ------------------------------------------------------- + + +def test_window_matches_the_direct_sum_definition() -> None: + time, _, error = _curve() + grid = _grid(time) + engine = SpectrumEngine(time, error, grid=grid, backend="numpy") + window = engine.window() + weight = 1.0 / error**2 + weight = weight / weight.sum() + dt = time - engine.t_ref + for index in range(0, grid.size, 29): + w_f = np.sum(weight * np.exp(2j * np.pi * grid.values[index] * dt)) + assert window.amplitude[index] == pytest.approx(abs(w_f), abs=1e-12) + assert np.all(window.amplitude <= 1.0 + 1e-12) + assert np.array_equal(window.power, window.amplitude**2) + + +def test_window_peaks_at_the_sampling_alias() -> None: + # Perfectly regular sampling at dt = 0.05 d puts an exact alias at 20 c/d: the + # window there is 1, and it is small away from the aliases. + time = 0.05 * np.arange(400) + grid = uniform_frequency_grid( + float(time.max()), maximum_frequency=22.0, minimum_frequency=0.5, + samples_per_peak=5, + ) + window = spectral_window(time, grid=grid) + alias = int(np.argmin(np.abs(window.frequency - 20.0))) + # The nearest grid sample sits a fraction of a Rayleigh width off the exact alias. + assert window.amplitude[alias] > 0.99 + assert window.refine_peak(alias)[1] == pytest.approx(1.0, abs=1e-3) + midway = int(np.argmin(np.abs(window.frequency - 10.0))) + assert window.amplitude[midway] < 0.05 + + +def test_nightly_gaps_put_sidelobes_at_one_cycle_per_day() -> None: + # Single-site ground-based sampling: observations only during a fraction of each + # night alias every peak at +/- 1 c/d, which is the classic reason to look at the + # window before believing a close pair. + rng = np.random.default_rng(3) + time = np.sort( + np.concatenate([day + rng.uniform(0.0, 0.3, 12) for day in range(25)]) + ) + grid = uniform_frequency_grid( + float(time.max() - time.min()), maximum_frequency=3.0, + minimum_frequency=0.05, samples_per_peak=10, + ) + window = spectral_window(time, grid=grid) + lobe = int(np.argmin(np.abs(window.frequency - 1.0))) + assert window.amplitude[lobe] > 0.5 + assert np.all(window.amplitude <= 1.0 + 1e-12) + + +def test_window_is_identical_for_lsq_and_dft_engines() -> None: + # The window is a property of sampling and weights alone; the amplitude + # normalization must not touch it (the dft engine just computes it lazily). + time, _, error = _curve() + grid = _grid(time) + lsq = SpectrumEngine(time, error, grid=grid, backend="numpy") + dft = SpectrumEngine(time, error, grid=grid, backend="numpy", + normalization="dft") + assert np.allclose(lsq.window().amplitude, dft.window().amplitude, atol=1e-14) + + +def test_window_backends_agree() -> None: + time, _, error = _curve() + grid = _grid(time) + direct = spectral_window(time, error, grid=grid, backend="numpy") + nufft = spectral_window(time, error, grid=grid, backend="finufft") + assert np.max(np.abs(direct.amplitude - nufft.amplitude)) < 1e-9 + + +def test_weighted_epoch_decorrelates_phase_from_frequency() -> None: + time = np.array([0.0, 1.0, 2.0, 10.0]) + assert weighted_epoch(time) == pytest.approx(3.25) + weights = np.array([1.0, 1.0, 1.0, 0.0]) + assert weighted_epoch(time, weights) == pytest.approx(1.0) + + +def test_engine_rejects_a_non_uniform_grid() -> None: + time, _, error = _curve() + grid = GridSpec(kind="period", values=np.geomspace(0.1, 10.0, 50)) + with pytest.raises(ValueError, match="uniform frequency grid"): + SpectrumEngine(time, error, grid=grid) + + +def test_engine_rejects_a_short_curve() -> None: + with pytest.raises(InsufficientDataError): + SpectrumEngine(np.array([1.0, 2.0]), grid=_grid(np.array([0.0, 10.0]))) + + +def test_spectrum_rejects_mismatched_values() -> None: + time, value, error = _curve() + engine = SpectrumEngine(time, error, grid=_grid(time), backend="numpy") + with pytest.raises(ValueError, match="does not match"): + engine.spectrum(value[:-1]) + + +def test_backend_resolution() -> None: + assert resolve_spectrum_backend("numpy") == "numpy" + assert resolve_spectrum_backend("astropy") == "numpy" + assert resolve_spectrum_backend("cpu") in {"finufft", "numpy"} + assert resolve_spectrum_backend("auto") in { + "cufinufft", "torch", "finufft", "numpy" + } + with pytest.raises(BackendUnavailableError, match="unknown backend"): + resolve_spectrum_backend("nonsense") + + +@requires_torch +def test_torch_backend_matches_numpy() -> None: + time, value, error = _curve() + grid = _grid(time) + reference = amplitude_spectrum(time, value, error, grid=grid, backend="numpy") + torch_result = amplitude_spectrum( + time, value, error, grid=grid, backend="torch:cpu" + ) + assert torch_result.backend == "torch:cpu" + assert np.max(np.abs(reference.amplitude - torch_result.amplitude)) < 1e-9 + + +@requires_gpu +def test_cufinufft_backend_matches_finufft() -> None: + time, value, error = _curve(n=500, span=30.0) + grid = _grid(time, maximum=20.0, samples=5) + cpu = amplitude_spectrum(time, value, error, grid=grid, backend="finufft") + gpu = amplitude_spectrum(time, value, error, grid=grid, backend="cufinufft") + assert gpu.backend == "cufinufft" + assert np.max(np.abs(cpu.amplitude - gpu.amplitude)) < 1e-9 diff --git a/tests/test_supersmoother.py b/tests/test_supersmoother.py new file mode 100644 index 0000000..efc8498 --- /dev/null +++ b/tests/test_supersmoother.py @@ -0,0 +1,223 @@ +"""SuperSmoother: reference-package parity, backend parity, and behavior.""" + +from __future__ import annotations + +import numpy as np +import pytest +from pydantic import ValidationError + +import cuperiod as cup +from conftest import requires_gpu, requires_numba, requires_torch +from cuperiod.core.errors import InsufficientDataError +from cuperiod.methods.supersmoother import span_windows, supersmoother_score +from synth import synthetic_eclipser, synthetic_sine + +PERIOD = 0.7365 + +#: A handful of trial periods spanning wrong, true, and multiple-of-true folds. +TEST_PERIODS = np.array([0.5, PERIOD, 0.9, 1.4, 2.2]) + + +def _reference_star( + n: int = 115, seed: int = 0 +) -> tuple[np.ndarray, np.ndarray, np.ndarray]: + """A star whose point count makes cuPeriod's windows match the PyPI reference. + + cuPeriod forces span windows to odd point counts (the upstream master + semantics); the released ``supersmoother`` 0.4 truncates instead. At + ``n = 115`` (and 75) every default span truncates to an odd count already, + so the two conventions coincide and parity can be asserted exactly. + """ + rng = np.random.RandomState(seed) + t = np.sort(rng.uniform(0, 30, n)) + y = ( + 14.0 + + 0.4 * np.sin(2 * np.pi * t / PERIOD) + + 0.15 * np.sin(4 * np.pi * t / PERIOD + 0.3) + ) + dy = np.full(n, 0.05) + return t, y + rng.normal(0, 0.05, n), dy + + +# --- window semantics --------------------------------------------------------- + + +def test_span_windows_odd_and_floored() -> None: + assert span_windows((0.05, 0.2, 0.5), 100) == (5, 21, 51) + assert span_windows((0.05, 0.2, 0.5), 115) == (5, 23, 57) + assert span_windows((0.01,), 100) == (3,) + + +# --- reference parity --------------------------------------------------------- + + +def test_score_matches_reference_package() -> None: + ssm = pytest.importorskip("supersmoother") + t, y, dy = _reference_star() + mine = supersmoother_score(t, y, dy, TEST_PERIODS) + w = 1.0 / dy**2 + mu = np.average(y, weights=w) + baseline = float(np.mean(np.abs((y - mu) / dy))) + for score, p in zip(mine, TEST_PERIODS, strict=True): + model = ssm.SuperSmoother(period=p).fit(t, y, dy) + expected = 1.0 - model.cv_error(skip_endpoints=False) / baseline + assert score == pytest.approx(expected, abs=1e-9) + + +def test_score_matches_gatspy() -> None: + gp = pytest.importorskip("gatspy.periodic") + t, y, dy = _reference_star() + mine = supersmoother_score(t, y, dy, TEST_PERIODS) + ref = gp.SuperSmoother().fit(t, y, dy).score(TEST_PERIODS) + assert np.allclose(mine, ref, atol=1e-9) + + +def test_multiband_matches_gatspy() -> None: + gp = pytest.importorskip("gatspy.periodic") + tg, yg, eg = _reference_star(n=115, seed=1) + tr, yr, er = _reference_star(n=75, seed=2) + yr = yr + 1.0 # distinct band mean + mb = cup.MultiBandLightCurve.from_light_curves( + { + "g": cup.LightCurve.from_arrays(tg, yg, eg), + "r": cup.LightCurve.from_arrays(tr, yr, er), + } + ) + freqs = np.sort(1.0 / TEST_PERIODS) + grid = cup.GridSpec(kind="frequency", values=freqs, uniform=False) + pg = cup.periodogram(mb, "SuperSmoother", grid=grid, backend="numpy") + assert isinstance(pg, cup.Periodogram) + + model = gp.SuperSmootherMultiband().fit( + np.concatenate([tg, tr]), + np.concatenate([yg, yr]), + np.concatenate([eg, er]), + np.array(["g"] * tg.size + ["r"] * tr.size), + ) + expected = model.score(1.0 / freqs) + assert np.allclose(pg.power, expected, atol=1e-9) + + +# --- period recovery ---------------------------------------------------------- + + +def test_recovers_sine_period() -> None: + t, mag, err = synthetic_sine(period=0.6234) + pg = cup.periodogram((t, mag, err), "SuperSmoother", backend="numpy") + assert isinstance(pg, cup.Periodogram) + assert pg.method == "SUPERSMOOTHER" + assert pg.objective_sense == "max" + assert pg.best_period() == pytest.approx(0.6234, rel=5e-3) + + +def test_recovers_eclipser_period() -> None: + # A non-sinusoidal fold is SuperSmoother's home turf; the eclipser may + # legitimately resolve to P or, with a similar secondary, P/2. + t, flux, err = synthetic_eclipser(period=2.5, depth=0.08) + lc = cup.LightCurve.from_arrays(t, flux, err, domain=cup.Domain.FLUX) + grid = cup.GridSpec( + kind="frequency", values=np.linspace(0.2, 1.1, 3000), uniform=True + ) + pg = cup.periodogram(lc, "SuperSmoother", grid=grid, backend="numpy") + assert isinstance(pg, cup.Periodogram) + ratio = pg.best_period() / 2.5 + assert min(abs(ratio - 1.0), abs(ratio - 0.5)) < 1e-2 + + +# --- backend parity ----------------------------------------------------------- + + +def _parity_inputs() -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: + t, y, dy = _reference_star(n=180, seed=3) + periods = 1.0 / np.linspace(0.8, 2.2, 400) + return t, y, dy, periods + + +@requires_numba +@pytest.mark.parametrize("alpha", [None, 8.0]) +def test_numba_matches_numpy(alpha: float | None) -> None: + t, y, dy, periods = _parity_inputs() + cpu = supersmoother_score(t, y, dy, periods, bass_enhancement=alpha) + fast = supersmoother_score( + t, y, dy, periods, bass_enhancement=alpha, backend="numba" + ) + assert np.allclose(fast, cpu, rtol=1e-9, atol=1e-11) + + +@requires_torch +def test_torch_cpu_matches_numpy() -> None: + t, y, dy, periods = _parity_inputs() + cpu = supersmoother_score(t, y, dy, periods) + tor = supersmoother_score(t, y, dy, periods, backend="torch:cpu") + assert np.allclose(tor, cpu, rtol=1e-9, atol=1e-11) + + +@requires_gpu +def test_cupy_matches_numpy() -> None: + t, y, dy, periods = _parity_inputs() + cpu = supersmoother_score(t, y, dy, periods) + gpu = supersmoother_score(t, y, dy, periods, backend="cupy") + assert np.allclose(gpu, cpu, rtol=1e-8, atol=1e-10) + + +# --- behavior ----------------------------------------------------------------- + + +def test_input_order_invariance() -> None: + t, y, dy = _reference_star() + rng = np.random.default_rng(1) + perm = rng.permutation(t.size) + a = supersmoother_score(t, y, dy, TEST_PERIODS) + b = supersmoother_score(t[perm], y[perm], dy[perm], TEST_PERIODS) + assert np.allclose(a, b, atol=1e-12) + + +def test_alpha_ten_pins_the_largest_span() -> None: + # Full bass enhancement forces every point onto the woofer span, which must + # equal running with that single span alone (crossing both code paths). + t, y, dy = _reference_star() + pinned = supersmoother_score(t, y, dy, TEST_PERIODS, bass_enhancement=10.0) + woofer = supersmoother_score(t, y, dy, TEST_PERIODS, primary_spans=(0.5,)) + assert np.allclose(pinned, woofer, atol=1e-12) + + +def test_constant_signal_scores_zero() -> None: + t = np.linspace(0.0, 10.0, 50) + scores = supersmoother_score(t, np.ones(50), None, np.array([1.0, 2.0])) + assert np.array_equal(scores, np.zeros(2)) + + +def test_empty_periods() -> None: + t, y, dy = _reference_star() + assert supersmoother_score(t, y, dy, np.zeros(0)).size == 0 + + +def test_uniform_weights_when_no_errors() -> None: + t, y, dy = _reference_star() + scores = supersmoother_score(t, y, None, TEST_PERIODS) + assert np.all(np.isfinite(scores)) + assert int(np.argmax(scores)) == 1 # still peaks at the true period + + +# --- guards and settings ------------------------------------------------------ + + +def test_too_few_points_raises() -> None: + t, y, dy = _reference_star() + with pytest.raises(InsufficientDataError): + cup.periodogram((t[:10], y[:10], dy[:10]), "SuperSmoother") + + +def test_spans_must_increase() -> None: + with pytest.raises(ValidationError, match="strictly increasing"): + cup.SuperSmootherSettings(primary_spans=(0.5, 0.2)) + with pytest.raises(ValidationError, match=r"in \(0, 1\]"): + cup.SuperSmootherSettings(primary_spans=(0.0, 0.5)) + + +def test_single_span_runs() -> None: + t, y, dy = _reference_star() + settings = cup.SuperSmootherSettings(primary_spans=(0.3,)) + pg = cup.periodogram((t, y, dy), "SuperSmoother", settings=settings) + assert isinstance(pg, cup.Periodogram) + assert np.all(np.isfinite(pg.power)) diff --git a/tests/test_torch_bonus.py b/tests/test_torch_bonus.py index 4646574..824d1d8 100644 --- a/tests/test_torch_bonus.py +++ b/tests/test_torch_bonus.py @@ -16,7 +16,7 @@ from cuperiod.methods.mhaov import aov_power from synth import synthetic_eclipser, synthetic_sine -FREQ_METHODS = ["CE", "STRINGLENGTH", "MHAOV", "PDM"] +FREQ_METHODS = ["CE", "STRINGLENGTH", "MHAOV", "PDM", "SUPERSMOOTHER"] @requires_torch diff --git a/uv.lock b/uv.lock index edbc96c..f8fe2f4 100644 --- a/uv.lock +++ b/uv.lock @@ -2,19 +2,38 @@ version = 1 revision = 3 requires-python = ">=3.11" resolution-markers = [ - "python_full_version >= '3.15' and sys_platform == 'win32'", - "python_full_version >= '3.15' and sys_platform == 'emscripten'", - "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'emscripten'", - "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version < '3.12' and sys_platform == 'win32'", - "python_full_version < '3.12' and sys_platform == 'emscripten'", - "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] + "python_full_version >= '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", +] +conflicts = [[ + { package = "cuperiod", extra = "dev" }, + { package = "cuperiod", extra = "lsdb" }, +]] [[package]] name = "accessible-pygments" @@ -28,6 +47,146 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/8d/3f/95338030883d8c8b91223b4e21744b04d11b161a3ef117295d8241f50ab4/accessible_pygments-0.0.5-py3-none-any.whl", hash = "sha256:88ae3211e68a1d0b011504b2ffc1691feafce124b845bd072ab6f9f66f34d4b7", size = 1395903, upload-time = "2024-05-10T11:23:08.421Z" }, ] +[[package]] +name = "aiohappyeyeballs" +version = "2.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/f4/eec0465c2f67b2664688d0240b3212d5196fd89e741df67ddb81f8d35658/aiohappyeyeballs-2.7.1.tar.gz", hash = "sha256:065665c041c42a5938ed220bdcd7230f22527fbec085e1853d2402c8a3615d9d", size = 24757, upload-time = "2026-07-01T17:11:55.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/43/1947f06babed6b3f1d7f38b0c767f52df66bfb2bc10b468c4a7de9eceff2/aiohappyeyeballs-2.7.1-py3-none-any.whl", hash = "sha256:9243213661e29250eb41368e5daa826fc017156c3b8a11440826b2e3ed376472", size = 15038, upload-time = "2026-07-01T17:11:54.055Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.14.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/d9/22ce5786ac0c1653ae8b6c23bded02c1686d11f0dbb45b31ce128e0df985/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc", size = 7971213, upload-time = "2026-07-23T01:57:27.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/5c/b3e4ff8ad43a8afef9602c5e90285936da1beaea8b029016b793891f03c3/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3", size = 764250, upload-time = "2026-07-23T01:52:48.525Z" }, + { url = "https://files.pythonhosted.org/packages/0e/da/f1b384465e51449d844056b75070461da03a9a23e6c1747003695bf4172a/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a", size = 516281, upload-time = "2026-07-23T01:52:51.047Z" }, + { url = "https://files.pythonhosted.org/packages/b9/3f/01264f820ee2e3712a827892b1cd6ff80f3300c1fcbffbb45714a915d47a/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8", size = 514742, upload-time = "2026-07-23T01:52:53.779Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8d/a71c6f2db52ac1ed142b133f7feddaa6b70539c3f4de24d7e226c95b794c/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239", size = 1780613, upload-time = "2026-07-23T01:52:56.948Z" }, + { url = "https://files.pythonhosted.org/packages/a5/11/3dd9b3fb3a170f6ec9011b5291d876a6fab4086714c9e158600edf01b4fd/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f", size = 1737688, upload-time = "2026-07-23T01:52:59.294Z" }, + { url = "https://files.pythonhosted.org/packages/6d/3e/834c26918be7d88068822b40e0db30fca50b5f4fe79104aa16a93f1d74e6/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06", size = 1845742, upload-time = "2026-07-23T01:53:01.641Z" }, + { url = "https://files.pythonhosted.org/packages/cc/c9/49ab8572df7d66bc13d11e31f781292badb04180dd87ba98733066c6aed7/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929", size = 1928412, upload-time = "2026-07-23T01:53:04.018Z" }, + { url = "https://files.pythonhosted.org/packages/a5/b9/2b8f0c0ce09c87a1daf80fd483431b56b1435d3f62789bc86f572e1245de/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db", size = 1786220, upload-time = "2026-07-23T01:53:06.481Z" }, + { url = "https://files.pythonhosted.org/packages/85/00/9c45f81de11710460edfa1dc81317b6e882703b160926c879a9d20da9fcc/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce", size = 1637231, upload-time = "2026-07-23T01:53:10.258Z" }, + { url = "https://files.pythonhosted.org/packages/19/ce/967d628e910756f3539c6107cb7844a1b69440dcb3029a5ee7871b09ab63/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c", size = 1753161, upload-time = "2026-07-23T01:53:13.817Z" }, + { url = "https://files.pythonhosted.org/packages/11/b2/0c3d4114f0aee4f580f5b3b4eb71b24d7a23b834ea506a4dfebe76513f35/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15", size = 1756356, upload-time = "2026-07-23T01:53:16.211Z" }, + { url = "https://files.pythonhosted.org/packages/63/5d/99e7d91c82f1399d1ae2a854e080bd1493fbc31e5e959dbc4ec33dac3bec/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c", size = 1819846, upload-time = "2026-07-23T01:53:18.289Z" }, + { url = "https://files.pythonhosted.org/packages/ad/05/d5e1cb6480eeffd3f901d40a2c5e2d1e7effdc797837da3b490272699f13/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae", size = 1628531, upload-time = "2026-07-23T01:53:23.86Z" }, + { url = "https://files.pythonhosted.org/packages/c9/90/b934682bcaefae18a9e04f3dff5b68522ba810906358ae5029b68110ea3b/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910", size = 1832712, upload-time = "2026-07-23T01:53:27.551Z" }, + { url = "https://files.pythonhosted.org/packages/21/df/6061679faaf81fac746e7307c7adb71e858071a5d34c27583afefc64f543/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7", size = 1775014, upload-time = "2026-07-23T01:53:30.223Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1d/f854878bbc69b88faefe924b619a34a6f59ec05fd387c77690667eaa75eb/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa", size = 456006, upload-time = "2026-07-23T01:53:34.97Z" }, + { url = "https://files.pythonhosted.org/packages/73/0c/2af9d1674baccd1dbd47282a93d660a22e57ef6167c856deb24b4214fbab/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d", size = 481069, upload-time = "2026-07-23T01:53:39.673Z" }, + { url = "https://files.pythonhosted.org/packages/8e/76/88401ff3fc95e85c5fc38d588f36f55e61ecb64343b2bc8d69326f453cc0/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39", size = 453021, upload-time = "2026-07-23T01:53:43.749Z" }, + { url = "https://files.pythonhosted.org/packages/18/d4/eb96299230e20acf2efae207cb8d69051f1f68e357e5ea5e479bf6fb097a/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5", size = 754690, upload-time = "2026-07-23T01:53:47.332Z" }, + { url = "https://files.pythonhosted.org/packages/88/11/e7a70a209eb9a067c0d3212b518a0134e3484f5178c7533878b6b514d469/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228", size = 509484, upload-time = "2026-07-23T01:53:51.159Z" }, + { url = "https://files.pythonhosted.org/packages/30/07/4bbc222cc8dbe31d4c3e8a5baad2286e4d42026ac0c570027b89afce6344/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee", size = 511949, upload-time = "2026-07-23T01:53:55.083Z" }, + { url = "https://files.pythonhosted.org/packages/54/b9/42e74c46b7b7c794b995bbc1f573fb48950c38b19d8600c62a6804ee2d67/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a", size = 1765282, upload-time = "2026-07-23T01:53:59.662Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ed/62bc4d74363ad346d518e0720363a949f63e2e23439a79eb5813d4d29bb3/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b", size = 1741511, upload-time = "2026-07-23T01:54:04.063Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9f/181e8a8bc79e47d13c7fc4540bd7a3b729d9505609c61f392a8dd2fbfe55/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529", size = 1810680, upload-time = "2026-07-23T01:54:09.882Z" }, + { url = "https://files.pythonhosted.org/packages/5c/9a/dec94d6ad694552fe3424e3f1928d7a606a5d9d9433a04e7ecdd9d38ae7f/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787", size = 1905646, upload-time = "2026-07-23T01:54:13.475Z" }, + { url = "https://files.pythonhosted.org/packages/52/b7/7cd31f29d6055bd711ae6e669367fba6f5ae9de463910a793e30556a8db7/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42", size = 1792122, upload-time = "2026-07-23T01:54:15.752Z" }, + { url = "https://files.pythonhosted.org/packages/66/73/10b1ef93afa61f4963c746257b70ced619cf31a4798671de5fdb2608501d/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b", size = 1591127, upload-time = "2026-07-23T01:54:19.489Z" }, + { url = "https://files.pythonhosted.org/packages/49/ed/3b203fa6de1b338c14acdc06bf6ca9b043b7944f005966958c2ced932cde/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043", size = 1725210, upload-time = "2026-07-23T01:54:24.129Z" }, + { url = "https://files.pythonhosted.org/packages/28/b7/1c2aab8c706436dcc28598452488ac9cd7c409da815237c28c27d58993e6/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427", size = 1764848, upload-time = "2026-07-23T01:54:27.973Z" }, + { url = "https://files.pythonhosted.org/packages/54/50/94c28f08b131c4bf10984ea2c7a536c9920608bb2d6e7f95642c30cc87b7/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d", size = 1777102, upload-time = "2026-07-23T01:54:31.775Z" }, + { url = "https://files.pythonhosted.org/packages/13/d4/e7d09ba7d345fb2d74440fd2fa033c5e079fac05552927705986f41a364f/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0", size = 1580205, upload-time = "2026-07-23T01:54:34.518Z" }, + { url = "https://files.pythonhosted.org/packages/a3/84/072a91d68e1e1eb587985b54baab94221277f877e8ef274fc213a0ceae28/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d", size = 1797219, upload-time = "2026-07-23T01:54:36.995Z" }, + { url = "https://files.pythonhosted.org/packages/e0/eb/aad34e897e668424d6e995da5dff8a4a09af93363d3392488772957a63aa/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19", size = 1768629, upload-time = "2026-07-23T01:54:40.103Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2b/6bb88ddba0fecd9122aa3ebcad25996cf6c083a4a7040dbb3a4f97972af6/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559", size = 451481, upload-time = "2026-07-23T01:54:42.547Z" }, + { url = "https://files.pythonhosted.org/packages/76/9b/f2f8f108da17ecef2cc3efc424e8b7ad3782b1a8360f7b8eae8ced84f6ea/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a", size = 476845, upload-time = "2026-07-23T01:54:44.853Z" }, + { url = "https://files.pythonhosted.org/packages/3e/44/28dac80a8941b604f4da10ce21097614ca1bf905ce93dca28d8d7de9c1e7/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c", size = 448050, upload-time = "2026-07-23T01:54:47.087Z" }, + { url = "https://files.pythonhosted.org/packages/57/be/5afd201cc0ab139029aadb75392efe85a293403d9dd3a3226161c21ce00c/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86", size = 506269, upload-time = "2026-07-23T01:54:49.075Z" }, + { url = "https://files.pythonhosted.org/packages/22/09/dec8189d62b45ade009f6792a2264b942a90cb88aeaf181239933cd72c3c/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627", size = 515166, upload-time = "2026-07-23T01:54:51.894Z" }, + { url = "https://files.pythonhosted.org/packages/28/24/2854869d29ed8a8b19d74f9ec6629515f7e04d02dd329d9d179201e58e47/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82", size = 486263, upload-time = "2026-07-23T01:54:54.223Z" }, + { url = "https://files.pythonhosted.org/packages/d4/dd/57187c8be2a35aea65eaee3bd2c3dcbbcf0204f5106c89637e3610380cd1/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c", size = 492299, upload-time = "2026-07-23T01:54:56.236Z" }, + { url = "https://files.pythonhosted.org/packages/b9/11/06ae6ed8f0d414edf4068861e233d8fe23ee699bfd4b3ceb8663db948a62/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f", size = 502235, upload-time = "2026-07-23T01:54:58.377Z" }, + { url = "https://files.pythonhosted.org/packages/7e/a3/559639c34a345d2cf7c52dff6838119f2eaf29eb508227b5b83f573af813/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80", size = 750883, upload-time = "2026-07-23T01:55:00.65Z" }, + { url = "https://files.pythonhosted.org/packages/91/cd/41e131f13afd1e7b0172a9d9eda085ef90eb8439f41f0d279db81ed3ae60/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0", size = 508473, upload-time = "2026-07-23T01:55:02.945Z" }, + { url = "https://files.pythonhosted.org/packages/bc/6b/e7f13410d391c6e55b4c007a8de024355389d7d459e3d64c42b2d33617e5/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf", size = 509190, upload-time = "2026-07-23T01:55:05.173Z" }, + { url = "https://files.pythonhosted.org/packages/97/21/6464573e53d69672cc1eada3e5c5cb2d2efa82701e8305a0f2047a576967/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd", size = 1761478, upload-time = "2026-07-23T01:55:07.383Z" }, + { url = "https://files.pythonhosted.org/packages/1a/81/d217043a4c17fbce360905e3b2bdd20139ebc9a2de836d035d179c4da006/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807", size = 1735092, upload-time = "2026-07-23T01:55:09.803Z" }, + { url = "https://files.pythonhosted.org/packages/a1/66/e13a02d0eeb1a9a502402a977abb4e4abff9fe4051c26f80558c57a7c975/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8", size = 1800546, upload-time = "2026-07-23T01:55:12.012Z" }, + { url = "https://files.pythonhosted.org/packages/26/5e/57d42fca1d18cb5acc1cad945d017fabc5d6ae71d8a08ad66be8dc3ee544/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24", size = 1895250, upload-time = "2026-07-23T01:55:14.357Z" }, + { url = "https://files.pythonhosted.org/packages/ca/1c/7da8d08e74d56f00070822f9638ff3f1c563f8ad87d1efa996c87bfc8644/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5", size = 1789289, upload-time = "2026-07-23T01:55:16.668Z" }, + { url = "https://files.pythonhosted.org/packages/cd/0f/cf16bcf56896981c1a0319f5d5db9337994b5165730c48a8fa07e9b34be6/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4", size = 1586706, upload-time = "2026-07-23T01:55:18.913Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6f/76eac12a7f2480e1e304f842efdb07db33256b0d9165b866b6ef0806c202/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9", size = 1724652, upload-time = "2026-07-23T01:55:21.296Z" }, + { url = "https://files.pythonhosted.org/packages/39/b6/19c8c592baeeb94b75f966547d40c02ac7590902306ec5863d5c027cf506/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1", size = 1756239, upload-time = "2026-07-23T01:55:23.705Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c9/4e9383150296f97f873b680c4de8fb2cd88608fb9f48c79edcb111611abc/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371", size = 1769161, upload-time = "2026-07-23T01:55:26.082Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1e/147bdc6cc5de5f3ab011be8bf5d6e786633249f22c20bae06f85e45f5387/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde", size = 1578759, upload-time = "2026-07-23T01:55:28.846Z" }, + { url = "https://files.pythonhosted.org/packages/fd/31/78388a9d6040ece2e11df62ea229a822cf5e52d238374b220ae9975b2623/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e", size = 1792025, upload-time = "2026-07-23T01:55:31.457Z" }, + { url = "https://files.pythonhosted.org/packages/03/51/a3d29fdf2c25d796746af8ad6fe56a45d6256c38b0a8a2ed752e1160b3a2/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71", size = 1768477, upload-time = "2026-07-23T01:55:33.87Z" }, + { url = "https://files.pythonhosted.org/packages/29/a6/442e18b5afeade534d877a2dc3c3e392aff8d49787890b0cf84790410267/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0", size = 451069, upload-time = "2026-07-23T01:55:36.121Z" }, + { url = "https://files.pythonhosted.org/packages/9d/69/3d876ac02659f271cf7f6769f14a8e3de5b6e888ed8b5a7e998086a4cec8/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883", size = 476518, upload-time = "2026-07-23T01:55:38.303Z" }, + { url = "https://files.pythonhosted.org/packages/b2/0e/50d6e6471cd31edce8b282bdec59375a3a69124d8a989a0b1313355cae52/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2", size = 447676, upload-time = "2026-07-23T01:55:40.451Z" }, + { url = "https://files.pythonhosted.org/packages/c8/20/887fdcf832326571b370ffc347b3e70abe101096f3720126aac161b1d872/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062", size = 509067, upload-time = "2026-07-23T01:55:42.618Z" }, + { url = "https://files.pythonhosted.org/packages/ad/a3/92cec936f78cc4bf0fa5554ebe593b73459d94e3c62303e1902a4cccb6f7/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6", size = 514774, upload-time = "2026-07-23T01:55:44.937Z" }, + { url = "https://files.pythonhosted.org/packages/29/ba/2a0c38df3fc557620b6a5acd98364af050053b6285b4dc7ee74100c63c18/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919", size = 488134, upload-time = "2026-07-23T01:55:47.135Z" }, + { url = "https://files.pythonhosted.org/packages/48/d6/d51b7d4bf309af3693940d8ffd2b9ed0b682434ef85959b7c9c137f60cf8/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7", size = 494201, upload-time = "2026-07-23T01:55:49.451Z" }, + { url = "https://files.pythonhosted.org/packages/3f/5a/8f624384e5f1efabb5229b94157eb966b021e97bdb188c62860c2ae243c2/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0", size = 502766, upload-time = "2026-07-23T01:55:51.656Z" }, + { url = "https://files.pythonhosted.org/packages/a6/26/4ff0164370deec18fb19254ee4ab10b7a73304ac0c860b13f5f84663759b/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924", size = 756557, upload-time = "2026-07-23T01:55:53.964Z" }, + { url = "https://files.pythonhosted.org/packages/97/a3/7056b86dc0d9ec709ea9777eae3b0161428f943372f8b98c01c11593b682/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646", size = 510168, upload-time = "2026-07-23T01:55:56.22Z" }, + { url = "https://files.pythonhosted.org/packages/85/ed/0357a015892fd68058bf2d39d3fd1958e459b997a7db30aaa6aaa434ae96/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b", size = 512957, upload-time = "2026-07-23T01:55:58.437Z" }, + { url = "https://files.pythonhosted.org/packages/47/d1/8aba53f15ccb2238405f5e9d30e2a8ca44f93878c26e7165ade00d374b1c/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30", size = 1750149, upload-time = "2026-07-23T01:56:00.856Z" }, + { url = "https://files.pythonhosted.org/packages/49/bd/40c3fee327529284375c6701cbb0fa4600cc2e8432af1378f897e2ef7d3a/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9", size = 1707685, upload-time = "2026-07-23T01:56:03.371Z" }, + { url = "https://files.pythonhosted.org/packages/2a/a3/ca0cc6724cca8114b05694abd916060758c79894c3aa5b012cdadc1bc28e/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f", size = 1803911, upload-time = "2026-07-23T01:56:05.817Z" }, + { url = "https://files.pythonhosted.org/packages/95/b5/85b099c299c3ffd38ad9b3e43694c8a346934e4a30c88c4fd5a841234f77/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d", size = 1876929, upload-time = "2026-07-23T01:56:08.413Z" }, + { url = "https://files.pythonhosted.org/packages/d5/b7/1da684a04175473fa4cddbf9a2f572e79514c3fd27a74597f43057d4f3da/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147", size = 1761112, upload-time = "2026-07-23T01:56:10.918Z" }, + { url = "https://files.pythonhosted.org/packages/d1/16/bc4b55e3e5cb175fd69c53c90d60d2f47797cb343da5106e23863dc4dba4/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c", size = 1583500, upload-time = "2026-07-23T01:56:13.613Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e8/13a9d957a1ee40837f46aa30f0f4c657e673ad86a2e6362a9f9be20d26d9/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a", size = 1713940, upload-time = "2026-07-23T01:56:15.969Z" }, + { url = "https://files.pythonhosted.org/packages/38/05/d33c680c1bcf1c7e130f9cbfc1fc02fe8bb0c4af2a94a53dd5fb56131e5c/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0", size = 1724413, upload-time = "2026-07-23T01:56:18.591Z" }, + { url = "https://files.pythonhosted.org/packages/85/1d/af798d306f7a74b6a632dbcabcf62a4c91391b7582d2a8c6d7712e2cc54e/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661", size = 1770748, upload-time = "2026-07-23T01:56:21.074Z" }, + { url = "https://files.pythonhosted.org/packages/a8/92/ad720d472556a995049206867765e9410969684f86ee09423ff9969044c1/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22", size = 1577564, upload-time = "2026-07-23T01:56:23.475Z" }, + { url = "https://files.pythonhosted.org/packages/60/ad/0ed7586cbef7a884e23a752fa2bb987a122e6a5dd50dab109258d0a95193/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41", size = 1782080, upload-time = "2026-07-23T01:56:25.994Z" }, + { url = "https://files.pythonhosted.org/packages/97/ea/dbaed0d73e8a69aad653b045dab451c67c2454bb731a37b45a86593e9422/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf", size = 1745813, upload-time = "2026-07-23T01:56:28.604Z" }, + { url = "https://files.pythonhosted.org/packages/81/1b/6893d4bc57e434fc93a6c9217c637d967a0b651d989f6e3265179375754a/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da", size = 455872, upload-time = "2026-07-23T01:56:31.031Z" }, + { url = "https://files.pythonhosted.org/packages/f5/8b/c7baa1ba1eda4db6989baefe5de6d99834921b84ebd7918624febcb9f290/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100", size = 481030, upload-time = "2026-07-23T01:56:33.365Z" }, + { url = "https://files.pythonhosted.org/packages/22/8c/c29d067df825a2df88ca432db848aa2fe8199598359cc06c12b09320cac9/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc", size = 453669, upload-time = "2026-07-23T01:56:35.731Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a4/9c033beb355d39b6147980597ec9645e4729243f686ee4dc73945de72030/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b", size = 791403, upload-time = "2026-07-23T01:56:37.972Z" }, + { url = "https://files.pythonhosted.org/packages/80/ca/87c32a0a7704583cfc49660bd817889bae5b830bf53b5dcb4e92145ac2da/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0", size = 526413, upload-time = "2026-07-23T01:56:40.523Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d8/8ec0e471248c500acdce2be3f46db8fb62b5eb60efef072529cc85ee1d26/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e", size = 532135, upload-time = "2026-07-23T01:56:42.876Z" }, + { url = "https://files.pythonhosted.org/packages/fe/45/f8919fd936e8b79fcd9bda7b6d8e62613462a713f4f17987fd7c34399142/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716", size = 1922742, upload-time = "2026-07-23T01:56:45.528Z" }, + { url = "https://files.pythonhosted.org/packages/f6/ec/9ca76b28a27525b0cc53e20842e0228b022f301ce1f436b7d814b4aaf2df/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f", size = 1787371, upload-time = "2026-07-23T01:56:48.045Z" }, + { url = "https://files.pythonhosted.org/packages/b1/04/6acdbf17315f7b55f1937e3387acb89a3cddeb4995689553d064af8e92ab/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553", size = 1912623, upload-time = "2026-07-23T01:56:50.605Z" }, + { url = "https://files.pythonhosted.org/packages/86/e6/438b0c79ca6f45eb9fd9817dd4c01a91919a38c0de5ee9e05e2b4dc0ece7/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100", size = 2005515, upload-time = "2026-07-23T01:56:53.153Z" }, + { url = "https://files.pythonhosted.org/packages/bb/6b/62cbd6577758699525f5c712d1ddef57d9875fbab0ae8d5f5a202fd598f8/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85", size = 1879906, upload-time = "2026-07-23T01:56:55.818Z" }, + { url = "https://files.pythonhosted.org/packages/00/95/18bcbf830a21dc3aae24d8f6b6feaf3db1d2090242d00a7868db2ffb0b67/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33", size = 1675849, upload-time = "2026-07-23T01:56:58.861Z" }, + { url = "https://files.pythonhosted.org/packages/a9/19/47f4968659c5e23606c3790c80fc624e691c153d036148449ee84d31b287/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f", size = 1843496, upload-time = "2026-07-23T01:57:01.591Z" }, + { url = "https://files.pythonhosted.org/packages/64/af/38c33c4dd82fddcb4e56c4653b6f1072a8edbc6b7fa15809f14932c41e2d/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0", size = 1827746, upload-time = "2026-07-23T01:57:05.131Z" }, + { url = "https://files.pythonhosted.org/packages/a1/9d/0537cda4885ac8f5b7053d164dd06312f4c483a4edcb8ee5b8aaf2a989bf/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098", size = 1853810, upload-time = "2026-07-23T01:57:08.043Z" }, + { url = "https://files.pythonhosted.org/packages/19/fe/26f9c5e6458385aa86497836b0dea6fb2f027827d63f37c7856cce9286ee/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25", size = 1668895, upload-time = "2026-07-23T01:57:10.837Z" }, + { url = "https://files.pythonhosted.org/packages/ec/4c/618b1db9b9ba079b8875d2cdf78e7c4a3bf72903bd5850fee7dd9544600a/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9", size = 1883833, upload-time = "2026-07-23T01:57:13.672Z" }, + { url = "https://files.pythonhosted.org/packages/94/c6/bd959bd1e4771f9fd944e9e436224c48c77b018b73b519b5aad346335bcc/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb", size = 1844251, upload-time = "2026-07-23T01:57:16.593Z" }, + { url = "https://files.pythonhosted.org/packages/5e/19/08d41839658bdd44a0ed2480f3891705ecb487ce28c0dde62c9040c997e0/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963", size = 474180, upload-time = "2026-07-23T01:57:19.306Z" }, + { url = "https://files.pythonhosted.org/packages/99/5d/3cd6ef0a2b2851f7ab913b5b079334781bd50ff56a323e4454063377a080/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b", size = 500528, upload-time = "2026-07-23T01:57:21.762Z" }, + { url = "https://files.pythonhosted.org/packages/a4/37/cfd1ed540a4d318da025590d96b728e63713c09e9377950fc655dadeb856/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7", size = 469280, upload-time = "2026-07-23T01:57:24.241Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + [[package]] name = "alabaster" version = "1.0.0" @@ -55,6 +214,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] +[[package]] +name = "array-api-compat" +version = "1.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/86/12/65d297d3e425cb7fe5247b7ec14b4ed83539e9b5e89b65c15ea7ee274182/array_api_compat-1.15.0.tar.gz", hash = "sha256:53c5f922491bf15f62847afafc4e39eedfae57d218988fefb8cce39c2a9b3dea", size = 129305, upload-time = "2026-06-07T20:53:24.964Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/16/1a8fd2b19544b84575cf84ef7aa3ad4c173b756d5f087c91f85d1b295777/array_api_compat-1.15.0-py3-none-any.whl", hash = "sha256:7b1b9c53269061403fd5f45a8de349f16e7887653328bfa0c5f2d45299ff0a8e", size = 79113, upload-time = "2026-06-07T20:53:23.621Z" }, +] + [[package]] name = "ast-serialize" version = "0.5.0" @@ -127,6 +295,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/97/1e/75767a712dd23740273560df5b9dcd203362f5e5c6bea846d99a7175e233/astropy_iers_data-0.2026.6.22.1.23.34-py3-none-any.whl", hash = "sha256:d96f5102426e7ba5f28d7aabf417a547d912482afa97c24430f5c9fe9b6a884d", size = 1994066, upload-time = "2026-06-22T01:24:08.609Z" }, ] +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + [[package]] name = "babel" version = "2.18.0" @@ -149,6 +326,73 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/88/c6/92fcd42f1ba33e1184263f25bfabf3d27c383410470f169e4b8163bf9c17/beautifulsoup4-4.15.0-py3-none-any.whl", hash = "sha256:d6f88de62e1d4e38ecb1077eb9724cd0eff29d2a08ca16a401e9b9e93f117cf9", size = 109924, upload-time = "2026-06-07T16:44:21.566Z" }, ] +[[package]] +name = "bokeh" +version = "3.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "jinja2" }, + { name = "narwhals" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyyaml" }, + { name = "tornado", marker = "sys_platform != 'emscripten'" }, + { name = "xyzservices" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/dd/6f/262b649ad2fdd5ed23341452eebfa669a73b0e0c739a369204d02ee2e201/bokeh-3.9.2.tar.gz", hash = "sha256:5be30d105b329d7d2ab1cb92f51e6bd44e23f0fe21ab8d49594b220b2ab11632", size = 5751825, upload-time = "2026-07-25T16:57:56.207Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/0c/06a99ee998b1babf95074376cbf6ede5a86af726b12cbf47c4b84fa2803a/bokeh-3.9.2-py3-none-any.whl", hash = "sha256:448e07d5ee78231f5bdece3be020024bb98696c0d6b127e0e2df0b8ba8fa9765", size = 6409477, upload-time = "2026-07-25T16:57:54.62Z" }, +] + +[[package]] +name = "cdshealpix" +version = "0.8.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/e9/531fb7d7dbff947f566cfd6322eae1b30586f0bcde327670fae7a8c61b9c/cdshealpix-0.8.1.tar.gz", hash = "sha256:b5c23d66f22a67b5a4429aa9ebd3b60a9c94467f2de8218ee46cff37338cab7c", size = 1612573, upload-time = "2026-03-11T15:06:27.308Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/65/65/b59c19cf0d47dc014e7443386d440a0a48aa0681fee40a10cd124c3f23d0/cdshealpix-0.8.1-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5443b2825e2ed348e07248df3742d96db44f0d1cc53550bb8f9664c503a295b1", size = 1796269, upload-time = "2026-03-11T15:14:13.812Z" }, + { url = "https://files.pythonhosted.org/packages/66/8e/32c669570b2572aab369ef4232d15100620e4ae1b3560c7ded1eead1529b/cdshealpix-0.8.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:548e3e3fb7086b4846c2d752f1f7fe5fd7a124348eedf88fbc4f00a5f907444f", size = 1201623, upload-time = "2026-03-11T15:14:42.693Z" }, + { url = "https://files.pythonhosted.org/packages/1a/22/791bb8f56c143dc236633b0443188a825e421ae375d92ef9549d2fac1914/cdshealpix-0.8.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e777ce3ee5db03e85907f08ba6ee0a7eeda024287cb03756b0322f1180acb276", size = 1229975, upload-time = "2026-03-11T15:32:55.546Z" }, + { url = "https://files.pythonhosted.org/packages/23/6b/276c47643a15da5e9aab35d77355e189a1a0c9fb232a1c15c762cd2f805b/cdshealpix-0.8.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19decc00bcdc235841fc576f7789ec305568a8bfca81118515c4fd6bd42a9115", size = 1371585, upload-time = "2026-03-11T15:10:11.626Z" }, + { url = "https://files.pythonhosted.org/packages/2b/3b/f8915fc8fbfa8b5108d2be76d7665e995f937d419c62c52e147025a9007f/cdshealpix-0.8.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e16ea708379a7bd104a5106502212694e875527e62c073419c23c1716e3e926", size = 1295747, upload-time = "2026-03-11T15:09:13.277Z" }, + { url = "https://files.pythonhosted.org/packages/bf/98/6d7567611e1c1a21ca324d2514115b9afe2f7bae1890703c9dc5ea5023bc/cdshealpix-0.8.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:68583e11911b2010d7592b79d7162a1a9ebfd729ffd07b30810b58718beae259", size = 1780350, upload-time = "2026-03-11T15:33:03.915Z" }, + { url = "https://files.pythonhosted.org/packages/cf/fb/3f6a749eb58f93c79dfa3fa65fbb1e5421edcc848b8669969e835646eaef/cdshealpix-0.8.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98fc4c3b4bea7de58314836c55fe8fea58f3286a568840b0aad4707bafb7458c", size = 1647094, upload-time = "2026-03-11T15:10:13.861Z" }, + { url = "https://files.pythonhosted.org/packages/2e/bd/ad62b12b6318532c448b70fe8931b3aa2294f11f270c663b23532d8bdd62/cdshealpix-0.8.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8807f890d8f3d812f6bf05157161a8030a8b2e2f9753cabf627879f809d147b9", size = 2137228, upload-time = "2026-03-11T15:09:54.136Z" }, + { url = "https://files.pythonhosted.org/packages/98/98/6dbd776991c68f185a9efc23c473330c80d8cc05485e015467af50d36d97/cdshealpix-0.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:32b565178eaa482e3c21d8b6f882b2b7e4c5e0d5e4de7f817b9fd2111ce1ed22", size = 1188138, upload-time = "2026-03-11T15:09:18.273Z" }, + { url = "https://files.pythonhosted.org/packages/2e/c4/bee386870d81cf1aa1c3b259623b2f3555392395befaac32268dd277f951/cdshealpix-0.8.1-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:be9d1dc2a745b7e234c7efe5dc38a25c42822428b694891af52b41c91bb3fe2e", size = 1792399, upload-time = "2026-03-11T15:12:20.603Z" }, + { url = "https://files.pythonhosted.org/packages/33/76/213ce161729a59f2fbd4ba91e85acf62e4ba93aa88ea7acdac7853085de0/cdshealpix-0.8.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fef71c3bbcdf9056025fd9ee5fd01ed806428752d3f38b460a91dd69979181ac", size = 1199544, upload-time = "2026-03-11T15:12:56.076Z" }, + { url = "https://files.pythonhosted.org/packages/da/eb/b8a9d28ceb65c404aa5406f77a3a49eea0367a6dc25c7ce9dd0f3c4f5d69/cdshealpix-0.8.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5ec740134f1cfe2bc4981467d49ff02fcfa242f31051e32eec1b4dd470b2909", size = 1226609, upload-time = "2026-03-11T15:21:49.639Z" }, + { url = "https://files.pythonhosted.org/packages/3f/58/2ade66306b3c16cd759ebbc46b8e55f98ac6882695424e96f21fb2258beb/cdshealpix-0.8.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:017bdc48de32b7f7cfd62033da8e4c6bb86139b1f163956ce5a9d0cbd29fdfb8", size = 1366842, upload-time = "2026-03-11T15:10:46.078Z" }, + { url = "https://files.pythonhosted.org/packages/00/e6/32fcd1cf68ef0d31066cc2346045351e3bb577c7a06cf14a8fdf1e124304/cdshealpix-0.8.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c63af22e6146b329bc49e73415a9a0bfd43fde184e41a7e67d141293cdfb8518", size = 1293898, upload-time = "2026-03-11T15:10:36.927Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7a/bb1fa8b39a93feb91472cf43364f12ddd2b30c7b32044244b96e011ae00f/cdshealpix-0.8.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:beccb9b50037e1d33411dc410f438c2789d33a04ae791f5576f811580863a5d2", size = 1776767, upload-time = "2026-03-11T15:21:58.23Z" }, + { url = "https://files.pythonhosted.org/packages/79/48/4962b9292aa814ba4ae9de9f54aec3b4bca6d566521c83497eaa9ca2e644/cdshealpix-0.8.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:66637da02427431100682c9b016b9df8f432f4585c9f59237a09abd8aeea0494", size = 1641838, upload-time = "2026-03-11T15:10:48.198Z" }, + { url = "https://files.pythonhosted.org/packages/77/7c/1d38f90e9067fdd5c28fd4d01e4f0769dff21e975df0ae5e0394382b80e9/cdshealpix-0.8.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b7281d7f43741fee6fa7946370a4caa8ada727d7135affe943fc513118684fbc", size = 2135425, upload-time = "2026-03-11T15:11:17.464Z" }, + { url = "https://files.pythonhosted.org/packages/d1/20/896e49e2250ac9b2bb89bb6c949b35e69b9326507302758ca27ea8c6d87c/cdshealpix-0.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:fb374bdac0486ff28a53d5254a5374ddd39d01a33a273a21678276363482b6b4", size = 1185675, upload-time = "2026-03-11T15:07:14.472Z" }, + { url = "https://files.pythonhosted.org/packages/36/68/02de46b3f764f942bc4c2385dd5ceb0d471131df1f60c63f05634e8bb082/cdshealpix-0.8.1-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:6db405f301e49877a730fc355c3240774591059f67c99364260046808ea2d3c5", size = 1791281, upload-time = "2026-03-11T15:12:22.48Z" }, + { url = "https://files.pythonhosted.org/packages/72/5c/08ecd67852fb76c2946b888cdc1d8acbc782101b87de15cec842726e6606/cdshealpix-0.8.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1cc26c546d3fe126f1e42ee22ad17442f1cf054577d0a90aea2f1ececb2b49a8", size = 1199405, upload-time = "2026-03-11T15:13:00.249Z" }, + { url = "https://files.pythonhosted.org/packages/bc/d4/82c63a248719a4028b6e2d8231d8475316aaaf7c1f6488895178b6d648cf/cdshealpix-0.8.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad8b352c659b378c83dccf997b4cb8558cd65f4d52a5d9ff2300d05c96b206a8", size = 1226072, upload-time = "2026-03-11T15:27:12.918Z" }, + { url = "https://files.pythonhosted.org/packages/9b/7b/f8ed7d3f3e6fd5047567a00c87a7685519a92d07794f8df458347d72628a/cdshealpix-0.8.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8559242e83737fdbd9c66f7361a365c87258024df8a183b5668c255bd4eaad2", size = 1366488, upload-time = "2026-03-11T15:11:20.65Z" }, + { url = "https://files.pythonhosted.org/packages/fa/0a/167a0cf79d2365cb138008c8eb9389a0e653e43b413204ce8300cc16f587/cdshealpix-0.8.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a031ee2845447d0bd0ea28d88112922723bcc0c34c26f2e6b87938f0648b48d0", size = 1293117, upload-time = "2026-03-11T15:12:00.204Z" }, + { url = "https://files.pythonhosted.org/packages/4a/24/8d262b99c64c9999ddd99ff78429e0d0ff6758f50195895a99402d15c1ef/cdshealpix-0.8.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:eeeed1d00ca96b99d304b5ffa47059eeac24d5d73fb59f58e0c1c088749ce3ba", size = 1776241, upload-time = "2026-03-11T15:27:21.527Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8f/2ee9dbefac6e4e58f4ae0b3c744ee16e51c3959573903d3f7731b2464102/cdshealpix-0.8.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4a895c354415988dbada73d50da569052a483af1dca576d9d4b690437ac26efd", size = 1641547, upload-time = "2026-03-11T15:11:22.778Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6b/12bd07740cb838ce61b644e4877137bbfc8067176e31ca4c268e442ddc7a/cdshealpix-0.8.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e7996020963f1323e8b651c2134e616e8513fa162845cda6963ed398b1e4c63e", size = 2134665, upload-time = "2026-03-11T15:12:41.106Z" }, + { url = "https://files.pythonhosted.org/packages/d4/04/d75798437c5a6fff9e0008e5d2037cd59014f3d5a3ee8553f792b7e097e5/cdshealpix-0.8.1-cp313-cp313-win_amd64.whl", hash = "sha256:4cfe70dc091cb89b0e7edb35a8b851c58cfc8866cec5d9c2c20c36b2a4a0bbe1", size = 1185286, upload-time = "2026-03-11T15:09:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/69/45/9c2c4fed6d9503bb726f1510085aa338eccc5eee3cb9a6e9c0ceb2d89f7f/cdshealpix-0.8.1-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:9f433d948beff2ae2fb237eaa24cfc6e717ad4f5a918ef0fd11f68dc83fc79b9", size = 1791506, upload-time = "2026-03-11T15:08:49.764Z" }, + { url = "https://files.pythonhosted.org/packages/cc/ad/7d1e87d056a99d9b74accaad2d81725c564f6ae7e50d9f4a429756a41cbe/cdshealpix-0.8.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:87196290025ef7cce58df4d8f7b261ffc6d14b71edac0811a1c472c3d77e8354", size = 1200053, upload-time = "2026-03-11T15:09:19.708Z" }, + { url = "https://files.pythonhosted.org/packages/9f/17/6be1c0539552de74fb0da2e4d0c98ed12677a7d222c22fbc82e040db4c75/cdshealpix-0.8.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fe11aca64ebf4c8950f05d6e49734da3e5743a690a1b1d8d11c1f7f7defb2a7", size = 1226950, upload-time = "2026-03-11T15:32:43.506Z" }, + { url = "https://files.pythonhosted.org/packages/58/73/b2d66a7a8ed1a568ba9451de187732a5d1b9c1eeb1b651c3103c71efbd17/cdshealpix-0.8.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56f4086081727ae48ca7b061a9491614cd2111cf1fe59ac6a5917a0fd62ef232", size = 1366828, upload-time = "2026-03-11T15:11:55.279Z" }, + { url = "https://files.pythonhosted.org/packages/d9/33/99e7ccb88f825fa55453915dfb46ed44844f7090c95fd3ac539370affa0b/cdshealpix-0.8.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24296ac9623c1ddac8a07b484ce078c436370daf9ebe01bf014428967b5e4b3a", size = 1293771, upload-time = "2026-03-11T15:13:23.806Z" }, + { url = "https://files.pythonhosted.org/packages/96/5c/8bdc320b0ced48b73c7c5526fff583189c2593afdebbed67bde843c6ebdf/cdshealpix-0.8.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e7fd1dd2792f07ed354a7753d83121d24a6747189eeead10a5fdedacf26f0245", size = 1777074, upload-time = "2026-03-11T15:32:51.959Z" }, + { url = "https://files.pythonhosted.org/packages/8e/67/3d06c20099b6946a5b2ad5e35bfda7d556faeadcda8d781311edc37c1571/cdshealpix-0.8.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:bd61d9e404f8c220ea45a96cfd65820ebde1dae2c8b3113d43674ec2aa8ee671", size = 1641846, upload-time = "2026-03-11T15:11:57.338Z" }, + { url = "https://files.pythonhosted.org/packages/de/a0/96b9e2323256c5ae92d43e9b059e6bfd3328eaabd9c6a8a795a3de3d9ad9/cdshealpix-0.8.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23cbedd04e5f89daf6f6c07b99eda001d3b9f32c22b1cd940614641316229b15", size = 2135191, upload-time = "2026-03-11T15:14:04.611Z" }, + { url = "https://files.pythonhosted.org/packages/c8/76/3284fe15112fb98e2c51de7ecaa6a2fc764e0556fbd60665cec4be6d58fb/cdshealpix-0.8.1-cp314-cp314-win_amd64.whl", hash = "sha256:cdb839d545586ef6931af7cc05562923fd9044e95d78247784d007098ce0fab5", size = 1184297, upload-time = "2026-03-11T15:09:38.403Z" }, +] + [[package]] name = "certifi" version = "2026.6.17" @@ -247,6 +491,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" }, ] +[[package]] +name = "click" +version = "8.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/d4/81420972a676e8ffea40450d8c8c92943e7218a78fe9b64359836cc9876b/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6", size = 338000, upload-time = "2026-06-24T17:45:15.148Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" }, +] + +[[package]] +name = "cloudpickle" +version = "3.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/27/fb/576f067976d320f5f0114a8d9fa1215425441bb35627b1993e5afd8111e5/cloudpickle-3.1.2.tar.gz", hash = "sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414", size = 22330, upload-time = "2025-11-03T09:25:26.604Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl", hash = "sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a", size = 22228, upload-time = "2025-11-03T09:25:25.534Z" }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -256,6 +521,88 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "contourpy" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload-time = "2025-07-26T12:01:02.277Z" }, + { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload-time = "2025-07-26T12:01:04.072Z" }, + { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload-time = "2025-07-26T12:01:05.688Z" }, + { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload-time = "2025-07-26T12:01:07.054Z" }, + { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload-time = "2025-07-26T12:01:08.801Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload-time = "2025-07-26T12:01:10.319Z" }, + { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload-time = "2025-07-26T12:01:12.659Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload-time = "2025-07-26T12:01:15.533Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, + { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" }, + { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" }, + { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" }, + { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" }, + { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" }, + { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" }, + { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" }, + { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" }, + { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" }, + { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" }, + { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" }, + { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload-time = "2025-07-26T12:02:16.095Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload-time = "2025-07-26T12:02:17.524Z" }, + { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" }, + { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" }, + { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" }, + { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" }, + { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" }, + { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload-time = "2025-07-26T12:02:34.2Z" }, + { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload-time = "2025-07-26T12:02:35.807Z" }, + { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" }, + { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" }, + { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" }, + { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" }, + { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, + { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, + { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" }, + { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" }, + { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" }, + { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload-time = "2025-07-26T12:02:57.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" }, +] + [[package]] name = "coverage" version = "7.14.3" @@ -345,6 +692,31 @@ toml = [ { name = "tomli", marker = "python_full_version <= '3.11'" }, ] +[[package]] +name = "cuda-bindings" +version = "13.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-pathfinder", marker = "(python_full_version < '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32') or (python_full_version >= '3.15' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev') or (sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/6b/457ca12dad3ee9bfcc9a545cfd6b64b359ba49de40f776f6e028e678f262/cuda_bindings-13.3.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c5879712accf6e14bb01aa5e67440eb84998b8d104b509cc7a6dc0b8f656a474", size = 6053539, upload-time = "2026-05-29T23:11:43.19Z" }, + { url = "https://files.pythonhosted.org/packages/95/7a/c5e3c34a409b148f5c0f5a4ea374158f95d488862c1dffedf9aa5c639df9/cuda_bindings-13.3.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:04436a9364059c84b8f9636f359eccda1cf814341f5b670c71d80d2f79dbc708", size = 6674166, upload-time = "2026-05-29T23:11:45.478Z" }, + { url = "https://files.pythonhosted.org/packages/93/f7/0e35987a21914f84068061dcf4b61466ccbce1c62ddc9727596d5ed0c26f/cuda_bindings-13.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:507b0e19e7f934c5e30f30f0244ad70a75812619a7d3a0d742543caae1bd50f1", size = 5664286, upload-time = "2026-05-29T23:11:47.719Z" }, + { url = "https://files.pythonhosted.org/packages/ce/67/5e7dba1ba576dd73da5dee894ca076ca5e959450dfff66d6d510a255d1f7/cuda_bindings-13.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7855c4868aabc0cfae28abbe83d56734bdfbd08f08fc234ac1912a12858bf49", size = 6025351, upload-time = "2026-05-29T23:11:49.685Z" }, + { url = "https://files.pythonhosted.org/packages/39/2a/6d2e9047d1fb243dbaa364b01e0297534b9ed7fd27dba1c9f361519cf69b/cuda_bindings-13.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e32d08f71ebcdf00f0f41eab2eb37e8da94c8ed411cc9f7f7a019ce6b34abe3a", size = 6657965, upload-time = "2026-05-29T23:11:52.227Z" }, + { url = "https://files.pythonhosted.org/packages/7c/95/872a0392122f1fb43fcb06869790ef3171f37beee9f7db8f441739113570/cuda_bindings-13.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:b134dd8c5c66ae4c4ad814f7aee88fd215353c077010cbc47e3b55ed35ec9eff", size = 5875099, upload-time = "2026-05-29T23:11:54.635Z" }, + { url = "https://files.pythonhosted.org/packages/cc/6e/2394f8163360f8391f8f1b7e72d300a82724edb81a7b7084c799fbd4c91f/cuda_bindings-13.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9efb21c1ee64981e184b9e0ba5eb3179e5ba3d4b51665a6cb52b8ef3d01a7cbf", size = 5920504, upload-time = "2026-05-29T23:11:56.883Z" }, + { url = "https://files.pythonhosted.org/packages/34/c2/ef9b6a63f7dc432712a462c816662e662e00d38caa9b861c8c2588195d03/cuda_bindings-13.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2732904099e0a4d4db774a5fc6d91ee95fae065b4d2ecabb4968c5fe2406c9d7", size = 6476660, upload-time = "2026-05-29T23:11:59.188Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2f/6a0dd496550c6fafbf6aeb1bf40242eeabb2fd138a43892aabb4be8224c2/cuda_bindings-13.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:18c8c167c8907b8f02531ca810534315c458dabef31f7965095619bf647b9202", size = 5830027, upload-time = "2026-05-29T23:12:01.205Z" }, + { url = "https://files.pythonhosted.org/packages/b1/81/bff68ce829999c1e4209c761bbf903b1c06ec570416ddb25020864ad5907/cuda_bindings-13.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ab2f74ed65bfef4163ba07a8db16f1085e0729291db12a2423aff84ee8278b8", size = 6013639, upload-time = "2026-05-29T23:12:03.509Z" }, + { url = "https://files.pythonhosted.org/packages/d4/e0/c8a1f0c8f9ffdea4f5fe6dbab89b326cef4d85caf489dad39e209da89416/cuda_bindings-13.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd4c814d311ec08c981f6dded1dbe7d4b371067ee4f6c14cccec4bde9590f80", size = 6534419, upload-time = "2026-05-29T23:12:05.633Z" }, + { url = "https://files.pythonhosted.org/packages/48/45/2734be44dbc80ac082ec23a86b41c8294992dcb90033645ed1bc50aafe4c/cuda_bindings-13.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:8de12ef60bf40756852cb62bbb40460609269f6ece522903d1cc93d73a3ececb", size = 5961055, upload-time = "2026-05-29T23:12:07.971Z" }, + { url = "https://files.pythonhosted.org/packages/52/b8/83b1f563925b290f2d11a01a77a84013ba56052fe3653a5bef3ccfbb43d6/cuda_bindings-13.3.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3c772dfff49681541d59630c90f858e173ac926b9c593a2b7123f2a1043cc76", size = 5809771, upload-time = "2026-05-29T23:12:10.422Z" }, + { url = "https://files.pythonhosted.org/packages/12/20/e79b4bfe98f075195afb6343d41c498f9dbd2d161d7021d4d28bceb83581/cuda_bindings-13.3.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:36febb7c1079d68a981dbbd8d5a67235b399802b82075c9388624719607e52b9", size = 6358584, upload-time = "2026-05-29T23:12:12.767Z" }, + { url = "https://files.pythonhosted.org/packages/27/2a/b59bcac016ab9985d6b48a5d05b0d698461a159ca03ee11c4abd54da2ac4/cuda_bindings-13.3.1-cp314-cp314t-win_amd64.whl", hash = "sha256:61120b5e4f4a63f67efd7e7396914cb9ef871bb1f0021e990fb70277be240a4d", size = 6740329, upload-time = "2026-05-29T23:12:15.153Z" }, +] + [[package]] name = "cuda-pathfinder" version = "1.5.5" @@ -353,6 +725,55 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/11/c8/26f2e4aae92f11522a96043892ba39a90eac610d5242523aa863212bc1c7/cuda_pathfinder-1.5.5-py3-none-any.whl", hash = "sha256:0228c023f95d1480f143ef5c8922d27a2ab052087a942e81dc289c9eb8f91689", size = 51671, upload-time = "2026-05-27T01:21:25.413Z" }, ] +[[package]] +name = "cuda-toolkit" +version = "13.0.3.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c7/a79086a62c98befcdb8349656c6f114e2db3b8b2422f6e25c97a7f2a9a3c/cuda_toolkit-13.0.3.0-py2.py3-none-any.whl", hash = "sha256:d693caaa261214ddd7dbb60d68e71cbed884e68c2be7509778f3051da0b91c3f", size = 2512, upload-time = "2026-04-14T00:50:08.173Z" }, +] + +[package.optional-dependencies] +cublas = [ + { name = "nvidia-cublas", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-cuda-nvrtc", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +cudart = [ + { name = "nvidia-cuda-runtime", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +cufft = [ + { name = "nvidia-cufft", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-nvjitlink", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +cufile = [ + { name = "nvidia-cufile", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +cupti = [ + { name = "nvidia-cuda-cupti", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +curand = [ + { name = "nvidia-curand", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +cusolver = [ + { name = "nvidia-cublas", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-cusolver", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-cusparse", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-nvjitlink", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +cusparse = [ + { name = "nvidia-cusparse", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-nvjitlink", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +nvjitlink = [ + { name = "nvidia-nvjitlink", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +nvrtc = [ + { name = "nvidia-cuda-nvrtc", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +nvtx = [ + { name = "nvidia-nvtx", marker = "(platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] + [[package]] name = "cufinufft" version = "2.5.1" @@ -369,36 +790,45 @@ wheels = [ [[package]] name = "cuperiod" -version = "1.0.0" +version = "1.2.0" source = { editable = "." } dependencies = [ + { name = "array-api-compat" }, { name = "astropy" }, { name = "finufft" }, { name = "numpy" }, { name = "pyarrow" }, { name = "pydantic" }, { name = "pydantic-settings" }, - { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, { name = "typer" }, ] [package.optional-dependencies] dev = [ + { name = "gatspy" }, { name = "hypothesis" }, { name = "mypy" }, + { name = "nested-pandas", version = "0.7.0", source = { registry = "https://pypi.org/simple" } }, { name = "numba" }, - { name = "pandas" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" } }, + { name = "pyqtgraph" }, + { name = "pyside6" }, { name = "pytest" }, { name = "pytest-cov" }, + { name = "pytest-qt" }, { name = "ruff" }, + { name = "supersmoother" }, + { name = "torch" }, ] docs = [ { name = "furo" }, { name = "myst-parser" }, - { name = "pandas" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, { name = "sphinx-copybutton" }, { name = "sphinx-design" }, ] @@ -414,20 +844,46 @@ gpu = [ { name = "nvidia-cufft-cu12" }, { name = "nvidia-cusolver-cu12" }, ] +gui = [ + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, + { name = "pyqtgraph" }, + { name = "pyside6" }, +] +lsdb = [ + { name = "lsdb" }, + { name = "nested-pandas", version = "0.6.10", source = { registry = "https://pypi.org/simple" } }, + { name = "pyarrow" }, +] +nested = [ + { name = "nested-pandas", version = "0.6.10", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "nested-pandas", version = "0.7.0", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, + { name = "pyarrow" }, +] pandas = [ - { name = "pandas" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, +] +torch = [ + { name = "torch" }, ] [package.metadata] requires-dist = [ + { name = "array-api-compat", specifier = ">=1.9" }, { name = "astropy", specifier = ">=6.0" }, { name = "cufinufft", marker = "extra == 'gpu'", specifier = ">=2.3" }, + { name = "cuperiod", extras = ["nested"], marker = "extra == 'lsdb'" }, { name = "cupy-cuda12x", marker = "extra == 'gpu'", specifier = ">=13.3" }, { name = "finufft", specifier = ">=2.2" }, { name = "furo", marker = "extra == 'docs'", specifier = ">=2024.8" }, + { name = "gatspy", marker = "extra == 'dev'", specifier = ">=0.3" }, { name = "hypothesis", marker = "extra == 'dev'", specifier = ">=6" }, + { name = "lsdb", marker = "extra == 'lsdb'", specifier = ">=0.10.0" }, { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.11" }, { name = "myst-parser", marker = "extra == 'docs'", specifier = ">=4" }, + { name = "nested-pandas", marker = "extra == 'dev'", specifier = ">=0.7" }, + { name = "nested-pandas", marker = "extra == 'nested'", specifier = ">=0.6.10" }, { name = "numba", marker = "extra == 'dev'", specifier = ">=0.59" }, { name = "numba", marker = "extra == 'fast'", specifier = ">=0.59" }, { name = "numpy", specifier = ">=1.24" }, @@ -438,20 +894,30 @@ requires-dist = [ { name = "nvidia-cusolver-cu12", marker = "extra == 'gpu'" }, { name = "pandas", marker = "extra == 'dev'", specifier = ">=2.0" }, { name = "pandas", marker = "extra == 'docs'", specifier = ">=2.0" }, + { name = "pandas", marker = "extra == 'gui'", specifier = ">=2.0" }, { name = "pandas", marker = "extra == 'pandas'", specifier = ">=2.0" }, { name = "pyarrow", specifier = ">=14" }, + { name = "pyarrow", marker = "extra == 'nested'", specifier = ">=16" }, { name = "pydantic", specifier = ">=2.5" }, { name = "pydantic-settings", specifier = ">=2.1" }, + { name = "pyqtgraph", marker = "extra == 'dev'", specifier = ">=0.13" }, + { name = "pyqtgraph", marker = "extra == 'gui'", specifier = ">=0.13" }, + { name = "pyside6", marker = "extra == 'dev'", specifier = ">=6.6" }, + { name = "pyside6", marker = "extra == 'gui'", specifier = ">=6.6" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8" }, { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=5" }, + { name = "pytest-qt", marker = "extra == 'dev'", specifier = ">=4" }, { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.6" }, { name = "scipy", specifier = ">=1.10" }, { name = "sphinx", marker = "extra == 'docs'", specifier = ">=8" }, { name = "sphinx-copybutton", marker = "extra == 'docs'", specifier = ">=0.5" }, { name = "sphinx-design", marker = "extra == 'docs'", specifier = ">=0.6" }, + { name = "supersmoother", marker = "extra == 'dev'", specifier = ">=0.4" }, + { name = "torch", marker = "extra == 'dev'", specifier = ">=2.2" }, + { name = "torch", marker = "extra == 'torch'", specifier = ">=2.2" }, { name = "typer", specifier = ">=0.12" }, ] -provides-extras = ["gpu", "pandas", "fast", "docs", "dev"] +provides-extras = ["gpu", "pandas", "nested", "lsdb", "fast", "torch", "gui", "docs", "dev"] [[package]] name = "cupy-cuda12x" @@ -478,6 +944,73 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a4/80/5e05de89ba61df072aab6f8a6ee3ffeec57db68a0a456825b3b4ce608426/cupy_cuda12x-14.1.1-cp314-cp314t-manylinux2014_x86_64.whl", hash = "sha256:238080487174268d0f09770fe518de7c5b206527bef5c6792aef7ba0626a1c48", size = 132635338, upload-time = "2026-06-01T04:53:35.229Z" }, ] +[[package]] +name = "dask" +version = "2026.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "cloudpickle" }, + { name = "fsspec" }, + { name = "importlib-metadata", marker = "python_full_version < '3.12'" }, + { name = "packaging" }, + { name = "partd" }, + { name = "pyyaml" }, + { name = "toolz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d6/39/cbd21c9133d02b4e60899ed466ad5e876553ea68ebffee6209e7dcafc8d4/dask-2026.7.1.tar.gz", hash = "sha256:5727484427665f051e86bf87d021a64d6411141cdc8a20bfe3c1ad2968cc06b7", size = 11548794, upload-time = "2026-07-14T01:06:22.46Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/5f/7c22733da92b3a6cc4dddcaa8731089d213c2790bbc997e51c429a4e8f8b/dask-2026.7.1-py3-none-any.whl", hash = "sha256:985ffd6c5e9d7979ede515e84ae8d39b647d6aa64f77600f15714ff65f578fe6", size = 1496882, upload-time = "2026-07-14T01:06:20.341Z" }, +] + +[package.optional-dependencies] +complete = [ + { name = "bokeh" }, + { name = "distributed" }, + { name = "jinja2" }, + { name = "lz4" }, + { name = "numpy" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" } }, + { name = "pyarrow" }, +] + +[[package]] +name = "deprecated" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wrapt", marker = "extra == 'extra-8-cuperiod-lsdb'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/49/85/12f0a49a7c4ffb70572b6c2ef13c90c88fd190debda93b23f026b25f9634/deprecated-1.3.1.tar.gz", hash = "sha256:b1b50e0ff0c1fddaa5708a2c6b0a6588bb09b892825ab2b214ac9ea9d92a5223", size = 2932523, upload-time = "2025-10-30T08:19:02.757Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl", hash = "sha256:597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f", size = 11298, upload-time = "2025-10-30T08:19:00.758Z" }, +] + +[[package]] +name = "distributed" +version = "2026.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "cloudpickle" }, + { name = "dask" }, + { name = "jinja2" }, + { name = "locket" }, + { name = "msgpack" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyyaml" }, + { name = "sortedcontainers" }, + { name = "tblib" }, + { name = "toolz" }, + { name = "tornado" }, + { name = "zict" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/e4/567125e6f2f504a6b1e37e3aecd936cf61b662c09e6e79270bd37c93f703/distributed-2026.7.1.tar.gz", hash = "sha256:f7c48ab6961734874521574d75898466703bce93f22f0cff5872c7e4ac6425d4", size = 2461209, upload-time = "2026-07-14T01:20:55.349Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/4c/369f0b5665afa8ad6fb1862da979dbf61a650ea2b99b5dccda8953aa327c/distributed-2026.7.1-py3-none-any.whl", hash = "sha256:64eaf4406a04ad26acdc5b8e32fad6bac522d07539225a530bab49610b0114a9", size = 1012001, upload-time = "2026-07-14T01:20:53.684Z" }, +] + [[package]] name = "docutils" version = "0.22.4" @@ -487,6 +1020,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de", size = 633196, upload-time = "2025-12-18T19:00:18.077Z" }, ] +[[package]] +name = "filelock" +version = "3.32.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/64/a02e6765de08964ed371eca577870593245afc9dfac16d037de7c10d18e6/filelock-3.32.3.tar.gz", hash = "sha256:0ffa185a3540854c95caa7fa76b76cb219d907415e2c5dc9af25fd970563487f", size = 218135, upload-time = "2026-08-13T16:00:05.577Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/8e/50f46a9c0ce8d2861a394c1347caae037ea0431d2f67d7feb151cbc4649a/filelock-3.32.3-py3-none-any.whl", hash = "sha256:7f0ca4bcc0e181c60dbbd8aa9ab5b120ebb99e4e064e83636340056f833a1f09", size = 98901, upload-time = "2026-08-13T16:00:03.974Z" }, +] + [[package]] name = "finufft" version = "2.5.1" @@ -505,6 +1047,120 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/05/98/a6632d986102cc94a0d9a6ff665c8d736c16ce462b0955c511e17d20b053/finufft-2.5.1-py3-none-win_amd64.whl", hash = "sha256:496ad48706e77f54078e31777bd4a30f33e788ae313ef30d8b1e7d41c7539788", size = 5881286, upload-time = "2026-04-08T23:42:07.132Z" }, ] +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/03/077f869d540370db12165c0aa51640a873fb661d8b315d1d4d67b284d7ac/frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84", size = 86912, upload-time = "2025-10-06T05:35:45.98Z" }, + { url = "https://files.pythonhosted.org/packages/df/b5/7610b6bd13e4ae77b96ba85abea1c8cb249683217ef09ac9e0ae93f25a91/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9", size = 50046, upload-time = "2025-10-06T05:35:47.009Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ef/0e8f1fe32f8a53dd26bdd1f9347efe0778b0fddf62789ea683f4cc7d787d/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93", size = 50119, upload-time = "2025-10-06T05:35:48.38Z" }, + { url = "https://files.pythonhosted.org/packages/11/b1/71a477adc7c36e5fb628245dfbdea2166feae310757dea848d02bd0689fd/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f", size = 231067, upload-time = "2025-10-06T05:35:49.97Z" }, + { url = "https://files.pythonhosted.org/packages/45/7e/afe40eca3a2dc19b9904c0f5d7edfe82b5304cb831391edec0ac04af94c2/frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695", size = 233160, upload-time = "2025-10-06T05:35:51.729Z" }, + { url = "https://files.pythonhosted.org/packages/a6/aa/7416eac95603ce428679d273255ffc7c998d4132cfae200103f164b108aa/frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52", size = 228544, upload-time = "2025-10-06T05:35:53.246Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3d/2a2d1f683d55ac7e3875e4263d28410063e738384d3adc294f5ff3d7105e/frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581", size = 243797, upload-time = "2025-10-06T05:35:54.497Z" }, + { url = "https://files.pythonhosted.org/packages/78/1e/2d5565b589e580c296d3bb54da08d206e797d941a83a6fdea42af23be79c/frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567", size = 247923, upload-time = "2025-10-06T05:35:55.861Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c3/65872fcf1d326a7f101ad4d86285c403c87be7d832b7470b77f6d2ed5ddc/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b", size = 230886, upload-time = "2025-10-06T05:35:57.399Z" }, + { url = "https://files.pythonhosted.org/packages/a0/76/ac9ced601d62f6956f03cc794f9e04c81719509f85255abf96e2510f4265/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92", size = 245731, upload-time = "2025-10-06T05:35:58.563Z" }, + { url = "https://files.pythonhosted.org/packages/b9/49/ecccb5f2598daf0b4a1415497eba4c33c1e8ce07495eb07d2860c731b8d5/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d", size = 241544, upload-time = "2025-10-06T05:35:59.719Z" }, + { url = "https://files.pythonhosted.org/packages/53/4b/ddf24113323c0bbcc54cb38c8b8916f1da7165e07b8e24a717b4a12cbf10/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd", size = 241806, upload-time = "2025-10-06T05:36:00.959Z" }, + { url = "https://files.pythonhosted.org/packages/a7/fb/9b9a084d73c67175484ba2789a59f8eebebd0827d186a8102005ce41e1ba/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967", size = 229382, upload-time = "2025-10-06T05:36:02.22Z" }, + { url = "https://files.pythonhosted.org/packages/95/a3/c8fb25aac55bf5e12dae5c5aa6a98f85d436c1dc658f21c3ac73f9fa95e5/frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25", size = 39647, upload-time = "2025-10-06T05:36:03.409Z" }, + { url = "https://files.pythonhosted.org/packages/0a/f5/603d0d6a02cfd4c8f2a095a54672b3cf967ad688a60fb9faf04fc4887f65/frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b", size = 44064, upload-time = "2025-10-06T05:36:04.368Z" }, + { url = "https://files.pythonhosted.org/packages/5d/16/c2c9ab44e181f043a86f9a8f84d5124b62dbcb3a02c0977ec72b9ac1d3e0/frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a", size = 39937, upload-time = "2025-10-06T05:36:05.669Z" }, + { url = "https://files.pythonhosted.org/packages/69/29/948b9aa87e75820a38650af445d2ef2b6b8a6fab1a23b6bb9e4ef0be2d59/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1", size = 87782, upload-time = "2025-10-06T05:36:06.649Z" }, + { url = "https://files.pythonhosted.org/packages/64/80/4f6e318ee2a7c0750ed724fa33a4bdf1eacdc5a39a7a24e818a773cd91af/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b", size = 50594, upload-time = "2025-10-06T05:36:07.69Z" }, + { url = "https://files.pythonhosted.org/packages/2b/94/5c8a2b50a496b11dd519f4a24cb5496cf125681dd99e94c604ccdea9419a/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4", size = 50448, upload-time = "2025-10-06T05:36:08.78Z" }, + { url = "https://files.pythonhosted.org/packages/6a/bd/d91c5e39f490a49df14320f4e8c80161cfcce09f1e2cde1edd16a551abb3/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383", size = 242411, upload-time = "2025-10-06T05:36:09.801Z" }, + { url = "https://files.pythonhosted.org/packages/8f/83/f61505a05109ef3293dfb1ff594d13d64a2324ac3482be2cedc2be818256/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4", size = 243014, upload-time = "2025-10-06T05:36:11.394Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cb/cb6c7b0f7d4023ddda30cf56b8b17494eb3a79e3fda666bf735f63118b35/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8", size = 234909, upload-time = "2025-10-06T05:36:12.598Z" }, + { url = "https://files.pythonhosted.org/packages/31/c5/cd7a1f3b8b34af009fb17d4123c5a778b44ae2804e3ad6b86204255f9ec5/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b", size = 250049, upload-time = "2025-10-06T05:36:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/c0/01/2f95d3b416c584a1e7f0e1d6d31998c4a795f7544069ee2e0962a4b60740/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52", size = 256485, upload-time = "2025-10-06T05:36:15.39Z" }, + { url = "https://files.pythonhosted.org/packages/ce/03/024bf7720b3abaebcff6d0793d73c154237b85bdf67b7ed55e5e9596dc9a/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29", size = 237619, upload-time = "2025-10-06T05:36:16.558Z" }, + { url = "https://files.pythonhosted.org/packages/69/fa/f8abdfe7d76b731f5d8bd217827cf6764d4f1d9763407e42717b4bed50a0/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3", size = 250320, upload-time = "2025-10-06T05:36:17.821Z" }, + { url = "https://files.pythonhosted.org/packages/f5/3c/b051329f718b463b22613e269ad72138cc256c540f78a6de89452803a47d/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143", size = 246820, upload-time = "2025-10-06T05:36:19.046Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ae/58282e8f98e444b3f4dd42448ff36fa38bef29e40d40f330b22e7108f565/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608", size = 250518, upload-time = "2025-10-06T05:36:20.763Z" }, + { url = "https://files.pythonhosted.org/packages/8f/96/007e5944694d66123183845a106547a15944fbbb7154788cbf7272789536/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa", size = 239096, upload-time = "2025-10-06T05:36:22.129Z" }, + { url = "https://files.pythonhosted.org/packages/66/bb/852b9d6db2fa40be96f29c0d1205c306288f0684df8fd26ca1951d461a56/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf", size = 39985, upload-time = "2025-10-06T05:36:23.661Z" }, + { url = "https://files.pythonhosted.org/packages/b8/af/38e51a553dd66eb064cdf193841f16f077585d4d28394c2fa6235cb41765/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746", size = 44591, upload-time = "2025-10-06T05:36:24.958Z" }, + { url = "https://files.pythonhosted.org/packages/a7/06/1dc65480ab147339fecc70797e9c2f69d9cea9cf38934ce08df070fdb9cb/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd", size = 40102, upload-time = "2025-10-06T05:36:26.333Z" }, + { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, + { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, + { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, + { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, + { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, + { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, + { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, + { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, + { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, + { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, + { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, + { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, + { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, + { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, + { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, + { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, + { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, + { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, + { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, + { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, + { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, + { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, + { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, + { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, + { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, + { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, + { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, + { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, + { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + +[[package]] +name = "fsspec" +version = "2026.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/00/78/f34251dadb8f3921264a1d9b8946f5e542014ee2614b285261b4e40e6775/fsspec-2026.7.0.tar.gz", hash = "sha256:c803c40f4cf860b49dea58ee3e1c33cb9c790520e233537e1340049f89b82a88", size = 317040, upload-time = "2026-07-28T16:34:51.052Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/3c/6a2bf344106328fd04963664a60b9bb6496fc25df8e962fcdc1367285fb9/fsspec-2026.7.0-py3-none-any.whl", hash = "sha256:b57ddbafedfaef7018c1ecab32aa200a9d7ca26b77965f64e48b70061249d279", size = 206583, upload-time = "2026-07-28T16:34:49.538Z" }, +] + [[package]] name = "furo" version = "2025.12.19" @@ -513,8 +1169,8 @@ dependencies = [ { name = "accessible-pygments" }, { name = "beautifulsoup4" }, { name = "pygments" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, { name = "sphinx-basic-ng" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ec/20/5f5ad4da6a5a27c80f2ed2ee9aee3f9e36c66e56e21c00fde467b2f8f88f/furo-2025.12.19.tar.gz", hash = "sha256:188d1f942037d8b37cd3985b955839fea62baa1730087dc29d157677c857e2a7", size = 1661473, upload-time = "2025-12-19T17:34:40.889Z" } @@ -522,6 +1178,50 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f4/b2/50e9b292b5cac13e9e81272c7171301abc753a60460d21505b606e15cf21/furo-2025.12.19-py3-none-any.whl", hash = "sha256:bb0ead5309f9500130665a26bee87693c41ce4dbdff864dbfb6b0dae4673d24f", size = 339262, upload-time = "2025-12-19T17:34:38.905Z" }, ] +[[package]] +name = "gatspy" +version = "0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/fa/a075f6cd3f40255a883e8a966df17322825f6b86cb4907edce06098aa566/gatspy-0.3.tar.gz", hash = "sha256:5bb9acf524d3583985cf689f7643fb8cb380f20387b6f904b77b468bbaf982bf", size = 554464, upload-time = "2016-03-18T22:33:41.097Z" } + +[[package]] +name = "hats" +version = "0.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "astropy" }, + { name = "cdshealpix" }, + { name = "fsspec" }, + { name = "human-readable" }, + { name = "jinja2" }, + { name = "jproperties" }, + { name = "mocpy" }, + { name = "nested-pandas", version = "0.6.10", source = { registry = "https://pypi.org/simple" } }, + { name = "numba" }, + { name = "numpy" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" } }, + { name = "pyarrow" }, + { name = "pydantic" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.12' and extra == 'extra-8-cuperiod-lsdb') or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and extra == 'extra-8-cuperiod-lsdb') or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "typing-extensions" }, + { name = "universal-pathlib" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1e/a5/d8d79509be3ad10bf79dec5c3ea13c82142a16d9de5f21656eabb8e63c00/hats-0.10.4.tar.gz", hash = "sha256:832592983122ef3a051fcfd895d199edd7df32c7395b68782f05505864274953", size = 5252898, upload-time = "2026-07-22T20:22:22.448Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/85/f2c7984addf6b8cfca8860677d7aadee13cca8b316ebb4544858daea636d/hats-0.10.4-py3-none-any.whl", hash = "sha256:13c0333f3260c5f7b8b6db889a77e3a7f11625f794b641c4f6d665bc222dcb5b", size = 117324, upload-time = "2026-07-22T20:22:20.983Z" }, +] + +[[package]] +name = "human-readable" +version = "2.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/14/d066bb51de047dd387f865ac936edd6b7859b96423a125f5bbb0673a9ac4/human_readable-2.0.3.tar.gz", hash = "sha256:3f811fd56ee8669572cb2ec9f852b53ee0700748e53c3695731ffd9ab4fc524b", size = 113593, upload-time = "2026-04-24T07:34:25.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/1a/2b2398089ba316454225d90e741774e631679c1b883935e867e8da0d9a40/human_readable-2.0.3-py3-none-any.whl", hash = "sha256:ab1422ab5103a8e5a9b55aabb95d407e0bfce54c167218a29203914e56f8df53", size = 120150, upload-time = "2026-04-24T07:34:24.049Z" }, +] + [[package]] name = "hypothesis" version = "6.155.7" @@ -552,6 +1252,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl", hash = "sha256:5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96", size = 9441, upload-time = "2026-03-03T14:18:27.892Z" }, ] +[[package]] +name = "importlib-metadata" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp", marker = "python_full_version < '3.12'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/01/15bb152d77b21318514a96f43af312635eb2500c96b55398d020c93d86ea/importlib_metadata-9.0.0.tar.gz", hash = "sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc", size = 56405, upload-time = "2026-03-20T06:42:56.999Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl", hash = "sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7", size = 27789, upload-time = "2026-03-20T06:42:55.665Z" }, +] + [[package]] name = "iniconfig" version = "2.3.0" @@ -573,6 +1285,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] +[[package]] +name = "jproperties" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/27/00abf648c6d573275d409b70196b66d9fb40ef03b8d1baf671ae3774e145/jproperties-2.1.2.tar.gz", hash = "sha256:036fcd52c10a8a1c21e6fa2a1c292c93892e759b76490acc4809213a36ddc329", size = 23860, upload-time = "2024-07-21T20:40:50.29Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/6f/55bc5837e9fe7a86a5acb553adec901257d709062bfaef7debd4d8cfee12/jproperties-2.1.2-py2.py3-none-any.whl", hash = "sha256:4108e868353a9f4a12bb86a92df5462d0e18d00119169533972ce473029be79a", size = 17981, upload-time = "2024-07-21T20:40:49.034Z" }, +] + [[package]] name = "librt" version = "0.11.0" @@ -674,6 +1398,86 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4f/79/d3bbab197e86e0ff4f9c07122895b66a3e0d024247fcff7f12c473cb36d9/llvmlite-0.47.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6842cf6f707ec4be3d985a385ad03f72b2d724439e118fcbe99b2929964f0453", size = 39153839, upload-time = "2026-03-31T18:29:51.004Z" }, ] +[[package]] +name = "locket" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/83/97b29fe05cb6ae28d2dbd30b81e2e402a3eed5f460c26e9eaa5895ceacf5/locket-1.0.0.tar.gz", hash = "sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632", size = 4350, upload-time = "2022-04-20T22:04:44.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl", hash = "sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3", size = 4398, upload-time = "2022-04-20T22:04:42.23Z" }, +] + +[[package]] +name = "lsdb" +version = "0.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dask", extra = ["complete"], marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "deprecated" }, + { name = "hats" }, + { name = "human-readable" }, + { name = "nested-pandas", version = "0.6.10", source = { registry = "https://pypi.org/simple" } }, + { name = "numpy" }, + { name = "pyarrow" }, + { name = "scipy", version = "1.17.1", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version < '3.12' and extra == 'extra-8-cuperiod-lsdb') or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "scipy", version = "1.18.0", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version >= '3.12' and extra == 'extra-8-cuperiod-lsdb') or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "tabulate" }, + { name = "tqdm" }, + { name = "universal-pathlib" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/60/3a037a53cf1ddab9952960626e3c149d49b2177568111580091bcbbc8ed5/lsdb-0.10.4.tar.gz", hash = "sha256:4230ce908031fda84806dd9d3f4b38405dd80d27d152e4cdbf85d73516448807", size = 23170236, upload-time = "2026-07-22T20:39:17.063Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/32/c0071e5f05c97e52d06ca390e5d6fb9f52fd628e950e5a5d8ae58cacfd39/lsdb-0.10.4-py3-none-any.whl", hash = "sha256:01eccd14b6bc97f9722da0ba8bcf896736e8e0ebd04a4990f436248180816aff", size = 140329, upload-time = "2026-07-22T20:39:15.185Z" }, +] + +[[package]] +name = "lz4" +version = "4.4.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/51/f1b86d93029f418033dddf9b9f79c8d2641e7454080478ee2aab5123173e/lz4-4.4.5.tar.gz", hash = "sha256:5f0b9e53c1e82e88c10d7c180069363980136b9d7a8306c4dca4f760d60c39f0", size = 172886, upload-time = "2025-11-03T13:02:36.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/5b/6edcd23319d9e28b1bedf32768c3d1fd56eed8223960a2c47dacd2cec2af/lz4-4.4.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d6da84a26b3aa5da13a62e4b89ab36a396e9327de8cd48b436a3467077f8ccd4", size = 207391, upload-time = "2025-11-03T13:01:36.644Z" }, + { url = "https://files.pythonhosted.org/packages/34/36/5f9b772e85b3d5769367a79973b8030afad0d6b724444083bad09becd66f/lz4-4.4.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:61d0ee03e6c616f4a8b69987d03d514e8896c8b1b7cc7598ad029e5c6aedfd43", size = 207146, upload-time = "2025-11-03T13:01:37.928Z" }, + { url = "https://files.pythonhosted.org/packages/04/f4/f66da5647c0d72592081a37c8775feacc3d14d2625bbdaabd6307c274565/lz4-4.4.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:33dd86cea8375d8e5dd001e41f321d0a4b1eb7985f39be1b6a4f466cd480b8a7", size = 1292623, upload-time = "2025-11-03T13:01:39.341Z" }, + { url = "https://files.pythonhosted.org/packages/85/fc/5df0f17467cdda0cad464a9197a447027879197761b55faad7ca29c29a04/lz4-4.4.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:609a69c68e7cfcfa9d894dc06be13f2e00761485b62df4e2472f1b66f7b405fb", size = 1279982, upload-time = "2025-11-03T13:01:40.816Z" }, + { url = "https://files.pythonhosted.org/packages/25/3b/b55cb577aa148ed4e383e9700c36f70b651cd434e1c07568f0a86c9d5fbb/lz4-4.4.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:75419bb1a559af00250b8f1360d508444e80ed4b26d9d40ec5b09fe7875cb989", size = 1368674, upload-time = "2025-11-03T13:01:42.118Z" }, + { url = "https://files.pythonhosted.org/packages/fb/31/e97e8c74c59ea479598e5c55cbe0b1334f03ee74ca97726e872944ed42df/lz4-4.4.5-cp311-cp311-win32.whl", hash = "sha256:12233624f1bc2cebc414f9efb3113a03e89acce3ab6f72035577bc61b270d24d", size = 88168, upload-time = "2025-11-03T13:01:43.282Z" }, + { url = "https://files.pythonhosted.org/packages/18/47/715865a6c7071f417bef9b57c8644f29cb7a55b77742bd5d93a609274e7e/lz4-4.4.5-cp311-cp311-win_amd64.whl", hash = "sha256:8a842ead8ca7c0ee2f396ca5d878c4c40439a527ebad2b996b0444f0074ed004", size = 99491, upload-time = "2025-11-03T13:01:44.167Z" }, + { url = "https://files.pythonhosted.org/packages/14/e7/ac120c2ca8caec5c945e6356ada2aa5cfabd83a01e3170f264a5c42c8231/lz4-4.4.5-cp311-cp311-win_arm64.whl", hash = "sha256:83bc23ef65b6ae44f3287c38cbf82c269e2e96a26e560aa551735883388dcc4b", size = 91271, upload-time = "2025-11-03T13:01:45.016Z" }, + { url = "https://files.pythonhosted.org/packages/1b/ac/016e4f6de37d806f7cc8f13add0a46c9a7cfc41a5ddc2bc831d7954cf1ce/lz4-4.4.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:df5aa4cead2044bab83e0ebae56e0944cc7fcc1505c7787e9e1057d6d549897e", size = 207163, upload-time = "2025-11-03T13:01:45.895Z" }, + { url = "https://files.pythonhosted.org/packages/8d/df/0fadac6e5bd31b6f34a1a8dbd4db6a7606e70715387c27368586455b7fc9/lz4-4.4.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d0bf51e7745484d2092b3a51ae6eb58c3bd3ce0300cf2b2c14f76c536d5697a", size = 207150, upload-time = "2025-11-03T13:01:47.205Z" }, + { url = "https://files.pythonhosted.org/packages/b7/17/34e36cc49bb16ca73fb57fbd4c5eaa61760c6b64bce91fcb4e0f4a97f852/lz4-4.4.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7b62f94b523c251cf32aa4ab555f14d39bd1a9df385b72443fd76d7c7fb051f5", size = 1292045, upload-time = "2025-11-03T13:01:48.667Z" }, + { url = "https://files.pythonhosted.org/packages/90/1c/b1d8e3741e9fc89ed3b5f7ef5f22586c07ed6bb04e8343c2e98f0fa7ff04/lz4-4.4.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c3ea562c3af274264444819ae9b14dbbf1ab070aff214a05e97db6896c7597e", size = 1279546, upload-time = "2025-11-03T13:01:50.159Z" }, + { url = "https://files.pythonhosted.org/packages/55/d9/e3867222474f6c1b76e89f3bd914595af69f55bf2c1866e984c548afdc15/lz4-4.4.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:24092635f47538b392c4eaeff14c7270d2c8e806bf4be2a6446a378591c5e69e", size = 1368249, upload-time = "2025-11-03T13:01:51.273Z" }, + { url = "https://files.pythonhosted.org/packages/b2/e7/d667d337367686311c38b580d1ca3d5a23a6617e129f26becd4f5dc458df/lz4-4.4.5-cp312-cp312-win32.whl", hash = "sha256:214e37cfe270948ea7eb777229e211c601a3e0875541c1035ab408fbceaddf50", size = 88189, upload-time = "2025-11-03T13:01:52.605Z" }, + { url = "https://files.pythonhosted.org/packages/a5/0b/a54cd7406995ab097fceb907c7eb13a6ddd49e0b231e448f1a81a50af65c/lz4-4.4.5-cp312-cp312-win_amd64.whl", hash = "sha256:713a777de88a73425cf08eb11f742cd2c98628e79a8673d6a52e3c5f0c116f33", size = 99497, upload-time = "2025-11-03T13:01:53.477Z" }, + { url = "https://files.pythonhosted.org/packages/6a/7e/dc28a952e4bfa32ca16fa2eb026e7a6ce5d1411fcd5986cd08c74ec187b9/lz4-4.4.5-cp312-cp312-win_arm64.whl", hash = "sha256:a88cbb729cc333334ccfb52f070463c21560fca63afcf636a9f160a55fac3301", size = 91279, upload-time = "2025-11-03T13:01:54.419Z" }, + { url = "https://files.pythonhosted.org/packages/2f/46/08fd8ef19b782f301d56a9ccfd7dafec5fd4fc1a9f017cf22a1accb585d7/lz4-4.4.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6bb05416444fafea170b07181bc70640975ecc2a8c92b3b658c554119519716c", size = 207171, upload-time = "2025-11-03T13:01:56.595Z" }, + { url = "https://files.pythonhosted.org/packages/8f/3f/ea3334e59de30871d773963997ecdba96c4584c5f8007fd83cfc8f1ee935/lz4-4.4.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b424df1076e40d4e884cfcc4c77d815368b7fb9ebcd7e634f937725cd9a8a72a", size = 207163, upload-time = "2025-11-03T13:01:57.721Z" }, + { url = "https://files.pythonhosted.org/packages/41/7b/7b3a2a0feb998969f4793c650bb16eff5b06e80d1f7bff867feb332f2af2/lz4-4.4.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:216ca0c6c90719731c64f41cfbd6f27a736d7e50a10b70fad2a9c9b262ec923d", size = 1292136, upload-time = "2025-11-03T13:02:00.375Z" }, + { url = "https://files.pythonhosted.org/packages/89/d1/f1d259352227bb1c185288dd694121ea303e43404aa77560b879c90e7073/lz4-4.4.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:533298d208b58b651662dd972f52d807d48915176e5b032fb4f8c3b6f5fe535c", size = 1279639, upload-time = "2025-11-03T13:02:01.649Z" }, + { url = "https://files.pythonhosted.org/packages/d2/fb/ba9256c48266a09012ed1d9b0253b9aa4fe9cdff094f8febf5b26a4aa2a2/lz4-4.4.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:451039b609b9a88a934800b5fc6ee401c89ad9c175abf2f4d9f8b2e4ef1afc64", size = 1368257, upload-time = "2025-11-03T13:02:03.35Z" }, + { url = "https://files.pythonhosted.org/packages/a5/6d/dee32a9430c8b0e01bbb4537573cabd00555827f1a0a42d4e24ca803935c/lz4-4.4.5-cp313-cp313-win32.whl", hash = "sha256:a5f197ffa6fc0e93207b0af71b302e0a2f6f29982e5de0fbda61606dd3a55832", size = 88191, upload-time = "2025-11-03T13:02:04.406Z" }, + { url = "https://files.pythonhosted.org/packages/18/e0/f06028aea741bbecb2a7e9648f4643235279a770c7ffaf70bd4860c73661/lz4-4.4.5-cp313-cp313-win_amd64.whl", hash = "sha256:da68497f78953017deb20edff0dba95641cc86e7423dfadf7c0264e1ac60dc22", size = 99502, upload-time = "2025-11-03T13:02:05.886Z" }, + { url = "https://files.pythonhosted.org/packages/61/72/5bef44afb303e56078676b9f2486f13173a3c1e7f17eaac1793538174817/lz4-4.4.5-cp313-cp313-win_arm64.whl", hash = "sha256:c1cfa663468a189dab510ab231aad030970593f997746d7a324d40104db0d0a9", size = 91285, upload-time = "2025-11-03T13:02:06.77Z" }, + { url = "https://files.pythonhosted.org/packages/49/55/6a5c2952971af73f15ed4ebfdd69774b454bd0dc905b289082ca8664fba1/lz4-4.4.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:67531da3b62f49c939e09d56492baf397175ff39926d0bd5bd2d191ac2bff95f", size = 207348, upload-time = "2025-11-03T13:02:08.117Z" }, + { url = "https://files.pythonhosted.org/packages/4e/d7/fd62cbdbdccc35341e83aabdb3f6d5c19be2687d0a4eaf6457ddf53bba64/lz4-4.4.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a1acbbba9edbcbb982bc2cac5e7108f0f553aebac1040fbec67a011a45afa1ba", size = 207340, upload-time = "2025-11-03T13:02:09.152Z" }, + { url = "https://files.pythonhosted.org/packages/77/69/225ffadaacb4b0e0eb5fd263541edd938f16cd21fe1eae3cd6d5b6a259dc/lz4-4.4.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a482eecc0b7829c89b498fda883dbd50e98153a116de612ee7c111c8bcf82d1d", size = 1293398, upload-time = "2025-11-03T13:02:10.272Z" }, + { url = "https://files.pythonhosted.org/packages/c6/9e/2ce59ba4a21ea5dc43460cba6f34584e187328019abc0e66698f2b66c881/lz4-4.4.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e099ddfaa88f59dd8d36c8a3c66bd982b4984edf127eb18e30bb49bdba68ce67", size = 1281209, upload-time = "2025-11-03T13:02:12.091Z" }, + { url = "https://files.pythonhosted.org/packages/80/4f/4d946bd1624ec229b386a3bc8e7a85fa9a963d67d0a62043f0af0978d3da/lz4-4.4.5-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2af2897333b421360fdcce895c6f6281dc3fab018d19d341cf64d043fc8d90d", size = 1369406, upload-time = "2025-11-03T13:02:13.683Z" }, + { url = "https://files.pythonhosted.org/packages/02/a2/d429ba4720a9064722698b4b754fb93e42e625f1318b8fe834086c7c783b/lz4-4.4.5-cp313-cp313t-win32.whl", hash = "sha256:66c5de72bf4988e1b284ebdd6524c4bead2c507a2d7f172201572bac6f593901", size = 88325, upload-time = "2025-11-03T13:02:14.743Z" }, + { url = "https://files.pythonhosted.org/packages/4b/85/7ba10c9b97c06af6c8f7032ec942ff127558863df52d866019ce9d2425cf/lz4-4.4.5-cp313-cp313t-win_amd64.whl", hash = "sha256:cdd4bdcbaf35056086d910d219106f6a04e1ab0daa40ec0eeef1626c27d0fddb", size = 99643, upload-time = "2025-11-03T13:02:15.978Z" }, + { url = "https://files.pythonhosted.org/packages/77/4d/a175459fb29f909e13e57c8f475181ad8085d8d7869bd8ad99033e3ee5fa/lz4-4.4.5-cp313-cp313t-win_arm64.whl", hash = "sha256:28ccaeb7c5222454cd5f60fcd152564205bcb801bd80e125949d2dfbadc76bbd", size = 91504, upload-time = "2025-11-03T13:02:17.313Z" }, + { url = "https://files.pythonhosted.org/packages/63/9c/70bdbdb9f54053a308b200b4678afd13efd0eafb6ddcbb7f00077213c2e5/lz4-4.4.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c216b6d5275fc060c6280936bb3bb0e0be6126afb08abccde27eed23dead135f", size = 207586, upload-time = "2025-11-03T13:02:18.263Z" }, + { url = "https://files.pythonhosted.org/packages/b6/cb/bfead8f437741ce51e14b3c7d404e3a1f6b409c440bad9b8f3945d4c40a7/lz4-4.4.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c8e71b14938082ebaf78144f3b3917ac715f72d14c076f384a4c062df96f9df6", size = 207161, upload-time = "2025-11-03T13:02:19.286Z" }, + { url = "https://files.pythonhosted.org/packages/e7/18/b192b2ce465dfbeabc4fc957ece7a1d34aded0d95a588862f1c8a86ac448/lz4-4.4.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9b5e6abca8df9f9bdc5c3085f33ff32cdc86ed04c65e0355506d46a5ac19b6e9", size = 1292415, upload-time = "2025-11-03T13:02:20.829Z" }, + { url = "https://files.pythonhosted.org/packages/67/79/a4e91872ab60f5e89bfad3e996ea7dc74a30f27253faf95865771225ccba/lz4-4.4.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3b84a42da86e8ad8537aabef062e7f661f4a877d1c74d65606c49d835d36d668", size = 1279920, upload-time = "2025-11-03T13:02:22.013Z" }, + { url = "https://files.pythonhosted.org/packages/f1/01/d52c7b11eaa286d49dae619c0eec4aabc0bf3cda7a7467eb77c62c4471f3/lz4-4.4.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bba042ec5a61fa77c7e380351a61cb768277801240249841defd2ff0a10742f", size = 1368661, upload-time = "2025-11-03T13:02:23.208Z" }, + { url = "https://files.pythonhosted.org/packages/f7/da/137ddeea14c2cb86864838277b2607d09f8253f152156a07f84e11768a28/lz4-4.4.5-cp314-cp314-win32.whl", hash = "sha256:bd85d118316b53ed73956435bee1997bd06cc66dd2fa74073e3b1322bd520a67", size = 90139, upload-time = "2025-11-03T13:02:24.301Z" }, + { url = "https://files.pythonhosted.org/packages/18/2c/8332080fd293f8337779a440b3a143f85e374311705d243439a3349b81ad/lz4-4.4.5-cp314-cp314-win_amd64.whl", hash = "sha256:92159782a4502858a21e0079d77cdcaade23e8a5d252ddf46b0652604300d7be", size = 101497, upload-time = "2025-11-03T13:02:25.187Z" }, + { url = "https://files.pythonhosted.org/packages/ca/28/2635a8141c9a4f4bc23f5135a92bbcf48d928d8ca094088c962df1879d64/lz4-4.4.5-cp314-cp314-win_arm64.whl", hash = "sha256:d994b87abaa7a88ceb7a37c90f547b8284ff9da694e6afcfaa8568d739faf3f7", size = 93812, upload-time = "2025-11-03T13:02:26.133Z" }, +] + [[package]] name = "markdown-it-py" version = "4.2.0" @@ -781,6 +1585,230 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] +[[package]] +name = "mocpy" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/24/d1/2d524e558c170c22c1eff0b67da03cc82072ddf3a203ddf66b90828f2c58/mocpy-0.20.0.tar.gz", hash = "sha256:a593519e28eef91635ca151fc8b258ac6a56ae6c5c714bfdffc8ab167911f477", size = 103010, upload-time = "2026-03-10T09:03:49.464Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/ca/08bcc6f8a98fefa6417ab10bc6ec53b2dd473487b63695e1d38183a3fc41/mocpy-0.20.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:43e4584101870aac526432713564c515700679eaf35669d7ed679dfeb057e24a", size = 2241380, upload-time = "2026-03-10T09:05:37.327Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/d4f138bff343d7b53b4019690b63a148c16728caa49bd0ed20a51e5fc72d/mocpy-0.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37e0178aa880db10be69d1f7f8b302a98e70dc32fd57b69c256ecf75b03cf6c4", size = 1142276, upload-time = "2026-03-10T09:06:13.777Z" }, + { url = "https://files.pythonhosted.org/packages/73/27/20d0e26eb9a15823670fdb39de8077d865758484458069e0d5f5b0c2d31e/mocpy-0.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa5bdfd873248928cfc1420de48ec1ea67d94bb67a382dee63490530191d2213", size = 1180022, upload-time = "2026-03-10T09:32:58.472Z" }, + { url = "https://files.pythonhosted.org/packages/73/92/a05557804d51ce3167d0209229c8bd1ba4c88baf777fc2a1dd5746b0d569/mocpy-0.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:632835b4ecfc5f67c05dd56c20325597b032d703d9c2ae4359c1029695f8ca2e", size = 1273916, upload-time = "2026-03-10T10:09:32.672Z" }, + { url = "https://files.pythonhosted.org/packages/6a/03/f58e4a0cc0aa9394217cfc2e6c198b33666958b66a3971045a5a5ade77b9/mocpy-0.20.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:ac7caf23e0a919c91dcea0715047a7d6ffb96f47ffce01ba87ef23b73b84a444", size = 1274326, upload-time = "2026-03-10T09:05:38.237Z" }, + { url = "https://files.pythonhosted.org/packages/2d/69/a44cfeb890006682a717e56a792b22f13ca7fc2790ec75cc555f7e5d2adb/mocpy-0.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:02caacf03334a6b2c4f8c1b0d095b0a86d29787a067a8dc3d89ce0ef03478c85", size = 1730637, upload-time = "2026-03-10T09:33:07.375Z" }, + { url = "https://files.pythonhosted.org/packages/5b/71/41bb800e8b0bfc5ceb019565fb7f07667cbe642dd0520ac5547a749cd18c/mocpy-0.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:57a510a57ec597de87da0d9d552e6f17ba53ec9c3928c23c1d371978693efdff", size = 1177191, upload-time = "2026-03-10T09:04:22.157Z" }, + { url = "https://files.pythonhosted.org/packages/1a/01/8ab6fd33f27f10b2d78d5345079a606445ae480e3a82258b101a8b0f7228/mocpy-0.20.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:95a4dd0b351bf4cbff25ed60bfc034cbe46f51a707f5d21dd341f9b65c24100f", size = 2238560, upload-time = "2026-03-10T09:08:14.624Z" }, + { url = "https://files.pythonhosted.org/packages/4b/bf/05fdb9434010e827b70abf5c40382c6d4eae236b10ceb1ab77e2243a22b4/mocpy-0.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47d667a537e47561637f80bf4462552c9b1dbae2ba8a4d24f99e92154c58d86f", size = 1140946, upload-time = "2026-03-10T09:09:04.507Z" }, + { url = "https://files.pythonhosted.org/packages/5c/47/79484c7bf4e7135ab4b89c44643f93b7891e26b5040fcff68cc84ac69c6e/mocpy-0.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4e3d9226fb86e64af2c848872647976a5df650c9379313df23c6805af70daea", size = 1178636, upload-time = "2026-03-10T09:38:22.489Z" }, + { url = "https://files.pythonhosted.org/packages/c5/d0/fb36347ef6174fd54fe0a0f196cfd6f6e4d6db0c33ff4f9942400055f066/mocpy-0.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62bf14da56f01695059113892d9ede1b8cf1bae23ad3cd68348e731fbd4bd3d9", size = 1273426, upload-time = "2026-03-10T10:10:45.667Z" }, + { url = "https://files.pythonhosted.org/packages/44/55/6724a1fbfa5da67ab8370782e23919919a0724e19aa3bd7c6970191fcbd8/mocpy-0.20.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:3deefcde58851bbd734064d07e0253789fe62b5553802624f9ff476965dad625", size = 1274048, upload-time = "2026-03-10T09:06:32.062Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d9/905ab955dd790a5b2d97323b3899a5e3ff1ed7af2171200d8074040af4ba/mocpy-0.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f65a8c7aef21a2ba6fe05df48d8da8f3ac73626da5d64c1b91d3618a5a329431", size = 1728518, upload-time = "2026-03-10T09:38:32.913Z" }, + { url = "https://files.pythonhosted.org/packages/89/93/0b797d65607f4a71fe65490f7eb518be7e46994e2fabda524698900830bf/mocpy-0.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:b3a815df302170baffd27ef3b6d6eecb7f5586307fb651bf1d0630b1c543a0fb", size = 1175996, upload-time = "2026-03-10T09:04:54.091Z" }, + { url = "https://files.pythonhosted.org/packages/35/9c/c683d754f2f183c1e8375f846f26f9a75c86889609e036b10e76420cd91d/mocpy-0.20.0-cp313-cp313-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:efbc6e55444f2006d82b6e0f10f14ad26923a70405b7c1b08654bfea261af710", size = 2238104, upload-time = "2026-03-10T09:05:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/fb/26/824d41d872c982cb0581bcc2ac70b67e6d3294885682c6b94bcbc859cbfe/mocpy-0.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ac506f39416e6b870ae9f9eb67084fdcbdffcbcf83f36feac707a8f1887c7276", size = 1140826, upload-time = "2026-03-10T09:06:02.59Z" }, + { url = "https://files.pythonhosted.org/packages/9b/d3/13a0d2cdbd323187c111883d4bc1510eba51ba7e1b1574fd441cf0c917e1/mocpy-0.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91cc2cff28c512b0f56189bde4ecb44c9a89ede083d2ed87b61e5d03f010fbd", size = 1273045, upload-time = "2026-03-10T10:11:47.713Z" }, + { url = "https://files.pythonhosted.org/packages/9a/f8/dccfe5479abdf75095a91238b1d9ecc2b8511311cedaab7fd9ecada81656/mocpy-0.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:5ad378728535dc34b4655adbb28889d8678b44e7e035ba4a825cfac29c1cf1b5", size = 1175466, upload-time = "2026-03-10T09:04:43.576Z" }, + { url = "https://files.pythonhosted.org/packages/a0/9b/750d03901b25e0de72c8c2f0ec8bb38ff16aa2fa4f9b2cef7b3269526e81/mocpy-0.20.0-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:c6553f3a3a820a477ecb0ffd225dcb431759cacf08bbc1f4f10db85573f7d232", size = 2237392, upload-time = "2026-03-10T09:07:39.076Z" }, + { url = "https://files.pythonhosted.org/packages/61/46/5046d8dcf24c809bd7d4dbcf0f0cd2746a662c53974ac2832bdc90e510d8/mocpy-0.20.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:11f4f451033239ccf9f1360abc3d6951a3e7fd95c10d182c47c748638ff35a53", size = 1140208, upload-time = "2026-03-10T09:08:15.625Z" }, + { url = "https://files.pythonhosted.org/packages/fc/fb/19f6466c848feaae8a48258a1f7be1124e1a849fdaa7f13b78388a835a89/mocpy-0.20.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ca13a4585299dd50c7e6ed0bcee16eaa6b932af4f0d294b24257bbcfaa69a5", size = 1273415, upload-time = "2026-03-10T10:13:46.706Z" }, + { url = "https://files.pythonhosted.org/packages/83/36/191fdd5b9597f571685e005eeabbee5ee37acb4bf9e3f3330ad154e53e9c/mocpy-0.20.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:0d608faea44e1c379983ea6f415bfdfd7aa1cc4728ed222750a04375a525d30d", size = 1273678, upload-time = "2026-03-10T09:08:17.327Z" }, + { url = "https://files.pythonhosted.org/packages/7d/24/9e7bb10d27f9f82061c0ea78e2c302abaa39ed550c8903f12e4ebd0ba94d/mocpy-0.20.0-cp314-cp314-win_amd64.whl", hash = "sha256:0e020fb88fd7d5f0dd6ee0ec419b1a7a10c5dc47e84cf3ae15eedd44c0ee7930", size = 1175422, upload-time = "2026-03-10T09:06:16.142Z" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + +[[package]] +name = "msgpack" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/f9/c0a1c127f9049db9155afc316952ea571720dd01833ff5e4d7e8e6352dbb/msgpack-1.2.1.tar.gz", hash = "sha256:04c721c2c7448767e9e3f2520a475663d8ee0f09c31890f6d2bd70fd636a9647", size = 183960, upload-time = "2026-06-18T16:13:52.594Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/6b/e9b1cdc042c4458801d2545ed782a95f3d6ba8e270cce8745b8603c7f748/msgpack-1.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:29a3f6e9667868429d8240dfd063ea5ffdc1321c13d783aa23827a38de0dcb22", size = 82812, upload-time = "2026-06-18T16:12:45.022Z" }, + { url = "https://files.pythonhosted.org/packages/0c/3a/dd518a1bf78ed1e9ad8afe57307c079a00eafe4b3068932a27ca1ea56b4f/msgpack-1.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:aded5bdf32609dc7987a49bbbd15a8ef096193f96dd8bbeb791de729e650acf5", size = 82739, upload-time = "2026-06-18T16:12:46.025Z" }, + { url = "https://files.pythonhosted.org/packages/70/e0/7ba9e1542bf0771a27b8b37c1316e3f95ae9d748fd765284655c476ad4ef/msgpack-1.2.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:146ee4e9ce80b365c6d4c47073da9da7bcec473e58194ceee5dd7620ace77e06", size = 414233, upload-time = "2026-06-18T16:12:47.029Z" }, + { url = "https://files.pythonhosted.org/packages/03/8d/671d81534ea0e2b0e8a121be100020da09eb78861fe3aa8f3ef7dcd3bed1/msgpack-1.2.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a28d076ca7c82b9c8728ad90b7147489449557038bed50e4241eb832395169b4", size = 423843, upload-time = "2026-06-18T16:12:48.19Z" }, + { url = "https://files.pythonhosted.org/packages/d2/b6/e5c737515ed1f166664b87601b532f58cbb73d8aa6a90b99f7c2c5037e8e/msgpack-1.2.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7d31c0ac0c640f877804c67cb2bc9f4e23dc2db97e96c2e67fa27d38283b41f8", size = 390772, upload-time = "2026-06-18T16:12:49.624Z" }, + { url = "https://files.pythonhosted.org/packages/a8/46/62ed8c2e87d7021eab19921594d961ef3aa3794eec76c716dc30f3bfd433/msgpack-1.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8ff92d7feeaf5bc26c51495b69e2f99ed97ab79346fb6555f44be7dd2ac6503b", size = 409559, upload-time = "2026-06-18T16:12:50.936Z" }, + { url = "https://files.pythonhosted.org/packages/70/ff/59aa3887b860bbf43532835e192b1c388a17590d6068ae4f8b2bc74c906e/msgpack-1.2.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:779197a6513bab3c3632265e3d0f7cb3227e62510841a6f34f1eaa37efbb345e", size = 387838, upload-time = "2026-06-18T16:12:52.161Z" }, + { url = "https://files.pythonhosted.org/packages/09/11/f8563e471093420cf6478cb3271a0175d8402b82d879783d4035d2d03360/msgpack-1.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:67f6dd22fa72a93752643f07889796d62739a13415ee630169a8ce764f86cf9f", size = 421732, upload-time = "2026-06-18T16:12:53.556Z" }, + { url = "https://files.pythonhosted.org/packages/57/cf/e673683c4c6c90c1022b24c65af4b03eda72b182a1176ef6449069d66acc/msgpack-1.2.1-cp311-cp311-win32.whl", hash = "sha256:91054a783328e0ea7954b8771095705c8d2243b814743fbaadf14552c9c52c5d", size = 64091, upload-time = "2026-06-18T16:12:54.821Z" }, + { url = "https://files.pythonhosted.org/packages/3f/07/ca212739d179f9083bff2c7c08c24101c3555a334fadc2b876b18768a3ae/msgpack-1.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2eda0b7ebb1283a98d3e4492ac933c8af6aff59fd3df1c3ed024f536af4b1dc8", size = 70462, upload-time = "2026-06-18T16:12:55.898Z" }, + { url = "https://files.pythonhosted.org/packages/6d/be/6798347b425e26f35db82e69dd83c09716c856a3714e7bffc4c0860fd830/msgpack-1.2.1-cp311-cp311-win_arm64.whl", hash = "sha256:6ee967f7c7e1df2890c671ff2ee51a28ded0efc95da3e507176dee881ce36c66", size = 65059, upload-time = "2026-06-18T16:12:57.053Z" }, + { url = "https://files.pythonhosted.org/packages/bc/dd/9e8cbd8f5582ca4b590336f2b91ee5662f6a6ca562b565abaf696a0f81ff/msgpack-1.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2ef59c659f289eddf8aa6623823f19fa2f40a4029266889eac7a2505dd210c35", size = 83531, upload-time = "2026-06-18T16:12:58.249Z" }, + { url = "https://files.pythonhosted.org/packages/50/2e/ebdb85a8da151397a2790363676b7ed7c125924fe618e4c6d8befb0cc62c/msgpack-1.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d3567748a5107cb40cdf66a275430c2f87c07777698f4bfd25c35f44d533258c", size = 82657, upload-time = "2026-06-18T16:12:59.396Z" }, + { url = "https://files.pythonhosted.org/packages/26/aa/753ad8b007b464e1d8aa0c8e650b9c5f4f725e658fc5ac8a7635c55b7f6e/msgpack-1.2.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60926b75d00c8e816ef98f3034f484a8bc64242d66839cef4cf7e503142316a0", size = 410634, upload-time = "2026-06-18T16:13:00.383Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/6adabd4f6d5e686f97dd02ce7fce3fe4cf672cbac36b8f67ff4040e8ad8b/msgpack-1.2.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:020e881a764b20d8d7ca1a54fc01b8175519d108e3c3f194fddc200bda95951a", size = 419989, upload-time = "2026-06-18T16:13:01.776Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cc/85039b7b0eb168aaad7383a23c97e291a11f08351cb45a606ce865e4e3f1/msgpack-1.2.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4202c74688ca06591f78cb18988228bd4cca2cc75d57b60008372892d2f1e6e6", size = 377544, upload-time = "2026-06-18T16:13:03.637Z" }, + { url = "https://files.pythonhosted.org/packages/ed/bf/35963899493b32030c85fc513b723ae66144ac70c11ebc52e889e16e3d99/msgpack-1.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8b267ce94efb76fbd1b3373511420074ee3187f0f7811bf394531de13294735a", size = 400842, upload-time = "2026-06-18T16:13:05.012Z" }, + { url = "https://files.pythonhosted.org/packages/a6/df/8e2ac970c8f99264cd9997d1c73df5466bc19da3301d7dc5500862a9b089/msgpack-1.2.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f1d0f8f98ade9634e01fb704a408f9336c0a8f1117b369f5db83dc7551d8b1", size = 374108, upload-time = "2026-06-18T16:13:06.232Z" }, + { url = "https://files.pythonhosted.org/packages/17/dd/fa8bd265110dfa51c20cb529f9e6d240a16fafe7e645004c6af2d01353ba/msgpack-1.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f02cf17a6ca1abe29b5f980644f7551f94d71f2011509b26d8625ce038f0df64", size = 414939, upload-time = "2026-06-18T16:13:07.478Z" }, + { url = "https://files.pythonhosted.org/packages/2e/b9/8377a5ad8953fc0437c70cc98d9ae29f27fe5ac5109fbec0812085865735/msgpack-1.2.1-cp312-cp312-win32.whl", hash = "sha256:0c0d9802354507bcba62af19c17918e3eb437cc25e6f50657d511b5856a77aac", size = 64504, upload-time = "2026-06-18T16:13:08.822Z" }, + { url = "https://files.pythonhosted.org/packages/57/7f/ce1e377df7e62461fefd9eb23bfb93a4a523f40a517b377b8f844d836828/msgpack-1.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:5c24aa15d5963051e1a5c62b12c50cd705992502b5ec1f3bece6046f33c9fc24", size = 71421, upload-time = "2026-06-18T16:13:09.828Z" }, + { url = "https://files.pythonhosted.org/packages/8f/32/ebfe84c9929f08f188d56c7a2fd913406a9ddad76a634697c1c43b8112e6/msgpack-1.2.1-cp312-cp312-win_arm64.whl", hash = "sha256:4227224aaec8f7fbcbfbd4272319347b2bb4030366502600f8c45588c5187b07", size = 64775, upload-time = "2026-06-18T16:13:11.056Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ac/dcddcab6f6c20ecb387ca5e980371cdb3f87ff69aeca388be97eebc4c074/msgpack-1.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0a70e3cf2804a300d921bb0940426e35f4e489a23adfb77a808892241db0a064", size = 83151, upload-time = "2026-06-18T16:13:12.173Z" }, + { url = "https://files.pythonhosted.org/packages/64/71/fbcfa83a1d6a9c6091942d1cfd070962244664b87427a9a49a6897b1b219/msgpack-1.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:491cc39455ca765fad51fb451bf2915eb2cf41192ab5801ce8d67c1d614fe056", size = 82351, upload-time = "2026-06-18T16:13:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/e3/10/ddf7b06db879e8792d13934ddda09ff20bd2a583fd84c9b59aae9b0e650b/msgpack-1.2.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f310233ef7fb9c14e201c93639fe5f5260b005f56f0b29048e999c30935596cc", size = 407518, upload-time = "2026-06-18T16:13:14.233Z" }, + { url = "https://files.pythonhosted.org/packages/79/d3/36a46a8ed992b781acbc05928bd5bee3c810cb0c3563bf81a7b0c04a1a76/msgpack-1.2.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:787c9bebb5833e8f6fc8abca3c0597683d8d87f56a8842b6b89c75a5f3176e2d", size = 416405, upload-time = "2026-06-18T16:13:15.435Z" }, + { url = "https://files.pythonhosted.org/packages/f9/84/e8e9598b557c0ba6ddae901a73780a4c75ac667dddf59414b1e56a42fb34/msgpack-1.2.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dc871b997a9370d855b7394465f2f350e847a5b806dd38dcc9c989e7d87da155", size = 376257, upload-time = "2026-06-18T16:13:17.022Z" }, + { url = "https://files.pythonhosted.org/packages/40/16/738fe6d875ad7e2a9429c165322a4ec088f4f273cdfae63d96a89c467961/msgpack-1.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:85f57e960d877f2977f6430896191b04a21f8901b3b4baf2e4604329f4db5402", size = 397469, upload-time = "2026-06-18T16:13:18.287Z" }, + { url = "https://files.pythonhosted.org/packages/ca/be/6d5952df75a7f24f35833af764c3a6860780364cb3a0030beb8099e1b2b4/msgpack-1.2.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:1233ee2dd0cefba127583de50ea654677277047d238303521db35def3d7b2e7c", size = 372802, upload-time = "2026-06-18T16:13:19.685Z" }, + { url = "https://files.pythonhosted.org/packages/e1/39/e2ef7dbf0473bcb8dc7c50bf782a892d67414877b63e47fc88eb189ef5e6/msgpack-1.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e3dc2feb0876209d9c38aa56cb1de169bd6c4348f1aa48271f241226590993e6", size = 411273, upload-time = "2026-06-18T16:13:21.028Z" }, + { url = "https://files.pythonhosted.org/packages/ef/c5/133f4512a56e983a93445c836c9d94d88f3bc2e0980ff4b9e577bd8416ce/msgpack-1.2.1-cp313-cp313-win32.whl", hash = "sha256:6d09badf350af2be9d189184e04e64cf54ad93569ab3d96fca58bd3e84aad707", size = 64471, upload-time = "2026-06-18T16:13:22.293Z" }, + { url = "https://files.pythonhosted.org/packages/e2/98/577e10b055096a7dd40732358cabaf7180a20c79ed1dcdbb618e4b9deac7/msgpack-1.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:33f14fba63278b714efe6ad07e50ea5f03d91537aa6a1c5f1ceca4cf44013ca9", size = 71274, upload-time = "2026-06-18T16:13:23.455Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ee/0c0048e7cfbef23c6a94791b8959ab28155232e7956de8a305b5ff588f05/msgpack-1.2.1-cp313-cp313-win_arm64.whl", hash = "sha256:afc5febcd4c99effbc02b528e49d6fd0760b2b7d48c05239e345a5fa6e743d9a", size = 64795, upload-time = "2026-06-18T16:13:24.687Z" }, + { url = "https://files.pythonhosted.org/packages/77/58/cce442852c6b9e1639c7c8ac8fd9143121cb32dab0f308df4d1426a8eb9c/msgpack-1.2.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:05f340e47e7e47d2da8db9b53e1bb1d294369e9ef45a747441309f6650b8351d", size = 83610, upload-time = "2026-06-18T16:13:25.724Z" }, + { url = "https://files.pythonhosted.org/packages/60/5c/15b4c7a0182f75ffa90751958ba36a9c01cafee367d49a3edc10ed140b01/msgpack-1.2.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:810b916696c86ef0deb3b74588480224df4c1b071136c34183e4a2a4284d7ac7", size = 83138, upload-time = "2026-06-18T16:13:26.781Z" }, + { url = "https://files.pythonhosted.org/packages/b8/a6/99e58722feaffc5f2fbcc0c8c0d1451ab9f84097f7af87291b46af2390f4/msgpack-1.2.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ca0dacff965c47afdc3749a8469d7302a8f801d6a28758d55120d75e66ce6889", size = 406090, upload-time = "2026-06-18T16:13:28.072Z" }, + { url = "https://files.pythonhosted.org/packages/19/03/8c63e8cf52958534ef688625965ab04c269a6cadd8caef16758b380a821a/msgpack-1.2.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e2bf9280bceb5efca998435904b5d3e9fdbcc11d90dc9df30aec7973252b720", size = 412106, upload-time = "2026-06-18T16:13:29.427Z" }, + { url = "https://files.pythonhosted.org/packages/63/d2/155d9e71b40e41fd934bc0c48b9b2770f22263e1ac20aad8e29fdca7be3f/msgpack-1.2.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aa6c4be5d1c02a42b066ca6ddb71adf36432868fdcdb6ee87e634e86e0674190", size = 374851, upload-time = "2026-06-18T16:13:30.631Z" }, + { url = "https://files.pythonhosted.org/packages/98/48/deaf2326262a8d5ea3295ce9649912ecd3f551ba7ec8e33c665d2ba583f3/msgpack-1.2.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec0e675d59150a6269ddc9139087c722292664a37d071a849c05c473350f1f2d", size = 396168, upload-time = "2026-06-18T16:13:31.977Z" }, + { url = "https://files.pythonhosted.org/packages/10/2a/b4410f906c2ec0008f1608d3ab5143afc3ad3f4e6da0fed3ea2231d0bef4/msgpack-1.2.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:dd3bfe82d53edfe4b7fc9a7ec9761e23a7a5b1dac22264505af428253c29ed24", size = 371959, upload-time = "2026-06-18T16:13:33.282Z" }, + { url = "https://files.pythonhosted.org/packages/59/86/1edc67270099a528fa2093ea60fe191233cd238e4bd30cfacf7db79fc959/msgpack-1.2.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5ad5467fc3f68b5468e06c5f788d712e9f8ffc8b0cd1bcb160c105c1ee92dae7", size = 408457, upload-time = "2026-06-18T16:13:34.567Z" }, + { url = "https://files.pythonhosted.org/packages/82/90/8b630fef07d8c5ab457b71ff2c217910c83d333c7a68472c186e87cc504a/msgpack-1.2.1-cp314-cp314-win32.whl", hash = "sha256:98b58bdb89c46190e4609bb36abe17c6d4105ad13f9c5f8f6f64d320f8ced3fb", size = 65942, upload-time = "2026-06-18T16:13:36.056Z" }, + { url = "https://files.pythonhosted.org/packages/16/f1/467b81e98b24dd3885d7b1857728797b4ffc76a7a7483af4fb321a07de3c/msgpack-1.2.1-cp314-cp314-win_amd64.whl", hash = "sha256:74847557e28ce71bd3c438a447ca90e4b507e997ddbdef8a12a7b283b86c156b", size = 72627, upload-time = "2026-06-18T16:13:37.079Z" }, + { url = "https://files.pythonhosted.org/packages/a7/1d/5d8c4c89985feb6acefb82a09e501c60392261856d2408d20bfe4f0360b1/msgpack-1.2.1-cp314-cp314-win_arm64.whl", hash = "sha256:b50b727bd652bdc37d950336c848ef20ec54a4cafc38dce19b1cd86ad625d0f7", size = 66908, upload-time = "2026-06-18T16:13:38.23Z" }, + { url = "https://files.pythonhosted.org/packages/1b/02/ad2afb678b4de94496cd432b581759b756a92c1192d8c767edd6b132efdc/msgpack-1.2.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8d00f177ca88a77c1cf848d204a38f249751650b601cb6532acc68805d8a8273", size = 86000, upload-time = "2026-06-18T16:13:39.44Z" }, + { url = "https://files.pythonhosted.org/packages/54/74/0b797484013128837f3b1cbb6cea019277c4de4e377dc512b4d9a0f92940/msgpack-1.2.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5bb9c386f0a329c035ddbab4b72d1028bf9627add8dda41070288563d57ed1b1", size = 86544, upload-time = "2026-06-18T16:13:40.447Z" }, + { url = "https://files.pythonhosted.org/packages/a9/b4/b774d7eb95561739907fec675582f83203cf41c597a418c2589b4bfb8e9d/msgpack-1.2.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20466cca18c49c7292a8984bc15d65857b171e7264bdcb5f96baf8be238791fc", size = 427661, upload-time = "2026-06-18T16:13:41.574Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f9/3243191dc9937e00756c8bc1b0272fed8f23758e43df2a3b46f533e5090f/msgpack-1.2.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:196300e7e5d6e74d50f1607ab9c06c4a1484c383cd22defd727902591f7e8dde", size = 426375, upload-time = "2026-06-18T16:13:42.936Z" }, + { url = "https://files.pythonhosted.org/packages/23/c7/1693111db9944ba4ad4b67a1e788400d78a0b6af7a6523dc7e4e58f8274b/msgpack-1.2.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575957e79cd51903a4e8495a242442949641e08f1efd5197b43bebd3ea7682b4", size = 380495, upload-time = "2026-06-18T16:13:44.306Z" }, + { url = "https://files.pythonhosted.org/packages/3e/2b/92f86956a0c13e8662f7e2ad630c4eb4db07497b967589bd5245e018b2c1/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8c2ed1e48cc0f460bf3c7780e7137ff21a4e18433451916f2442c1b21036cd7d", size = 410897, upload-time = "2026-06-18T16:13:45.629Z" }, + { url = "https://files.pythonhosted.org/packages/da/ea/1479f72d200313a76fc2f823a79d1e07ed052ab7b8a0280640aa7b95de42/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5f6277e5f783c36786a145e0247fc189a03f35f84b251646e53592d2bc12b355", size = 378519, upload-time = "2026-06-18T16:13:46.998Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/fa006060ffa1011d32bfae826fe766fe73e02982183601633b7121058ab3/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f9389552ecf4784886345ead0647e4edc96bee37cbab05b75540f542f766c48c", size = 419815, upload-time = "2026-06-18T16:13:48.205Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/aab6c946570496b78e67804721f3d5e2d62a93081b9b37df77764ef56347/msgpack-1.2.1-cp314-cp314t-win32.whl", hash = "sha256:c1c79a604a2969a868a78b6ebd27a887e00c624f14f66b3038e0590cb23332d1", size = 70914, upload-time = "2026-06-18T16:13:49.385Z" }, + { url = "https://files.pythonhosted.org/packages/13/0a/e608956488a2af014cfe6e3d665e090b8ee42aa14b07f8f95b8880d66b09/msgpack-1.2.1-cp314-cp314t-win_amd64.whl", hash = "sha256:f12038a35fabd52e56a3547bab42401af49a45caa6dd00b34c44de235bc93ee2", size = 77999, upload-time = "2026-06-18T16:13:50.467Z" }, + { url = "https://files.pythonhosted.org/packages/d2/8a/27e2e57055176e366a46b85d02d68e7a5bcfbdd8474c9706375d965f24d3/msgpack-1.2.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0adcf06ffde0777c0e1a9b771a2b1c4226ba1bbf748c8efcc02fcdeca3299107", size = 71160, upload-time = "2026-06-18T16:13:51.498Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/c2/c2d94cbe6ac1753f3fc980da97b3d930efe1da3af3c9f5125354436c073d/multidict-6.7.1.tar.gz", hash = "sha256:ec6652a1bee61c53a3e5776b6049172c53b6aaba34f18c9ad04f82712bac623d", size = 102010, upload-time = "2026-01-26T02:46:45.979Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/f1/a90635c4f88fb913fbf4ce660b83b7445b7a02615bda034b2f8eb38fd597/multidict-6.7.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7ff981b266af91d7b4b3793ca3382e53229088d193a85dfad6f5f4c27fc73e5d", size = 76626, upload-time = "2026-01-26T02:43:26.485Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9b/267e64eaf6fc637a15b35f5de31a566634a2740f97d8d094a69d34f524a4/multidict-6.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:844c5bca0b5444adb44a623fb0a1310c2f4cd41f402126bb269cd44c9b3f3e1e", size = 44706, upload-time = "2026-01-26T02:43:27.607Z" }, + { url = "https://files.pythonhosted.org/packages/dd/a4/d45caf2b97b035c57267791ecfaafbd59c68212004b3842830954bb4b02e/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f2a0a924d4c2e9afcd7ec64f9de35fcd96915149b2216e1cb2c10a56df483855", size = 44356, upload-time = "2026-01-26T02:43:28.661Z" }, + { url = "https://files.pythonhosted.org/packages/fd/d2/0a36c8473f0cbaeadd5db6c8b72d15bbceeec275807772bfcd059bef487d/multidict-6.7.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8be1802715a8e892c784c0197c2ace276ea52702a0ede98b6310c8f255a5afb3", size = 244355, upload-time = "2026-01-26T02:43:31.165Z" }, + { url = "https://files.pythonhosted.org/packages/5d/16/8c65be997fd7dd311b7d39c7b6e71a0cb449bad093761481eccbbe4b42a2/multidict-6.7.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e2d2ed645ea29f31c4c7ea1552fcfd7cb7ba656e1eafd4134a6620c9f5fdd9e", size = 246433, upload-time = "2026-01-26T02:43:32.581Z" }, + { url = "https://files.pythonhosted.org/packages/01/fb/4dbd7e848d2799c6a026ec88ad39cf2b8416aa167fcc903baa55ecaa045c/multidict-6.7.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:95922cee9a778659e91db6497596435777bd25ed116701a4c034f8e46544955a", size = 225376, upload-time = "2026-01-26T02:43:34.417Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8a/4a3a6341eac3830f6053062f8fbc9a9e54407c80755b3f05bc427295c2d0/multidict-6.7.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6b83cabdc375ffaaa15edd97eb7c0c672ad788e2687004990074d7d6c9b140c8", size = 257365, upload-time = "2026-01-26T02:43:35.741Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a2/dd575a69c1aa206e12d27d0770cdf9b92434b48a9ef0cd0d1afdecaa93c4/multidict-6.7.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:38fb49540705369bab8484db0689d86c0a33a0a9f2c1b197f506b71b4b6c19b0", size = 254747, upload-time = "2026-01-26T02:43:36.976Z" }, + { url = "https://files.pythonhosted.org/packages/5a/56/21b27c560c13822ed93133f08aa6372c53a8e067f11fbed37b4adcdac922/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:439cbebd499f92e9aa6793016a8acaa161dfa749ae86d20960189f5398a19144", size = 246293, upload-time = "2026-01-26T02:43:38.258Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a4/23466059dc3854763423d0ad6c0f3683a379d97673b1b89ec33826e46728/multidict-6.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6d3bc717b6fe763b8be3f2bee2701d3c8eb1b2a8ae9f60910f1b2860c82b6c49", size = 242962, upload-time = "2026-01-26T02:43:40.034Z" }, + { url = "https://files.pythonhosted.org/packages/1f/67/51dd754a3524d685958001e8fa20a0f5f90a6a856e0a9dcabff69be3dbb7/multidict-6.7.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:619e5a1ac57986dbfec9f0b301d865dddf763696435e2962f6d9cf2fdff2bb71", size = 237360, upload-time = "2026-01-26T02:43:41.752Z" }, + { url = "https://files.pythonhosted.org/packages/64/3f/036dfc8c174934d4b55d86ff4f978e558b0e585cef70cfc1ad01adc6bf18/multidict-6.7.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0b38ebffd9be37c1170d33bc0f36f4f262e0a09bc1aac1c34c7aa51a7293f0b3", size = 245940, upload-time = "2026-01-26T02:43:43.042Z" }, + { url = "https://files.pythonhosted.org/packages/3d/20/6214d3c105928ebc353a1c644a6ef1408bc5794fcb4f170bb524a3c16311/multidict-6.7.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:10ae39c9cfe6adedcdb764f5e8411d4a92b055e35573a2eaa88d3323289ef93c", size = 253502, upload-time = "2026-01-26T02:43:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/b1/e2/c653bc4ae1be70a0f836b82172d643fcf1dade042ba2676ab08ec08bff0f/multidict-6.7.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:25167cc263257660290fba06b9318d2026e3c910be240a146e1f66dd114af2b0", size = 247065, upload-time = "2026-01-26T02:43:45.745Z" }, + { url = "https://files.pythonhosted.org/packages/c8/11/a854b4154cd3bd8b1fd375e8a8ca9d73be37610c361543d56f764109509b/multidict-6.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:128441d052254f42989ef98b7b6a6ecb1e6f708aa962c7984235316db59f50fa", size = 241870, upload-time = "2026-01-26T02:43:47.054Z" }, + { url = "https://files.pythonhosted.org/packages/13/bf/9676c0392309b5fdae322333d22a829715b570edb9baa8016a517b55b558/multidict-6.7.1-cp311-cp311-win32.whl", hash = "sha256:d62b7f64ffde3b99d06b707a280db04fb3855b55f5a06df387236051d0668f4a", size = 41302, upload-time = "2026-01-26T02:43:48.753Z" }, + { url = "https://files.pythonhosted.org/packages/c9/68/f16a3a8ba6f7b6dc92a1f19669c0810bd2c43fc5a02da13b1cbf8e253845/multidict-6.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:bdbf9f3b332abd0cdb306e7c2113818ab1e922dc84b8f8fd06ec89ed2a19ab8b", size = 45981, upload-time = "2026-01-26T02:43:49.921Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ad/9dd5305253fa00cd3c7555dbef69d5bf4133debc53b87ab8d6a44d411665/multidict-6.7.1-cp311-cp311-win_arm64.whl", hash = "sha256:b8c990b037d2fff2f4e33d3f21b9b531c5745b33a49a7d6dbe7a177266af44f6", size = 43159, upload-time = "2026-01-26T02:43:51.635Z" }, + { url = "https://files.pythonhosted.org/packages/8d/9c/f20e0e2cf80e4b2e4b1c365bf5fe104ee633c751a724246262db8f1a0b13/multidict-6.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a90f75c956e32891a4eda3639ce6dd86e87105271f43d43442a3aedf3cddf172", size = 76893, upload-time = "2026-01-26T02:43:52.754Z" }, + { url = "https://files.pythonhosted.org/packages/fe/cf/18ef143a81610136d3da8193da9d80bfe1cb548a1e2d1c775f26b23d024a/multidict-6.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fccb473e87eaa1382689053e4a4618e7ba7b9b9b8d6adf2027ee474597128cd", size = 45456, upload-time = "2026-01-26T02:43:53.893Z" }, + { url = "https://files.pythonhosted.org/packages/a9/65/1caac9d4cd32e8433908683446eebc953e82d22b03d10d41a5f0fefe991b/multidict-6.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0fa96985700739c4c7853a43c0b3e169360d6855780021bfc6d0f1ce7c123e7", size = 43872, upload-time = "2026-01-26T02:43:55.041Z" }, + { url = "https://files.pythonhosted.org/packages/cf/3b/d6bd75dc4f3ff7c73766e04e705b00ed6dbbaccf670d9e05a12b006f5a21/multidict-6.7.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cb2a55f408c3043e42b40cc8eecd575afa27b7e0b956dfb190de0f8499a57a53", size = 251018, upload-time = "2026-01-26T02:43:56.198Z" }, + { url = "https://files.pythonhosted.org/packages/fd/80/c959c5933adedb9ac15152e4067c702a808ea183a8b64cf8f31af8ad3155/multidict-6.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb0ce7b2a32d09892b3dd6cc44877a0d02a33241fafca5f25c8b6b62374f8b75", size = 258883, upload-time = "2026-01-26T02:43:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/86/85/7ed40adafea3d4f1c8b916e3b5cc3a8e07dfcdcb9cd72800f4ed3ca1b387/multidict-6.7.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c3a32d23520ee37bf327d1e1a656fec76a2edd5c038bf43eddfa0572ec49c60b", size = 242413, upload-time = "2026-01-26T02:43:58.755Z" }, + { url = "https://files.pythonhosted.org/packages/d2/57/b8565ff533e48595503c785f8361ff9a4fde4d67de25c207cd0ba3befd03/multidict-6.7.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9c90fed18bffc0189ba814749fdcc102b536e83a9f738a9003e569acd540a733", size = 268404, upload-time = "2026-01-26T02:44:00.216Z" }, + { url = "https://files.pythonhosted.org/packages/e0/50/9810c5c29350f7258180dfdcb2e52783a0632862eb334c4896ac717cebcb/multidict-6.7.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:da62917e6076f512daccfbbde27f46fed1c98fee202f0559adec8ee0de67f71a", size = 269456, upload-time = "2026-01-26T02:44:02.202Z" }, + { url = "https://files.pythonhosted.org/packages/f3/8d/5e5be3ced1d12966fefb5c4ea3b2a5b480afcea36406559442c6e31d4a48/multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bfde23ef6ed9db7eaee6c37dcec08524cb43903c60b285b172b6c094711b3961", size = 256322, upload-time = "2026-01-26T02:44:03.56Z" }, + { url = "https://files.pythonhosted.org/packages/31/6e/d8a26d81ac166a5592782d208dd90dfdc0a7a218adaa52b45a672b46c122/multidict-6.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3758692429e4e32f1ba0df23219cd0b4fc0a52f476726fff9337d1a57676a582", size = 253955, upload-time = "2026-01-26T02:44:04.845Z" }, + { url = "https://files.pythonhosted.org/packages/59/4c/7c672c8aad41534ba619bcd4ade7a0dc87ed6b8b5c06149b85d3dd03f0cd/multidict-6.7.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:398c1478926eca669f2fd6a5856b6de9c0acf23a2cb59a14c0ba5844fa38077e", size = 251254, upload-time = "2026-01-26T02:44:06.133Z" }, + { url = "https://files.pythonhosted.org/packages/7b/bd/84c24de512cbafbdbc39439f74e967f19570ce7924e3007174a29c348916/multidict-6.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c102791b1c4f3ab36ce4101154549105a53dc828f016356b3e3bcae2e3a039d3", size = 252059, upload-time = "2026-01-26T02:44:07.518Z" }, + { url = "https://files.pythonhosted.org/packages/fa/ba/f5449385510825b73d01c2d4087bf6d2fccc20a2d42ac34df93191d3dd03/multidict-6.7.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a088b62bd733e2ad12c50dad01b7d0166c30287c166e137433d3b410add807a6", size = 263588, upload-time = "2026-01-26T02:44:09.382Z" }, + { url = "https://files.pythonhosted.org/packages/d7/11/afc7c677f68f75c84a69fe37184f0f82fce13ce4b92f49f3db280b7e92b3/multidict-6.7.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3d51ff4785d58d3f6c91bdbffcb5e1f7ddfda557727043aa20d20ec4f65e324a", size = 259642, upload-time = "2026-01-26T02:44:10.73Z" }, + { url = "https://files.pythonhosted.org/packages/2b/17/ebb9644da78c4ab36403739e0e6e0e30ebb135b9caf3440825001a0bddcb/multidict-6.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc5907494fccf3e7d3f94f95c91d6336b092b5fc83811720fae5e2765890dfba", size = 251377, upload-time = "2026-01-26T02:44:12.042Z" }, + { url = "https://files.pythonhosted.org/packages/ca/a4/840f5b97339e27846c46307f2530a2805d9d537d8b8bd416af031cad7fa0/multidict-6.7.1-cp312-cp312-win32.whl", hash = "sha256:28ca5ce2fd9716631133d0e9a9b9a745ad7f60bac2bccafb56aa380fc0b6c511", size = 41887, upload-time = "2026-01-26T02:44:14.245Z" }, + { url = "https://files.pythonhosted.org/packages/80/31/0b2517913687895f5904325c2069d6a3b78f66cc641a86a2baf75a05dcbb/multidict-6.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcee94dfbd638784645b066074b338bc9cc155d4b4bffa4adce1615c5a426c19", size = 46053, upload-time = "2026-01-26T02:44:15.371Z" }, + { url = "https://files.pythonhosted.org/packages/0c/5b/aba28e4ee4006ae4c7df8d327d31025d760ffa992ea23812a601d226e682/multidict-6.7.1-cp312-cp312-win_arm64.whl", hash = "sha256:ba0a9fb644d0c1a2194cf7ffb043bd852cea63a57f66fbd33959f7dae18517bf", size = 43307, upload-time = "2026-01-26T02:44:16.852Z" }, + { url = "https://files.pythonhosted.org/packages/f2/22/929c141d6c0dba87d3e1d38fbdf1ba8baba86b7776469f2bc2d3227a1e67/multidict-6.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2b41f5fed0ed563624f1c17630cb9941cf2309d4df00e494b551b5f3e3d67a23", size = 76174, upload-time = "2026-01-26T02:44:18.509Z" }, + { url = "https://files.pythonhosted.org/packages/c7/75/bc704ae15fee974f8fccd871305e254754167dce5f9e42d88a2def741a1d/multidict-6.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84e61e3af5463c19b67ced91f6c634effb89ef8bfc5ca0267f954451ed4bb6a2", size = 45116, upload-time = "2026-01-26T02:44:19.745Z" }, + { url = "https://files.pythonhosted.org/packages/79/76/55cd7186f498ed080a18440c9013011eb548f77ae1b297206d030eb1180a/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:935434b9853c7c112eee7ac891bc4cb86455aa631269ae35442cb316790c1445", size = 43524, upload-time = "2026-01-26T02:44:21.571Z" }, + { url = "https://files.pythonhosted.org/packages/e9/3c/414842ef8d5a1628d68edee29ba0e5bcf235dbfb3ccd3ea303a7fe8c72ff/multidict-6.7.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:432feb25a1cb67fe82a9680b4d65fb542e4635cb3166cd9c01560651ad60f177", size = 249368, upload-time = "2026-01-26T02:44:22.803Z" }, + { url = "https://files.pythonhosted.org/packages/f6/32/befed7f74c458b4a525e60519fe8d87eef72bb1e99924fa2b0f9d97a221e/multidict-6.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e82d14e3c948952a1a85503817e038cba5905a3352de76b9a465075d072fba23", size = 256952, upload-time = "2026-01-26T02:44:24.306Z" }, + { url = "https://files.pythonhosted.org/packages/03/d6/c878a44ba877f366630c860fdf74bfb203c33778f12b6ac274936853c451/multidict-6.7.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4cfb48c6ea66c83bcaaf7e4dfa7ec1b6bbcf751b7db85a328902796dfde4c060", size = 240317, upload-time = "2026-01-26T02:44:25.772Z" }, + { url = "https://files.pythonhosted.org/packages/68/49/57421b4d7ad2e9e60e25922b08ceb37e077b90444bde6ead629095327a6f/multidict-6.7.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1d540e51b7e8e170174555edecddbd5538105443754539193e3e1061864d444d", size = 267132, upload-time = "2026-01-26T02:44:27.648Z" }, + { url = "https://files.pythonhosted.org/packages/b7/fe/ec0edd52ddbcea2a2e89e174f0206444a61440b40f39704e64dc807a70bd/multidict-6.7.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:273d23f4b40f3dce4d6c8a821c741a86dec62cded82e1175ba3d99be128147ed", size = 268140, upload-time = "2026-01-26T02:44:29.588Z" }, + { url = "https://files.pythonhosted.org/packages/b0/73/6e1b01cbeb458807aa0831742232dbdd1fa92bfa33f52a3f176b4ff3dc11/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d624335fd4fa1c08a53f8b4be7676ebde19cd092b3895c421045ca87895b429", size = 254277, upload-time = "2026-01-26T02:44:30.902Z" }, + { url = "https://files.pythonhosted.org/packages/6a/b2/5fb8c124d7561a4974c342bc8c778b471ebbeb3cc17df696f034a7e9afe7/multidict-6.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:12fad252f8b267cc75b66e8fc51b3079604e8d43a75428ffe193cd9e2195dfd6", size = 252291, upload-time = "2026-01-26T02:44:32.31Z" }, + { url = "https://files.pythonhosted.org/packages/5a/96/51d4e4e06bcce92577fcd488e22600bd38e4fd59c20cb49434d054903bd2/multidict-6.7.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:03ede2a6ffbe8ef936b92cb4529f27f42be7f56afcdab5ab739cd5f27fb1cbf9", size = 250156, upload-time = "2026-01-26T02:44:33.734Z" }, + { url = "https://files.pythonhosted.org/packages/db/6b/420e173eec5fba721a50e2a9f89eda89d9c98fded1124f8d5c675f7a0c0f/multidict-6.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:90efbcf47dbe33dcf643a1e400d67d59abeac5db07dc3f27d6bdeae497a2198c", size = 249742, upload-time = "2026-01-26T02:44:35.222Z" }, + { url = "https://files.pythonhosted.org/packages/44/a3/ec5b5bd98f306bc2aa297b8c6f11a46714a56b1e6ef5ebda50a4f5d7c5fb/multidict-6.7.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c4b9bfc148f5a91be9244d6264c53035c8a0dcd2f51f1c3c6e30e30ebaa1c84", size = 262221, upload-time = "2026-01-26T02:44:36.604Z" }, + { url = "https://files.pythonhosted.org/packages/cd/f7/e8c0d0da0cd1e28d10e624604e1a36bcc3353aaebdfdc3a43c72bc683a12/multidict-6.7.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:401c5a650f3add2472d1d288c26deebc540f99e2fb83e9525007a74cd2116f1d", size = 258664, upload-time = "2026-01-26T02:44:38.008Z" }, + { url = "https://files.pythonhosted.org/packages/52/da/151a44e8016dd33feed44f730bd856a66257c1ee7aed4f44b649fb7edeb3/multidict-6.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:97891f3b1b3ffbded884e2916cacf3c6fc87b66bb0dde46f7357404750559f33", size = 249490, upload-time = "2026-01-26T02:44:39.386Z" }, + { url = "https://files.pythonhosted.org/packages/87/af/a3b86bf9630b732897f6fc3f4c4714b90aa4361983ccbdcd6c0339b21b0c/multidict-6.7.1-cp313-cp313-win32.whl", hash = "sha256:e1c5988359516095535c4301af38d8a8838534158f649c05dd1050222321bcb3", size = 41695, upload-time = "2026-01-26T02:44:41.318Z" }, + { url = "https://files.pythonhosted.org/packages/b2/35/e994121b0e90e46134673422dd564623f93304614f5d11886b1b3e06f503/multidict-6.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:960c83bf01a95b12b08fd54324a4eb1d5b52c88932b5cba5d6e712bb3ed12eb5", size = 45884, upload-time = "2026-01-26T02:44:42.488Z" }, + { url = "https://files.pythonhosted.org/packages/ca/61/42d3e5dbf661242a69c97ea363f2d7b46c567da8eadef8890022be6e2ab0/multidict-6.7.1-cp313-cp313-win_arm64.whl", hash = "sha256:563fe25c678aaba333d5399408f5ec3c383ca5b663e7f774dd179a520b8144df", size = 43122, upload-time = "2026-01-26T02:44:43.664Z" }, + { url = "https://files.pythonhosted.org/packages/6d/b3/e6b21c6c4f314bb956016b0b3ef2162590a529b84cb831c257519e7fde44/multidict-6.7.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:c76c4bec1538375dad9d452d246ca5368ad6e1c9039dadcf007ae59c70619ea1", size = 83175, upload-time = "2026-01-26T02:44:44.894Z" }, + { url = "https://files.pythonhosted.org/packages/fb/76/23ecd2abfe0957b234f6c960f4ade497f55f2c16aeb684d4ecdbf1c95791/multidict-6.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:57b46b24b5d5ebcc978da4ec23a819a9402b4228b8a90d9c656422b4bdd8a963", size = 48460, upload-time = "2026-01-26T02:44:46.106Z" }, + { url = "https://files.pythonhosted.org/packages/c4/57/a0ed92b23f3a042c36bc4227b72b97eca803f5f1801c1ab77c8a212d455e/multidict-6.7.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e954b24433c768ce78ab7929e84ccf3422e46deb45a4dc9f93438f8217fa2d34", size = 46930, upload-time = "2026-01-26T02:44:47.278Z" }, + { url = "https://files.pythonhosted.org/packages/b5/66/02ec7ace29162e447f6382c495dc95826bf931d3818799bbef11e8f7df1a/multidict-6.7.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3bd231490fa7217cc832528e1cd8752a96f0125ddd2b5749390f7c3ec8721b65", size = 242582, upload-time = "2026-01-26T02:44:48.604Z" }, + { url = "https://files.pythonhosted.org/packages/58/18/64f5a795e7677670e872673aca234162514696274597b3708b2c0d276cce/multidict-6.7.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:253282d70d67885a15c8a7716f3a73edf2d635793ceda8173b9ecc21f2fb8292", size = 250031, upload-time = "2026-01-26T02:44:50.544Z" }, + { url = "https://files.pythonhosted.org/packages/c8/ed/e192291dbbe51a8290c5686f482084d31bcd9d09af24f63358c3d42fd284/multidict-6.7.1-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b4c48648d7649c9335cf1927a8b87fa692de3dcb15faa676c6a6f1f1aabda43", size = 228596, upload-time = "2026-01-26T02:44:51.951Z" }, + { url = "https://files.pythonhosted.org/packages/1e/7e/3562a15a60cf747397e7f2180b0a11dc0c38d9175a650e75fa1b4d325e15/multidict-6.7.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:98bc624954ec4d2c7cb074b8eefc2b5d0ce7d482e410df446414355d158fe4ca", size = 257492, upload-time = "2026-01-26T02:44:53.902Z" }, + { url = "https://files.pythonhosted.org/packages/24/02/7d0f9eae92b5249bb50ac1595b295f10e263dd0078ebb55115c31e0eaccd/multidict-6.7.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1b99af4d9eec0b49927b4402bcbb58dea89d3e0db8806a4086117019939ad3dd", size = 255899, upload-time = "2026-01-26T02:44:55.316Z" }, + { url = "https://files.pythonhosted.org/packages/00/e3/9b60ed9e23e64c73a5cde95269ef1330678e9c6e34dd4eb6b431b85b5a10/multidict-6.7.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6aac4f16b472d5b7dc6f66a0d49dd57b0e0902090be16594dc9ebfd3d17c47e7", size = 247970, upload-time = "2026-01-26T02:44:56.783Z" }, + { url = "https://files.pythonhosted.org/packages/3e/06/538e58a63ed5cfb0bd4517e346b91da32fde409d839720f664e9a4ae4f9d/multidict-6.7.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:21f830fe223215dffd51f538e78c172ed7c7f60c9b96a2bf05c4848ad49921c3", size = 245060, upload-time = "2026-01-26T02:44:58.195Z" }, + { url = "https://files.pythonhosted.org/packages/b2/2f/d743a3045a97c895d401e9bd29aaa09b94f5cbdf1bd561609e5a6c431c70/multidict-6.7.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f5dd81c45b05518b9aa4da4aa74e1c93d715efa234fd3e8a179df611cc85e5f4", size = 235888, upload-time = "2026-01-26T02:44:59.57Z" }, + { url = "https://files.pythonhosted.org/packages/38/83/5a325cac191ab28b63c52f14f1131f3b0a55ba3b9aa65a6d0bf2a9b921a0/multidict-6.7.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:eb304767bca2bb92fb9c5bd33cedc95baee5bb5f6c88e63706533a1c06ad08c8", size = 243554, upload-time = "2026-01-26T02:45:01.054Z" }, + { url = "https://files.pythonhosted.org/packages/20/1f/9d2327086bd15da2725ef6aae624208e2ef828ed99892b17f60c344e57ed/multidict-6.7.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c9035dde0f916702850ef66460bc4239d89d08df4d02023a5926e7446724212c", size = 252341, upload-time = "2026-01-26T02:45:02.484Z" }, + { url = "https://files.pythonhosted.org/packages/e8/2c/2a1aa0280cf579d0f6eed8ee5211c4f1730bd7e06c636ba2ee6aafda302e/multidict-6.7.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:af959b9beeb66c822380f222f0e0a1889331597e81f1ded7f374f3ecb0fd6c52", size = 246391, upload-time = "2026-01-26T02:45:03.862Z" }, + { url = "https://files.pythonhosted.org/packages/e5/03/7ca022ffc36c5a3f6e03b179a5ceb829be9da5783e6fe395f347c0794680/multidict-6.7.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:41f2952231456154ee479651491e94118229844dd7226541788be783be2b5108", size = 243422, upload-time = "2026-01-26T02:45:05.296Z" }, + { url = "https://files.pythonhosted.org/packages/dc/1d/b31650eab6c5778aceed46ba735bd97f7c7d2f54b319fa916c0f96e7805b/multidict-6.7.1-cp313-cp313t-win32.whl", hash = "sha256:df9f19c28adcb40b6aae30bbaa1478c389efd50c28d541d76760199fc1037c32", size = 47770, upload-time = "2026-01-26T02:45:06.754Z" }, + { url = "https://files.pythonhosted.org/packages/ac/5b/2d2d1d522e51285bd61b1e20df8f47ae1a9d80839db0b24ea783b3832832/multidict-6.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d54ecf9f301853f2c5e802da559604b3e95bb7a3b01a9c295c6ee591b9882de8", size = 53109, upload-time = "2026-01-26T02:45:08.044Z" }, + { url = "https://files.pythonhosted.org/packages/3d/a3/cc409ba012c83ca024a308516703cf339bdc4b696195644a7215a5164a24/multidict-6.7.1-cp313-cp313t-win_arm64.whl", hash = "sha256:5a37ca18e360377cfda1d62f5f382ff41f2b8c4ccb329ed974cc2e1643440118", size = 45573, upload-time = "2026-01-26T02:45:09.349Z" }, + { url = "https://files.pythonhosted.org/packages/91/cc/db74228a8be41884a567e88a62fd589a913708fcf180d029898c17a9a371/multidict-6.7.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8f333ec9c5eb1b7105e3b84b53141e66ca05a19a605368c55450b6ba208cb9ee", size = 75190, upload-time = "2026-01-26T02:45:10.651Z" }, + { url = "https://files.pythonhosted.org/packages/d5/22/492f2246bb5b534abd44804292e81eeaf835388901f0c574bac4eeec73c5/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a407f13c188f804c759fc6a9f88286a565c242a76b27626594c133b82883b5c2", size = 44486, upload-time = "2026-01-26T02:45:11.938Z" }, + { url = "https://files.pythonhosted.org/packages/f1/4f/733c48f270565d78b4544f2baddc2fb2a245e5a8640254b12c36ac7ac68e/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0e161ddf326db5577c3a4cc2d8648f81456e8a20d40415541587a71620d7a7d1", size = 43219, upload-time = "2026-01-26T02:45:14.346Z" }, + { url = "https://files.pythonhosted.org/packages/24/bb/2c0c2287963f4259c85e8bcbba9182ced8d7fca65c780c38e99e61629d11/multidict-6.7.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1e3a8bb24342a8201d178c3b4984c26ba81a577c80d4d525727427460a50c22d", size = 245132, upload-time = "2026-01-26T02:45:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/a7/f9/44d4b3064c65079d2467888794dea218d1601898ac50222ab8a9a8094460/multidict-6.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97231140a50f5d447d3164f994b86a0bed7cd016e2682f8650d6a9158e14fd31", size = 252420, upload-time = "2026-01-26T02:45:17.293Z" }, + { url = "https://files.pythonhosted.org/packages/8b/13/78f7275e73fa17b24c9a51b0bd9d73ba64bb32d0ed51b02a746eb876abe7/multidict-6.7.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6b10359683bd8806a200fd2909e7c8ca3a7b24ec1d8132e483d58e791d881048", size = 233510, upload-time = "2026-01-26T02:45:19.356Z" }, + { url = "https://files.pythonhosted.org/packages/4b/25/8167187f62ae3cbd52da7893f58cb036b47ea3fb67138787c76800158982/multidict-6.7.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:283ddac99f7ac25a4acadbf004cb5ae34480bbeb063520f70ce397b281859362", size = 264094, upload-time = "2026-01-26T02:45:20.834Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e7/69a3a83b7b030cf283fb06ce074a05a02322359783424d7edf0f15fe5022/multidict-6.7.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:538cec1e18c067d0e6103aa9a74f9e832904c957adc260e61cd9d8cf0c3b3d37", size = 260786, upload-time = "2026-01-26T02:45:22.818Z" }, + { url = "https://files.pythonhosted.org/packages/fe/3b/8ec5074bcfc450fe84273713b4b0a0dd47c0249358f5d82eb8104ffe2520/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7eee46ccb30ff48a1e35bb818cc90846c6be2b68240e42a78599166722cea709", size = 248483, upload-time = "2026-01-26T02:45:24.368Z" }, + { url = "https://files.pythonhosted.org/packages/48/5a/d5a99e3acbca0e29c5d9cba8f92ceb15dce78bab963b308ae692981e3a5d/multidict-6.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa263a02f4f2dd2d11a7b1bb4362aa7cb1049f84a9235d31adf63f30143469a0", size = 248403, upload-time = "2026-01-26T02:45:25.982Z" }, + { url = "https://files.pythonhosted.org/packages/35/48/e58cd31f6c7d5102f2a4bf89f96b9cf7e00b6c6f3d04ecc44417c00a5a3c/multidict-6.7.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:2e1425e2f99ec5bd36c15a01b690a1a2456209c5deed58f95469ffb46039ccbb", size = 240315, upload-time = "2026-01-26T02:45:27.487Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/1cd210229559cb90b6786c30676bb0c58249ff42f942765f88793b41fdce/multidict-6.7.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:497394b3239fc6f0e13a78a3e1b61296e72bf1c5f94b4c4eb80b265c37a131cd", size = 245528, upload-time = "2026-01-26T02:45:28.991Z" }, + { url = "https://files.pythonhosted.org/packages/64/f2/6e1107d226278c876c783056b7db43d800bb64c6131cec9c8dfb6903698e/multidict-6.7.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:233b398c29d3f1b9676b4b6f75c518a06fcb2ea0b925119fb2c1bc35c05e1601", size = 258784, upload-time = "2026-01-26T02:45:30.503Z" }, + { url = "https://files.pythonhosted.org/packages/4d/c1/11f664f14d525e4a1b5327a82d4de61a1db604ab34c6603bb3c2cc63ad34/multidict-6.7.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:93b1818e4a6e0930454f0f2af7dfce69307ca03cdcfb3739bf4d91241967b6c1", size = 251980, upload-time = "2026-01-26T02:45:32.603Z" }, + { url = "https://files.pythonhosted.org/packages/e1/9f/75a9ac888121d0c5bbd4ecf4eead45668b1766f6baabfb3b7f66a410e231/multidict-6.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f33dc2a3abe9249ea5d8360f969ec7f4142e7ac45ee7014d8f8d5acddf178b7b", size = 243602, upload-time = "2026-01-26T02:45:34.043Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e7/50bf7b004cc8525d80dbbbedfdc7aed3e4c323810890be4413e589074032/multidict-6.7.1-cp314-cp314-win32.whl", hash = "sha256:3ab8b9d8b75aef9df299595d5388b14530839f6422333357af1339443cff777d", size = 40930, upload-time = "2026-01-26T02:45:36.278Z" }, + { url = "https://files.pythonhosted.org/packages/e0/bf/52f25716bbe93745595800f36fb17b73711f14da59ed0bb2eba141bc9f0f/multidict-6.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:5e01429a929600e7dab7b166062d9bb54a5eed752384c7384c968c2afab8f50f", size = 45074, upload-time = "2026-01-26T02:45:37.546Z" }, + { url = "https://files.pythonhosted.org/packages/97/ab/22803b03285fa3a525f48217963da3a65ae40f6a1b6f6cf2768879e208f9/multidict-6.7.1-cp314-cp314-win_arm64.whl", hash = "sha256:4885cb0e817aef5d00a2e8451d4665c1808378dc27c2705f1bf4ef8505c0d2e5", size = 42471, upload-time = "2026-01-26T02:45:38.889Z" }, + { url = "https://files.pythonhosted.org/packages/e0/6d/f9293baa6146ba9507e360ea0292b6422b016907c393e2f63fc40ab7b7b5/multidict-6.7.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0458c978acd8e6ea53c81eefaddbbee9c6c5e591f41b3f5e8e194780fe026581", size = 82401, upload-time = "2026-01-26T02:45:40.254Z" }, + { url = "https://files.pythonhosted.org/packages/7a/68/53b5494738d83558d87c3c71a486504d8373421c3e0dbb6d0db48ad42ee0/multidict-6.7.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:c0abd12629b0af3cf590982c0b413b1e7395cd4ec026f30986818ab95bfaa94a", size = 48143, upload-time = "2026-01-26T02:45:41.635Z" }, + { url = "https://files.pythonhosted.org/packages/37/e8/5284c53310dcdc99ce5d66563f6e5773531a9b9fe9ec7a615e9bc306b05f/multidict-6.7.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:14525a5f61d7d0c94b368a42cff4c9a4e7ba2d52e2672a7b23d84dc86fb02b0c", size = 46507, upload-time = "2026-01-26T02:45:42.99Z" }, + { url = "https://files.pythonhosted.org/packages/e4/fc/6800d0e5b3875568b4083ecf5f310dcf91d86d52573160834fb4bfcf5e4f/multidict-6.7.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:17307b22c217b4cf05033dabefe68255a534d637c6c9b0cc8382718f87be4262", size = 239358, upload-time = "2026-01-26T02:45:44.376Z" }, + { url = "https://files.pythonhosted.org/packages/41/75/4ad0973179361cdf3a113905e6e088173198349131be2b390f9fa4da5fc6/multidict-6.7.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a7e590ff876a3eaf1c02a4dfe0724b6e69a9e9de6d8f556816f29c496046e59", size = 246884, upload-time = "2026-01-26T02:45:47.167Z" }, + { url = "https://files.pythonhosted.org/packages/c3/9c/095bb28b5da139bd41fb9a5d5caff412584f377914bd8787c2aa98717130/multidict-6.7.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5fa6a95dfee63893d80a34758cd0e0c118a30b8dcb46372bf75106c591b77889", size = 225878, upload-time = "2026-01-26T02:45:48.698Z" }, + { url = "https://files.pythonhosted.org/packages/07/d0/c0a72000243756e8f5a277b6b514fa005f2c73d481b7d9e47cd4568aa2e4/multidict-6.7.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a0543217a6a017692aa6ae5cc39adb75e587af0f3a82288b1492eb73dd6cc2a4", size = 253542, upload-time = "2026-01-26T02:45:50.164Z" }, + { url = "https://files.pythonhosted.org/packages/c0/6b/f69da15289e384ecf2a68837ec8b5ad8c33e973aa18b266f50fe55f24b8c/multidict-6.7.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f99fe611c312b3c1c0ace793f92464d8cd263cc3b26b5721950d977b006b6c4d", size = 252403, upload-time = "2026-01-26T02:45:51.779Z" }, + { url = "https://files.pythonhosted.org/packages/a2/76/b9669547afa5a1a25cd93eaca91c0da1c095b06b6d2d8ec25b713588d3a1/multidict-6.7.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9004d8386d133b7e6135679424c91b0b854d2d164af6ea3f289f8f2761064609", size = 244889, upload-time = "2026-01-26T02:45:53.27Z" }, + { url = "https://files.pythonhosted.org/packages/7e/a9/a50d2669e506dad33cfc45b5d574a205587b7b8a5f426f2fbb2e90882588/multidict-6.7.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e628ef0e6859ffd8273c69412a2465c4be4a9517d07261b33334b5ec6f3c7489", size = 241982, upload-time = "2026-01-26T02:45:54.919Z" }, + { url = "https://files.pythonhosted.org/packages/c5/bb/1609558ad8b456b4827d3c5a5b775c93b87878fd3117ed3db3423dfbce1b/multidict-6.7.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:841189848ba629c3552035a6a7f5bf3b02eb304e9fea7492ca220a8eda6b0e5c", size = 232415, upload-time = "2026-01-26T02:45:56.981Z" }, + { url = "https://files.pythonhosted.org/packages/d8/59/6f61039d2aa9261871e03ab9dc058a550d240f25859b05b67fd70f80d4b3/multidict-6.7.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ce1bbd7d780bb5a0da032e095c951f7014d6b0a205f8318308140f1a6aba159e", size = 240337, upload-time = "2026-01-26T02:45:58.698Z" }, + { url = "https://files.pythonhosted.org/packages/a1/29/fdc6a43c203890dc2ae9249971ecd0c41deaedfe00d25cb6564b2edd99eb/multidict-6.7.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b26684587228afed0d50cf804cc71062cc9c1cdf55051c4c6345d372947b268c", size = 248788, upload-time = "2026-01-26T02:46:00.862Z" }, + { url = "https://files.pythonhosted.org/packages/a9/14/a153a06101323e4cf086ecee3faadba52ff71633d471f9685c42e3736163/multidict-6.7.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:9f9af11306994335398293f9958071019e3ab95e9a707dc1383a35613f6abcb9", size = 242842, upload-time = "2026-01-26T02:46:02.824Z" }, + { url = "https://files.pythonhosted.org/packages/41/5f/604ae839e64a4a6efc80db94465348d3b328ee955e37acb24badbcd24d83/multidict-6.7.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b4938326284c4f1224178a560987b6cf8b4d38458b113d9b8c1db1a836e640a2", size = 240237, upload-time = "2026-01-26T02:46:05.898Z" }, + { url = "https://files.pythonhosted.org/packages/5f/60/c3a5187bf66f6fb546ff4ab8fb5a077cbdd832d7b1908d4365c7f74a1917/multidict-6.7.1-cp314-cp314t-win32.whl", hash = "sha256:98655c737850c064a65e006a3df7c997cd3b220be4ec8fe26215760b9697d4d7", size = 48008, upload-time = "2026-01-26T02:46:07.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/f7/addf1087b860ac60e6f382240f64fb99f8bfb532bb06f7c542b83c29ca61/multidict-6.7.1-cp314-cp314t-win_amd64.whl", hash = "sha256:497bde6223c212ba11d462853cfa4f0ae6ef97465033e7dc9940cdb3ab5b48e5", size = 53542, upload-time = "2026-01-26T02:46:08.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/81/4629d0aa32302ef7b2ec65c75a728cc5ff4fa410c50096174c1632e70b3e/multidict-6.7.1-cp314-cp314t-win_arm64.whl", hash = "sha256:2bbd113e0d4af5db41d5ebfe9ccaff89de2120578164f86a5d17d5a576d1e5b2", size = 44719, upload-time = "2026-01-26T02:46:11.146Z" }, + { url = "https://files.pythonhosted.org/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" }, +] + [[package]] name = "mypy" version = "2.1.0" @@ -851,14 +1879,98 @@ dependencies = [ { name = "markdown-it-py" }, { name = "mdit-py-plugins" }, { name = "pyyaml" }, - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/21/dc/603751677fff302f34396e206b610f556a59d7fe58b9a2145f54e96b48e8/myst_parser-5.1.0.tar.gz", hash = "sha256:ab69322dc6719dcc7f296479dbb70181b66df6ed315064f92dbc85c0e1bf2f02", size = 101182, upload-time = "2026-05-13T09:38:19.361Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/09/dc/f3dfb7488b770f3f67e6545085bf2abea5172e88f57b8ad25ef860ca704c/myst_parser-5.1.0-py3-none-any.whl", hash = "sha256:9c91c52b3cdb4d94a6506e4fab4e2f296c7623a0da0dcbe6de1565c3dad67a8a", size = 85817, upload-time = "2026-05-13T09:38:17.904Z" }, ] +[[package]] +name = "narwhals" +version = "2.24.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2b/1d/58946e5aab18393e793bd4add6985b95d0e01c3a2d832f38f54468b10dcd/narwhals-2.24.0.tar.gz", hash = "sha256:b5c0f684ccd9d7475b564111e319a4964abcf2baf79d3cf6b1003d06ac9b828d", size = 661143, upload-time = "2026-07-13T10:49:19.086Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/85/a5bfaebfd305ac18b57b0854d74e37e586809061a91fda62f0bd50c8518e/narwhals-2.24.0-py3-none-any.whl", hash = "sha256:42fdedf44e5b2ca7505630d45b4ac3058f38d8485cba9fe1652ca23152df7489", size = 461030, upload-time = "2026-07-13T10:49:17.571Z" }, +] + +[[package]] +name = "nested-pandas" +version = "0.6.10" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'win32'", + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform != 'win32'", +] +dependencies = [ + { name = "deprecated", marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "fsspec", marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "numpy", marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "pyarrow", marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "universal-pathlib", marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "wrapt", marker = "extra == 'extra-8-cuperiod-lsdb'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/77/92/c5edd6b35f7b98a78acb6cd369705229f549b14bea2e4fac0e3809a164b0/nested_pandas-0.6.10.tar.gz", hash = "sha256:f8eb60372ba8953168147bec25b820a8813d17e0fe58de1b3dbd3cd0746ba0b2", size = 1208667, upload-time = "2026-05-14T18:17:19.336Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/46/7f5fc49e6e7c0cf1c98c511e09749e99c944702bc030ff53e3d0f2ebf469/nested_pandas-0.6.10-py3-none-any.whl", hash = "sha256:10fa2a7583041b61d2f987d4bb6021dc80f862bc4a56e3d391d20bb787f2a1e0", size = 81115, upload-time = "2026-05-14T18:17:17.674Z" }, +] + +[[package]] +name = "nested-pandas" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", +] +dependencies = [ + { name = "fsspec", marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, + { name = "numpy", marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, + { name = "pandas", version = "3.0.5", source = { registry = "https://pypi.org/simple" }, marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, + { name = "pyarrow", marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, + { name = "universal-pathlib", marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, + { name = "wrapt", marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/03/d00a1d067024364d7493dedc30cf82c8efda18f1a4340f2645e40905cb17/nested_pandas-0.7.0.tar.gz", hash = "sha256:4383441bc757bf53b6db6d7d576e3494565ccada6493b6bee6b237ded9ccb770", size = 1207944, upload-time = "2026-07-09T16:07:59.282Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/b6/1e2ab0cb518d64038fca6b30553219f4b113e910286eabe22aa28c4a1d8a/nested_pandas-0.7.0-py3-none-any.whl", hash = "sha256:910f6fe425e879e68c529654608cda6bbd19c66873df3f9e376a12f4f74bfd46", size = 81035, upload-time = "2026-07-09T16:07:58.081Z" }, +] + +[[package]] +name = "networkx" +version = "3.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, +] + [[package]] name = "numba" version = "0.65.1" @@ -970,6 +2082,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/15/ce/e5ec180bc41812edcd8daeb8639d205622c0e8c02259d8ab25a0201b3c2a/numpy-2.4.6-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:2803abfebfc990042cd494d8ce2d5f82e9d847af6d35ec486923aa19dbad5e73", size = 12504263, upload-time = "2026-05-18T23:37:09.715Z" }, ] +[[package]] +name = "nvidia-cublas" +version = "13.1.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cuda-nvrtc", marker = "(sys_platform != 'emscripten' and sys_platform != 'win32') or (sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/a1/0bd24ee8c8d03adac032fd2909426a00c88f8c57961b1277ded97f91119f/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:b7a210458267ac818974c53038fbec2e969d5c99f305ab15c72522fa9f001dd5", size = 542848918, upload-time = "2026-04-08T18:46:22.985Z" }, + { url = "https://files.pythonhosted.org/packages/3b/cd/154ca20c38269e05eff77c1464e6c1da89f50a6390b565e9d82e06bc11e1/nvidia_cublas-13.1.1.3-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:37936a16db8fe4ac1f065c2139360608a543a09275cb1a1af612e08cfa065436", size = 423138758, upload-time = "2026-04-08T18:46:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/45/9e/2f562daf80eb8f7a685fb7bea4fda71f6048e4f359d6fdd1b6e70206cb2f/nvidia_cublas-13.1.1.3-py3-none-win_amd64.whl", hash = "sha256:b6cdce694e47ff6aadf0a69df1cab6628d696f5ff56e8d16af50309d855fa20f", size = 404358158, upload-time = "2026-04-08T18:47:26.987Z" }, +] + [[package]] name = "nvidia-cublas-cu12" version = "12.9.2.10" @@ -983,6 +2108,26 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/e2/fc9a0e985249d873150276d5afb02e39a66817fedbf1a385724393e505ed/nvidia_cublas_cu12-12.9.2.10-py3-none-win_amd64.whl", hash = "sha256:623f43027d40d44ceadf0043f002bd25cf353e8f13ce90b9a87057019f560661", size = 553162896, upload-time = "2026-04-08T18:53:10.035Z" }, ] +[[package]] +name = "nvidia-cuda-cupti" +version = "13.0.85" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/2a/80353b103fc20ce05ef51e928daed4b6015db4aaa9162ed0997090fe2250/nvidia_cuda_cupti-13.0.85-py3-none-manylinux_2_25_aarch64.whl", hash = "sha256:796bd679890ee55fb14a94629b698b6db54bcfd833d391d5e94017dd9d7d3151", size = 10310827, upload-time = "2025-09-04T08:26:42.012Z" }, + { url = "https://files.pythonhosted.org/packages/33/6d/737d164b4837a9bbd202f5ae3078975f0525a55730fe871d8ed4e3b952b0/nvidia_cuda_cupti-13.0.85-py3-none-manylinux_2_25_x86_64.whl", hash = "sha256:4eb01c08e859bf924d222250d2e8f8b8ff6d3db4721288cf35d14252a4d933c8", size = 10715597, upload-time = "2025-09-04T08:26:51.312Z" }, + { url = "https://files.pythonhosted.org/packages/ad/df/b74b10025c1205695c5676373f2edd3e87a7202cc62ead0dfbc373b0f6ea/nvidia_cuda_cupti-13.0.85-py3-none-win_amd64.whl", hash = "sha256:683f58d301548deeefcb8f6fac1b8d907691b9d8b18eccab417f51e362102f00", size = 7736776, upload-time = "2025-09-04T08:38:08.38Z" }, +] + +[[package]] +name = "nvidia-cuda-nvrtc" +version = "13.0.88" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/68/483a78f5e8f31b08fb1bb671559968c0ca3a065ac7acabfc7cee55214fd6/nvidia_cuda_nvrtc-13.0.88-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:ad9b6d2ead2435f11cbb6868809d2adeeee302e9bb94bcf0539c7a40d80e8575", size = 90215200, upload-time = "2025-09-04T08:28:44.204Z" }, + { url = "https://files.pythonhosted.org/packages/b7/dc/6bb80850e0b7edd6588d560758f17e0550893a1feaf436807d64d2da040f/nvidia_cuda_nvrtc-13.0.88-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d27f20a0ca67a4bb34268a5e951033496c5b74870b868bacd046b1b8e0c3267b", size = 43015449, upload-time = "2025-09-04T08:28:20.239Z" }, + { url = "https://files.pythonhosted.org/packages/4a/af/345fedb9f4c76c84ab4fa445b36bd4048a4d9db60e6bc76b4f913ff4b852/nvidia_cuda_nvrtc-13.0.88-py3-none-win_amd64.whl", hash = "sha256:6bcd4e7f8e205cbe644f5a98f2f799bef9556fefc89dd786e79a16312ce49872", size = 76807835, upload-time = "2025-09-04T08:39:15.274Z" }, +] + [[package]] name = "nvidia-cuda-nvrtc-cu12" version = "12.9.86" @@ -993,6 +2138,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/de/823919be3b9d0ccbf1f784035423c5f18f4267fb0123558d58b813c6ec86/nvidia_cuda_nvrtc_cu12-12.9.86-py3-none-win_amd64.whl", hash = "sha256:72972ebdcf504d69462d3bcd67e7b81edd25d0fb85a2c46d3ea3517666636349", size = 76408187, upload-time = "2025-06-05T20:12:27.819Z" }, ] +[[package]] +name = "nvidia-cuda-runtime" +version = "13.0.96" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/4f/17d7b9b8e285199c58ce28e31b5c5bbaa4d8271af06a89b6405258245de2/nvidia_cuda_runtime-13.0.96-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ef9bcbe90493a2b9d810e43d249adb3d02e98dd30200d86607d8d02687c43f55", size = 2261060, upload-time = "2025-10-09T08:55:15.78Z" }, + { url = "https://files.pythonhosted.org/packages/2e/24/d1558f3b68b1d26e706813b1d10aa1d785e4698c425af8db8edc3dced472/nvidia_cuda_runtime-13.0.96-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f82250d7782aa23b6cfe765ecc7db554bd3c2870c43f3d1821f1d18aebf0548", size = 2243632, upload-time = "2025-10-09T08:55:36.117Z" }, + { url = "https://files.pythonhosted.org/packages/b7/94/6b867483bec07da24ffa32736c79fabb94ef3a7af4d787a9d4a974868576/nvidia_cuda_runtime-13.0.96-py3-none-win_amd64.whl", hash = "sha256:f79298c8a098cec150a597c8eba58ecdab96e3bdc4b9bc4f9983635031740492", size = 2927037, upload-time = "2025-10-09T09:04:23.782Z" }, +] + [[package]] name = "nvidia-cuda-runtime-cu12" version = "12.9.79" @@ -1003,6 +2158,32 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/59/df/e7c3a360be4f7b93cee39271b792669baeb3846c58a4df6dfcf187a7ffab/nvidia_cuda_runtime_cu12-12.9.79-py3-none-win_amd64.whl", hash = "sha256:8e018af8fa02363876860388bd10ccb89eb9ab8fb0aa749aaf58430a9f7c4891", size = 3591604, upload-time = "2025-06-05T20:11:17.036Z" }, ] +[[package]] +name = "nvidia-cudnn-cu13" +version = "9.20.0.48" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas", marker = "(sys_platform != 'emscripten' and sys_platform != 'win32') or (sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/c5/83384d846b2fd17c44bd499b36c75a45ed4f095fbbb2252294e89cea5c5c/nvidia_cudnn_cu13-9.20.0.48-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:e31454ae00094b0c55319d9d15b6fa2fc50a9e1c0f5c8c80fb75258234e731e1", size = 444574296, upload-time = "2026-03-09T19:28:27.751Z" }, + { url = "https://files.pythonhosted.org/packages/6e/5e/edb9c0ae051602c3ccaffe424256463636d639e27d7f302dde9975ef9e7a/nvidia_cudnn_cu13-9.20.0.48-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:0c45dd8eeb50b603f07995b1b300c62ffe6a1980482b82b3bcf94a4ca9d49304", size = 366173588, upload-time = "2026-03-09T19:29:34.474Z" }, + { url = "https://files.pythonhosted.org/packages/78/39/21507455b1bca8b5702a9e9fc6ce73735f216f558dac2c9ede58e4d456b8/nvidia_cudnn_cu13-9.20.0.48-py3-none-win_amd64.whl", hash = "sha256:af8139732b99c0118be65ea5aac97f0d46018f8c552889e49d2fb0c6261a4a24", size = 350712614, upload-time = "2026-03-09T19:31:11.398Z" }, +] + +[[package]] +name = "nvidia-cufft" +version = "12.0.0.61" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink", marker = "(sys_platform != 'emscripten' and sys_platform != 'win32') or (sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/8b/ae/f417a75c0259e85c1d2f83ca4e960289a5f814ed0cea74d18c353d3e989d/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2708c852ef8cd89d1d2068bdbece0aa188813a0c934db3779b9b1faa8442e5f5", size = 214053554, upload-time = "2025-09-04T08:31:38.196Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2f/7b57e29836ea8714f81e9898409196f47d772d5ddedddf1592eadb8ab743/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c44f692dce8fd5ffd3e3df134b6cdb9c2f72d99cf40b62c32dde45eea9ddad3", size = 214085489, upload-time = "2025-09-04T08:31:56.044Z" }, + { url = "https://files.pythonhosted.org/packages/85/b2/f8af21a2ed1beed337a6a02c5a28aeb85441f4d578ec3d529543c775ea4b/nvidia_cufft-12.0.0.61-py3-none-win_amd64.whl", hash = "sha256:2abce5b39d2f5ae12730fb7e5db6696533e36c26e2d3e8fd1750bdd2853364eb", size = 213342123, upload-time = "2025-09-04T08:40:51.145Z" }, +] + [[package]] name = "nvidia-cufft-cu12" version = "11.4.1.4" @@ -1016,6 +2197,40 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/ee/29955203338515b940bd4f60ffdbc073428f25ef9bfbce44c9a066aedc5c/nvidia_cufft_cu12-11.4.1.4-py3-none-win_amd64.whl", hash = "sha256:8e5bfaac795e93f80611f807d42844e8e27e340e0cde270dcb6c65386d795b80", size = 200067309, upload-time = "2025-06-05T20:13:59.762Z" }, ] +[[package]] +name = "nvidia-cufile" +version = "1.15.1.6" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/70/4f193de89a48b71714e74602ee14d04e4019ad36a5a9f20c425776e72cd6/nvidia_cufile-1.15.1.6-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:08a3ecefae5a01c7f5117351c64f17c7c62efa5fffdbe24fc7d298da19cd0b44", size = 1223672, upload-time = "2025-09-04T08:32:22.779Z" }, + { url = "https://files.pythonhosted.org/packages/ab/73/cc4a14c9813a8a0d509417cf5f4bdaba76e924d58beb9864f5a7baceefbf/nvidia_cufile-1.15.1.6-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:bdc0deedc61f548bddf7733bdc216456c2fdb101d020e1ab4b88d232d5e2f6d1", size = 1136992, upload-time = "2025-09-04T08:32:14.119Z" }, +] + +[[package]] +name = "nvidia-curand" +version = "10.4.0.35" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/72/7c2ae24fb6b63a32e6ae5d241cc65263ea18d08802aaae087d9f013335a2/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:133df5a7509c3e292aaa2b477afd0194f06ce4ea24d714d616ff36439cee349a", size = 61962106, upload-time = "2025-08-04T10:21:41.128Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9f/be0a41ca4a4917abf5cb9ae0daff1a6060cc5de950aec0396de9f3b52bc5/nvidia_curand-10.4.0.35-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:1aee33a5da6e1db083fe2b90082def8915f30f3248d5896bcec36a579d941bfc", size = 59544258, upload-time = "2025-08-04T10:22:03.992Z" }, + { url = "https://files.pythonhosted.org/packages/99/27/72103153b1ffc00e09fdc40ac970235343dcd1ea8bd762e84d2d73219ffa/nvidia_curand-10.4.0.35-py3-none-win_amd64.whl", hash = "sha256:65b1710aa6961d326b411e314b374290904c5ddf41dc3f766ebc3f1d7d4ca69f", size = 55242481, upload-time = "2025-08-04T10:30:41.831Z" }, +] + +[[package]] +name = "nvidia-cusolver" +version = "12.0.4.66" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas", marker = "(sys_platform != 'emscripten' and sys_platform != 'win32') or (sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-cusparse", marker = "(sys_platform != 'emscripten' and sys_platform != 'win32') or (sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-nvjitlink", marker = "(sys_platform != 'emscripten' and sys_platform != 'win32') or (sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/c3/b30c9e935fc01e3da443ec0116ed1b2a009bb867f5324d3f2d7e533e776b/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:02c2457eaa9e39de20f880f4bd8820e6a1cfb9f9a34f820eb12a155aa5bc92d2", size = 223467760, upload-time = "2025-09-04T08:33:04.222Z" }, + { url = "https://files.pythonhosted.org/packages/5f/67/cba3777620cdacb99102da4042883709c41c709f4b6323c10781a9c3aa34/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:0a759da5dea5c0ea10fd307de75cdeb59e7ea4fcb8add0924859b944babf1112", size = 200941980, upload-time = "2025-09-04T08:33:22.767Z" }, + { url = "https://files.pythonhosted.org/packages/99/ef/332a0101260ca78a1daef046bf0b06199e8ed4dac1d2aa698289c358169c/nvidia_cusolver-12.0.4.66-py3-none-win_amd64.whl", hash = "sha256:16515bd33a8e76bb54d024cfa068fa68d30e80fc34b9e1090813ea9362e0cb65", size = 193551444, upload-time = "2025-09-04T08:41:46.813Z" }, +] + [[package]] name = "nvidia-cusolver-cu12" version = "11.7.5.82" @@ -1031,6 +2246,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/5d/feb7f86b809f89b14193beffebe24cf2e4bf7af08372ab8cdd34d19a65a0/nvidia_cusolver_cu12-11.7.5.82-py3-none-win_amd64.whl", hash = "sha256:77666337237716783c6269a658dea310195cddbd80a5b2919b1ba8735cec8efd", size = 326215953, upload-time = "2025-06-05T20:14:41.76Z" }, ] +[[package]] +name = "nvidia-cusparse" +version = "12.6.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink", marker = "(sys_platform != 'emscripten' and sys_platform != 'win32') or (sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/94/5c26f33738ae35276672f12615a64bd008ed5be6d1ebcb23579285d960a9/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:80bcc4662f23f1054ee334a15c72b8940402975e0eab63178fc7e670aa59472c", size = 162155568, upload-time = "2025-09-04T08:33:42.864Z" }, + { url = "https://files.pythonhosted.org/packages/fa/18/623c77619c31d62efd55302939756966f3ecc8d724a14dab2b75f1508850/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2b3c89c88d01ee0e477cb7f82ef60a11a4bcd57b6b87c33f789350b59759360b", size = 145942937, upload-time = "2025-09-04T08:33:58.029Z" }, + { url = "https://files.pythonhosted.org/packages/02/b0/b043d6f3480f102f885cf87fc3ffd3edcb5e23b855025a50e2ef4d059185/nvidia_cusparse-12.6.3.3-py3-none-win_amd64.whl", hash = "sha256:cbcf42feb737bd7ec15b4c0a63e62351886bd3f975027b8815d7f720a2b5ea79", size = 143783033, upload-time = "2025-09-04T08:42:12.391Z" }, +] + [[package]] name = "nvidia-cusparse-cu12" version = "12.5.10.65" @@ -1044,6 +2272,35 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/73/ef/063500c25670fbd1cbb0cd3eb7c8a061585b53adb4dd8bf3492bb49b0df3/nvidia_cusparse_cu12-12.5.10.65-py3-none-win_amd64.whl", hash = "sha256:9e487468a22a1eaf1fbd1d2035936a905feb79c4ce5c2f67626764ee4f90227c", size = 362504719, upload-time = "2025-06-05T20:15:17.947Z" }, ] +[[package]] +name = "nvidia-cusparselt-cu13" +version = "0.8.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/e1/cdc1797eadf82d3a9a575a19b33fdc871a97edbec42c00b5b5e914f4aff4/nvidia_cusparselt_cu13-0.8.1-py3-none-manylinux2014_aarch64.whl", hash = "sha256:4dca476c50bf4780d46cd0bfbd82e2bc10a08e4fef7950917ce8d7578d22a23f", size = 221051344, upload-time = "2025-09-05T18:49:51.289Z" }, + { url = "https://files.pythonhosted.org/packages/34/7d/2661f2fb3ac4302f3a246f5fc030213ac60c1fe0bce84f9783dbd831dbb7/nvidia_cusparselt_cu13-0.8.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:786ce87568c303fadb5afcc7102d454cd3040d75f6f8626f5db460d1871f4dd0", size = 170148586, upload-time = "2025-09-05T18:50:50.248Z" }, + { url = "https://files.pythonhosted.org/packages/31/83/f3647ce26916c94a6ca4ff1810623e2c405cff2dea6e78d29516b2514df9/nvidia_cusparselt_cu13-0.8.1-py3-none-win_amd64.whl", hash = "sha256:dccbd362f91a7b9024d1f55ee9f548ac065027ff15d8c8b0db889ab3a8f31215", size = 156885108, upload-time = "2025-09-05T18:51:35.958Z" }, +] + +[[package]] +name = "nvidia-nccl-cu13" +version = "2.29.7" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/0d/daf50d44177ee0cbc7ff0a0c91eb5ff676c82be42f9a970bc7597f440c3a/nvidia_nccl_cu13-2.29.7-py3-none-manylinux_2_18_aarch64.whl", hash = "sha256:674a12383e3c38a1bcccae7d4f3633b37852230b6047883cb2f4c2d1b36d9bf5", size = 206014712, upload-time = "2026-03-03T05:34:20.843Z" }, + { url = "https://files.pythonhosted.org/packages/67/f4/58e4e91b6919367c7aafb8e36fce9aad1a3047e536bf7e2fd560927d3a4c/nvidia_nccl_cu13-2.29.7-py3-none-manylinux_2_18_x86_64.whl", hash = "sha256:edd81538446786ec3b73972543e53bb43bcaf0bfc8ef76cb679fcc390ffe136d", size = 205976000, upload-time = "2026-03-03T05:36:24.472Z" }, +] + +[[package]] +name = "nvidia-nvjitlink" +version = "13.3.33" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/ee/580ca6f29dcab0221db8706badca1bbbb084f1975c4d4e83329c3a7e31f0/nvidia_nvjitlink-13.3.33-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:26a6de7fb4c8fdaa7703d3dad720d6d427ddfea5c48a528fd97c11733ad830e5", size = 40742423, upload-time = "2026-05-26T16:54:51.613Z" }, + { url = "https://files.pythonhosted.org/packages/69/30/45414e35ff2eee7db3da037e5707037ccf9d2b5218ffbdb055ea4d5aa98a/nvidia_nvjitlink-13.3.33-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ce48b37dfeb3cb1eae4cf85adacb47d7a6539ea2272870c9a3628ce275c2037e", size = 39168635, upload-time = "2026-05-26T16:54:13.906Z" }, + { url = "https://files.pythonhosted.org/packages/67/f2/ec9c05a108095828dfc58840978c627b3c313fdf2a567c6de9ffbbb46901/nvidia_nvjitlink-13.3.33-py3-none-win_amd64.whl", hash = "sha256:4297ee49639b4f2e07255a1d69b3acc7ab2d011bb892b403e91ac98368962e3b", size = 37766359, upload-time = "2026-05-26T17:11:28.96Z" }, +] + [[package]] name = "nvidia-nvjitlink-cu12" version = "12.9.86" @@ -1054,6 +2311,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/dd/7e/2eecb277d8a98184d881fb98a738363fd4f14577a4d2d7f8264266e82623/nvidia_nvjitlink_cu12-12.9.86-py3-none-win_amd64.whl", hash = "sha256:cc6fcec260ca843c10e34c936921a1c426b351753587fdd638e8cff7b16bb9db", size = 35584936, upload-time = "2025-06-05T20:16:08.525Z" }, ] +[[package]] +name = "nvidia-nvshmem-cu13" +version = "3.4.5" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/0f/05cc9c720236dcd2db9c1ab97fff629e96821be2e63103569da0c9b72f19/nvidia_nvshmem_cu13-3.4.5-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6dc2a197f38e5d0376ad52cd1a2a3617d3cdc150fd5966f4aee9bcebb1d68fe9", size = 60215947, upload-time = "2025-09-06T00:32:20.022Z" }, + { url = "https://files.pythonhosted.org/packages/3c/35/a9bf80a609e74e3b000fef598933235c908fcefcef9026042b8e6dfde2a9/nvidia_nvshmem_cu13-3.4.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:290f0a2ee94c9f3687a02502f3b9299a9f9fe826e6d0287ee18482e78d495b80", size = 60412546, upload-time = "2025-09-06T00:32:41.564Z" }, +] + +[[package]] +name = "nvidia-nvtx" +version = "13.0.85" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/f3/d86c845465a2723ad7e1e5c36dcd75ddb82898b3f53be47ebd429fb2fa5d/nvidia_nvtx-13.0.85-py3-none-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4936d1d6780fbe68db454f5e72a42ff64d1fd6397df9f363ae786930fd5c1cd4", size = 148047, upload-time = "2025-09-04T08:29:01.761Z" }, + { url = "https://files.pythonhosted.org/packages/a8/64/3708a90d1ebe202ffdeb7185f878a3c84d15c2b2c31858da2ce0583e2def/nvidia_nvtx-13.0.85-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb7780edb6b14107373c835bf8b72e7a178bac7367e23da7acb108f973f157a6", size = 148878, upload-time = "2025-09-04T08:28:53.627Z" }, + { url = "https://files.pythonhosted.org/packages/d2/50/0e2220f8620a177de994211186ffc5bfa9f2ce1e1282797f8f90096f9f88/nvidia_nvtx-13.0.85-py3-none-win_amd64.whl", hash = "sha256:d66ea44254dd3c6eacc300047af6e1288d2269dd072b417e0adffbf479e18519", size = 137066, upload-time = "2025-09-04T08:39:25.649Z" }, +] + [[package]] name = "packaging" version = "26.2" @@ -1065,56 +2341,163 @@ wheels = [ [[package]] name = "pandas" -version = "3.0.4" +version = "2.3.3" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform != 'win32'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'win32'", + "python_full_version < '3.12' and sys_platform == 'win32'", + "python_full_version < '3.12' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "python-dateutil", marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "pytz", marker = "extra == 'extra-8-cuperiod-lsdb'" }, + { name = "tzdata", marker = "extra == 'extra-8-cuperiod-lsdb'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/fa/7ac648108144a095b4fb6aa3de1954689f7af60a14cf25583f4960ecb878/pandas-2.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:602b8615ebcc4a0c1751e71840428ddebeb142ec02c786e8ad6b1ce3c8dec523", size = 11578790, upload-time = "2025-09-29T23:18:30.065Z" }, + { url = "https://files.pythonhosted.org/packages/9b/35/74442388c6cf008882d4d4bdfc4109be87e9b8b7ccd097ad1e7f006e2e95/pandas-2.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8fe25fc7b623b0ef6b5009149627e34d2a4657e880948ec3c840e9402e5c1b45", size = 10833831, upload-time = "2025-09-29T23:38:56.071Z" }, + { url = "https://files.pythonhosted.org/packages/fe/e4/de154cbfeee13383ad58d23017da99390b91d73f8c11856f2095e813201b/pandas-2.3.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b468d3dad6ff947df92dcb32ede5b7bd41a9b3cceef0a30ed925f6d01fb8fa66", size = 12199267, upload-time = "2025-09-29T23:18:41.627Z" }, + { url = "https://files.pythonhosted.org/packages/bf/c9/63f8d545568d9ab91476b1818b4741f521646cbdd151c6efebf40d6de6f7/pandas-2.3.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b98560e98cb334799c0b07ca7967ac361a47326e9b4e5a7dfb5ab2b1c9d35a1b", size = 12789281, upload-time = "2025-09-29T23:18:56.834Z" }, + { url = "https://files.pythonhosted.org/packages/f2/00/a5ac8c7a0e67fd1a6059e40aa08fa1c52cc00709077d2300e210c3ce0322/pandas-2.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37b5848ba49824e5c30bedb9c830ab9b7751fd049bc7914533e01c65f79791", size = 13240453, upload-time = "2025-09-29T23:19:09.247Z" }, + { url = "https://files.pythonhosted.org/packages/27/4d/5c23a5bc7bd209231618dd9e606ce076272c9bc4f12023a70e03a86b4067/pandas-2.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db4301b2d1f926ae677a751eb2bd0e8c5f5319c9cb3f88b0becbbb0b07b34151", size = 13890361, upload-time = "2025-09-29T23:19:25.342Z" }, + { url = "https://files.pythonhosted.org/packages/8e/59/712db1d7040520de7a4965df15b774348980e6df45c129b8c64d0dbe74ef/pandas-2.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:f086f6fe114e19d92014a1966f43a3e62285109afe874f067f5abbdcbb10e59c", size = 11348702, upload-time = "2025-09-29T23:19:38.296Z" }, + { url = "https://files.pythonhosted.org/packages/9c/fb/231d89e8637c808b997d172b18e9d4a4bc7bf31296196c260526055d1ea0/pandas-2.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d21f6d74eb1725c2efaa71a2bfc661a0689579b58e9c0ca58a739ff0b002b53", size = 11597846, upload-time = "2025-09-29T23:19:48.856Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bd/bf8064d9cfa214294356c2d6702b716d3cf3bb24be59287a6a21e24cae6b/pandas-2.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3fd2f887589c7aa868e02632612ba39acb0b8948faf5cc58f0850e165bd46f35", size = 10729618, upload-time = "2025-09-29T23:39:08.659Z" }, + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/86/41/585a168330ff063014880a80d744219dbf1dd7a1c706e75ab3425a987384/pandas-2.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:a16dcec078a01eeef8ee61bf64074b4e524a2a3f4b3be9326420cabe59c4778b", size = 10992722, upload-time = "2025-09-29T23:20:54.139Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4b/18b035ee18f97c1040d94debd8f2e737000ad70ccc8f5513f4eefad75f4b/pandas-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:56851a737e3470de7fa88e6131f41281ed440d29a9268dcbf0002da5ac366713", size = 11544671, upload-time = "2025-09-29T23:21:05.024Z" }, + { url = "https://files.pythonhosted.org/packages/31/94/72fac03573102779920099bcac1c3b05975c2cb5f01eac609faf34bed1ca/pandas-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdcd9d1167f4885211e401b3036c0c8d9e274eee67ea8d0758a256d60704cfe8", size = 10680807, upload-time = "2025-09-29T23:21:15.979Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c7/e54682c96a895d0c808453269e0b5928a07a127a15704fedb643e9b0a4c8/pandas-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f8bfc0e12dc78f777f323f55c58649591b2cd0c43534e8355c51d3fede5f4dee", size = 10993991, upload-time = "2025-09-29T23:25:04.889Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ca/3f8d4f49740799189e1395812f3bf23b5e8fc7c190827d55a610da72ce55/pandas-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:75ea25f9529fdec2d2e93a42c523962261e567d250b0013b16210e1d40d7c2e5", size = 12048227, upload-time = "2025-09-29T23:22:24.343Z" }, + { url = "https://files.pythonhosted.org/packages/0e/5a/f43efec3e8c0cc92c4663ccad372dbdff72b60bdb56b2749f04aa1d07d7e/pandas-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74ecdf1d301e812db96a465a525952f4dde225fdb6d8e5a521d47e1f42041e21", size = 11411056, upload-time = "2025-09-29T23:22:37.762Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, + { url = "https://files.pythonhosted.org/packages/04/fd/74903979833db8390b73b3a8a7d30d146d710bd32703724dd9083950386f/pandas-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:ee15f284898e7b246df8087fc82b87b01686f98ee67d85a17b7ab44143a3a9a0", size = 11540635, upload-time = "2025-09-29T23:25:52.486Z" }, + { url = "https://files.pythonhosted.org/packages/21/00/266d6b357ad5e6d3ad55093a7e8efc7dd245f5a842b584db9f30b0f0a287/pandas-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1611aedd912e1ff81ff41c745822980c49ce4a7907537be8692c8dbc31924593", size = 10759079, upload-time = "2025-09-29T23:26:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, + { url = "https://files.pythonhosted.org/packages/a6/3d/124ac75fcd0ecc09b8fdccb0246ef65e35b012030defb0e0eba2cbbbe948/pandas-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:1b07204a219b3b7350abaae088f451860223a52cfb8a6c53358e7948735158e5", size = 11109071, upload-time = "2025-09-29T23:32:27.484Z" }, + { url = "https://files.pythonhosted.org/packages/89/9c/0e21c895c38a157e0faa1fb64587a9226d6dd46452cac4532d80c3c4a244/pandas-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2462b1a365b6109d275250baaae7b760fd25c726aaca0054649286bcfbb3e8ec", size = 12048504, upload-time = "2025-09-29T23:29:31.47Z" }, + { url = "https://files.pythonhosted.org/packages/d7/82/b69a1c95df796858777b68fbe6a81d37443a33319761d7c652ce77797475/pandas-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0242fe9a49aa8b4d78a4fa03acb397a58833ef6199e9aa40a95f027bb3a1b6e7", size = 11410702, upload-time = "2025-09-29T23:29:54.591Z" }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, +] + +[[package]] +name = "pandas" +version = "3.0.5" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.15' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", +] dependencies = [ - { name = "numpy" }, - { name = "python-dateutil" }, - { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5a/fd/e0194474c71dbfba82e744f66945c274f15b667acd5f8c117b12555fb91e/pandas-3.0.4.tar.gz", hash = "sha256:62f6062586d159663825f06e70ef49cd1572d45824cb63a9559f3ffd1d0d2a20", size = 4658146, upload-time = "2026-06-28T15:31:51.3Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d3/be/f23b2369adf0fd241820778e3d534e940cf052e6cd325fee9b508726d26e/pandas-3.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:87d6be6820c5c2b3c41d30f2c8387aac10e842af7d43dd9c3c22f2ce0a4c4176", size = 10409998, upload-time = "2026-06-28T15:29:45.196Z" }, - { url = "https://files.pythonhosted.org/packages/79/c0/902b30ae918f5482016f6151f7e4621b71f43200f4b20f7a7fa162c74130/pandas-3.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dce7eca7e5adc4cc79bc28435e6111474772c14c11f4a742ea0041e23fff7d73", size = 10041669, upload-time = "2026-06-28T15:29:49.492Z" }, - { url = "https://files.pythonhosted.org/packages/58/54/2b287f9edfcbeecfd5ae9372827738f47f84130c4be73c9069c04e29bf1a/pandas-3.0.4-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:14d274e00885373c879042dd3bd3dd27bfea6edef993f23644ed8a20468a7471", size = 10598978, upload-time = "2026-06-28T15:29:52.113Z" }, - { url = "https://files.pythonhosted.org/packages/0c/36/94e1bf5c6b3a635b7d8dc496af11840489322522a53e842477fdbcd8b08a/pandas-3.0.4-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c423500b3f0118c2d02b5a76ade4c57f3a13b9c9cecf04599bf983ba247cebaa", size = 11119683, upload-time = "2026-06-28T15:29:54.912Z" }, - { url = "https://files.pythonhosted.org/packages/1a/89/d8c41d1807a09c51170e2666c956e07d881eaaac1ecdc942d6f8662a9d1e/pandas-3.0.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aaa9760a86a77a2586807a72f64748b312b95c37135ae9932cd65fe859507377", size = 11612249, upload-time = "2026-06-28T15:29:58.235Z" }, - { url = "https://files.pythonhosted.org/packages/64/fc/e62c97b2234c89bd541ff3cc19a019c4399ca5d0af35c6a35a6bf5b41a3a/pandas-3.0.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e9c0eb4036cbf4110af16c5593191c51c1803752c7645f8f74b3a922a1027f42", size = 12170521, upload-time = "2026-06-28T15:30:01.695Z" }, - { url = "https://files.pythonhosted.org/packages/ec/b8/f5f6caf9a6c643296a92e88922c53e9932101e00403517c45ca3704b47ab/pandas-3.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:a79a6401beed48057b9101d7e722d3d0af80e570b578438da6c7de4a10cc3a29", size = 9868871, upload-time = "2026-06-28T15:30:04.754Z" }, - { url = "https://files.pythonhosted.org/packages/b8/f8/22d6f9575a918c0a5c2c57414fd4ff07765b8bce1bce34bb7b6a886c6d86/pandas-3.0.4-cp311-cp311-win_arm64.whl", hash = "sha256:dc827bff97d448ced1a8d9b4055486cadd97b6ac52c3eb3e1dd154f49d869be1", size = 9117450, upload-time = "2026-06-28T15:30:08.982Z" }, - { url = "https://files.pythonhosted.org/packages/69/7d/37fce6b1f4537218af19ab71ca2814e0794c4a1d4e412026afdc1988b5cb/pandas-3.0.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0f22242de864ca997028520e28b5dcdd440443ad239395bdabcb6124ed009067", size = 10422311, upload-time = "2026-06-28T15:30:12.192Z" }, - { url = "https://files.pythonhosted.org/packages/1b/ce/3b280464d1c6faba9080435cd54f23c244ea79228f3508913f58753235dc/pandas-3.0.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2bef5bf689a9f0d21ca83436f74c061ba52f426a689d2f8028e2e3d9ac0a8d05", size = 10061739, upload-time = "2026-06-28T15:30:15.162Z" }, - { url = "https://files.pythonhosted.org/packages/94/50/927a39cdf93bf541b56390c32a58ae64f70f2748b8f2a88576ce8e4b6d7b/pandas-3.0.4-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9624cceb273c8f97d16c518f0cbf362d12edbdbb4ed46712eb2def2f7ed7de1", size = 10287537, upload-time = "2026-06-28T15:30:18.181Z" }, - { url = "https://files.pythonhosted.org/packages/bd/63/6898384737b5e32dd72067843bea661661ff32325da91f978347ba563cf2/pandas-3.0.4-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a477e4b7f3d18d63b5131e7a5faea3f2f8d7153f493cb145e552ba52c904ab2e", size = 10793447, upload-time = "2026-06-28T15:30:21.038Z" }, - { url = "https://files.pythonhosted.org/packages/b3/8d/1424ca0d99ea192e84b17d1547463ed7f9cd628c9c395b770aded58a7efc/pandas-3.0.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:fa604623167246500d962d109df5c5b953955afb637f0dd14d9500ab191dbce7", size = 11309351, upload-time = "2026-06-28T15:30:23.987Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f0/4f5aa9df56b378434b056afc22e0a6f4ed2b69006f61e61cd4b4397a87cd/pandas-3.0.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:833232f7a694cb841a2fd8b309ca655e24dcac2ae3e1959efed97d573499b389", size = 11859582, upload-time = "2026-06-28T15:30:27.365Z" }, - { url = "https://files.pythonhosted.org/packages/5a/b0/97c3be4b0bbe82ed31d78d32659637d1ad0f2ad50b524a0851a068734f9c/pandas-3.0.4-cp312-cp312-pyemscripten_2024_0_wasm32.whl", hash = "sha256:25d9ba5ad021e7bd50c674f528e31f15dc22e28c9dfa50bd4cdbdd3a4f5f1902", size = 7115248, upload-time = "2026-06-28T15:30:30.128Z" }, - { url = "https://files.pythonhosted.org/packages/66/93/503f381c106a9e6b4717356cc4805cc68b5af64b97f273590bf294cedd54/pandas-3.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:6b6797a68ccb1391ec7b7873681b23317dd4cfbd45228aadc0b837fdff02170d", size = 9670611, upload-time = "2026-06-28T15:30:32.776Z" }, - { url = "https://files.pythonhosted.org/packages/92/7d/9d7efe0c18d059d9cf0cd0f56f55c6aa584f8c506bcd5776ae097f195eaf/pandas-3.0.4-cp312-cp312-win_arm64.whl", hash = "sha256:b3543e828bbd8d6ebe98b6a4268f57edc6bd945561fd08abfd29021bd5dc23ff", size = 8966047, upload-time = "2026-06-28T15:30:35.665Z" }, - { url = "https://files.pythonhosted.org/packages/dc/df/9febd45b3a643876260a4f53c6c1c7e30894e9e9f7d3a484b97d4ccc61fb/pandas-3.0.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ab8b23bf3ea0fe4337d115389d800896583854694b4c0b2de08e19c81f70140f", size = 10443559, upload-time = "2026-06-28T15:30:38.67Z" }, - { url = "https://files.pythonhosted.org/packages/5f/e2/081b445177716989e6320c49b45c67b0b5ea75d71a327843826e380e1875/pandas-3.0.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bcf15e8c8cbe4d1bb7b9c3f243ddb96123bbeb4585a40bad4c22dd673620a3c0", size = 10073663, upload-time = "2026-06-28T15:30:41.329Z" }, - { url = "https://files.pythonhosted.org/packages/7a/76/60d39cd44c42995cb92cc627138a429533098bb4e9f4268dfef53de24e77/pandas-3.0.4-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d7ddfd571e26846b568d6e08065002046b54ffd4e81c51a61520f3040c677431", size = 10236941, upload-time = "2026-06-28T15:30:44.034Z" }, - { url = "https://files.pythonhosted.org/packages/50/68/7abd718ed1b373e47684bb788dec0b547ed218a41a15e0b04d05b81d1779/pandas-3.0.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6afa70bd5a24cedf0c983d888f7d48c3ca1bc5fc095d38a3e6277e85f9bd4ab3", size = 10762008, upload-time = "2026-06-28T15:30:46.904Z" }, - { url = "https://files.pythonhosted.org/packages/fb/0c/99ee1b43b23cbeb69585aebaa08575fa1bf3e8e0c5f3bb27f5148ae7d8bb/pandas-3.0.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ba4acbe620c3888ffc561d278ba5a67f30fa9d2aba92052fbee9c951938110fc", size = 11258245, upload-time = "2026-06-28T15:30:50.438Z" }, - { url = "https://files.pythonhosted.org/packages/23/74/e6dd260c2d65fe8a5eed5b2bd7756f9393ccaefef12ea683fb05b7c15b9c/pandas-3.0.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:26451dd26dcfa2e9f5172cb9c6d8213cebfc9130fc7a1844e11e642ffa458b54", size = 11820489, upload-time = "2026-06-28T15:30:53.539Z" }, - { url = "https://files.pythonhosted.org/packages/fb/e7/8eedac9e7443651a4400d2ec8ebfb4be3be43cc3ec8ac3d5fbdbf7f0e149/pandas-3.0.4-cp313-cp313-win_amd64.whl", hash = "sha256:63468a898ba7b54280fc6db21833cf99b9b62b2b54b5d5d10b5ab813ce100fbf", size = 9650344, upload-time = "2026-06-28T15:30:56.716Z" }, - { url = "https://files.pythonhosted.org/packages/fc/36/5f00ada639c67062720dc813a72d6dcca8eb86bc55620d2bb17dcf284073/pandas-3.0.4-cp313-cp313-win_arm64.whl", hash = "sha256:5f9538b9d13b974a3a7d40c23b8d66f41114ceffe6c586f38efb8ed71d778caa", size = 8958077, upload-time = "2026-06-28T15:30:59.462Z" }, - { url = "https://files.pythonhosted.org/packages/da/9d/b70e2d6fd65f497a03922d0a0019a2b9ec7a40374fbd2f2cb6a697109806/pandas-3.0.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:45751e5d456788ca891167c6456fb5e373ad72aa82a949c9635b63e215940181", size = 10515604, upload-time = "2026-06-28T15:31:02.329Z" }, - { url = "https://files.pythonhosted.org/packages/ae/fc/a514a959eeb0a8ad0294747df5ff1c95bf364aa2f2c533d6c2a8c0720bf4/pandas-3.0.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5c912d80243e4563934f34acc41cfad1a08d7af1b40597492cc6b5e6ba311404", size = 10169825, upload-time = "2026-06-28T15:31:05.34Z" }, - { url = "https://files.pythonhosted.org/packages/72/f8/11da3c5c7a39ab436bda99a1bf2ff5ab3b6addb91155b3fc5d068e733940/pandas-3.0.4-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ccdf354cddecbf0d763ab5a21d0d698440154c5ed6f2c43643c5f528e5c184a7", size = 10384438, upload-time = "2026-06-28T15:31:07.949Z" }, - { url = "https://files.pythonhosted.org/packages/3e/64/01d6352e2f108045e628680f1dd0a11276489beeae580c2c9d8a74df390b/pandas-3.0.4-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cadb8f48ada5de3feaa735577af15f0874cd5498d6875cf17989d97d4bc2e926", size = 10795673, upload-time = "2026-06-28T15:31:11.331Z" }, - { url = "https://files.pythonhosted.org/packages/47/1f/c4319dc17cc88b7a90780ecaad15a484ab8ddee32466093a7ff6fcf8fdb1/pandas-3.0.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bf867a8fe99499762626adbda73759b0378add0d13a58044ee668ba2d5df92f9", size = 11394840, upload-time = "2026-06-28T15:31:14.223Z" }, - { url = "https://files.pythonhosted.org/packages/ab/c4/5660f3f5bebfee4bcdee8c13212806f326ba9d1dbdf7f408c7766f279faa/pandas-3.0.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:58a0b88e5f6c46974ba110c2cef6b8714aaea57f9f26d55ab5361de662b28165", size = 11877357, upload-time = "2026-06-28T15:31:17.205Z" }, - { url = "https://files.pythonhosted.org/packages/c4/92/a16e08eebab6183817757adf6783f644e2061fa14e5905ced79d362cbf36/pandas-3.0.4-cp314-cp314-win_amd64.whl", hash = "sha256:2a32675e6e7641effa300e58040609107f6e976bb0783b0264556358df64db58", size = 9806280, upload-time = "2026-06-28T15:31:20.496Z" }, - { url = "https://files.pythonhosted.org/packages/6a/ef/7d0810b2ba48fd3b015f82e5f907b2b757f40727d86481a2bea22123e454/pandas-3.0.4-cp314-cp314-win_arm64.whl", hash = "sha256:337be3b93ca7e0db3ec25edc769ebb74a8702427edeb345ee6ebe3e3080c6350", size = 9125456, upload-time = "2026-06-28T15:31:23.426Z" }, - { url = "https://files.pythonhosted.org/packages/78/e6/32800039b35eaa4eeb2da0182dd13d2cc205ce21e13e860c0e855f9f64e8/pandas-3.0.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ca9c1332eb5b69027fa1a73125e5b35fae26aea8c64a716a1924261070b0b859", size = 10938203, upload-time = "2026-06-28T15:31:26.903Z" }, - { url = "https://files.pythonhosted.org/packages/67/16/eff8bc63f22c8e881d31fe25a09542eea3bf8142ccf595974fc76f28a373/pandas-3.0.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1ae9e815bb61e0a85227aec3db22ba5502a4192df4918c115a772960e6ba606", size = 10586746, upload-time = "2026-06-28T15:31:29.836Z" }, - { url = "https://files.pythonhosted.org/packages/0b/03/6b413ed392ce8d7e90af963123bc62ccb6dd8d889ecf8951b7d1c1dddd86/pandas-3.0.4-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6f482730bc2ec12b53c6205190deb195275495b4871bc1a2036beb91a7c97aee", size = 10240823, upload-time = "2026-06-28T15:31:32.879Z" }, - { url = "https://files.pythonhosted.org/packages/67/26/7992ed1748beb166a68d667e6651a03309f7e08a88a0520a7a381e06e21e/pandas-3.0.4-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5065f02eb94b947ff2610bba2b0c1a74fd67ca10fde0686b12adfc36e61d11d3", size = 10658793, upload-time = "2026-06-28T15:31:36.404Z" }, - { url = "https://files.pythonhosted.org/packages/5d/16/c92b5ea088632476b831200c54de4740531a6777c8f650ab3c3cec5e7bf5/pandas-3.0.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9b1a5e49e5fa13d002e1b237af4ab57f91f535cc6f6ca9225a366b2ce6241d99", size = 11274714, upload-time = "2026-06-28T15:31:39.871Z" }, - { url = "https://files.pythonhosted.org/packages/9c/0c/149cfc617640575a28c878f2d26f20899f4ef206b08a7338a83eb592f297/pandas-3.0.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f660473c1e7a7ea7155214f89047b83ac0db6ebe7fab4d5a463f881307162d8c", size = 11729898, upload-time = "2026-06-28T15:31:42.95Z" }, - { url = "https://files.pythonhosted.org/packages/fb/4a/5f1e5b5784ecd4eab4ad52b2025f3e828c289d49c063eac64b400619bb07/pandas-3.0.4-cp314-cp314t-win_amd64.whl", hash = "sha256:453c9e65d0ea8f1ff00d0d5dd2a2612df9ead3ac1baaf55b81e18a01a7a56846", size = 10201594, upload-time = "2026-06-28T15:31:45.917Z" }, - { url = "https://files.pythonhosted.org/packages/05/f3/40a59a8e1abf01b13be5102ece560dc30bb7e85ed06b3e78442c445cb028/pandas-3.0.4-cp314-cp314t-win_arm64.whl", hash = "sha256:02a8c70e5a304947a802551b8ddb38fe83d9c528395a361609fddcccb7cf8003", size = 9387615, upload-time = "2026-06-28T15:31:48.694Z" }, + { name = "numpy", marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, + { name = "python-dateutil", marker = "extra == 'extra-8-cuperiod-dev' or extra != 'extra-8-cuperiod-lsdb'" }, + { name = "tzdata", marker = "(sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev') or (sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-lsdb') or (sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev') or (sys_platform == 'win32' and extra != 'extra-8-cuperiod-lsdb') or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/4f/5f3422a2afec5ffc46308b79e53291365a93748b498ac2e58bead0197916/pandas-3.0.5.tar.gz", hash = "sha256:dca3734d6ab7c906e6730f0788b0a1dbb9f2467731f9711f77995c8e9d62d712", size = 4658219, upload-time = "2026-07-22T22:19:28.819Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/ef/f1fd7431d635bf20015489bf0bd69c17fff1018de773540f651455a3916b/pandas-3.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2946e77e4a53cd248cbde631a12f0e51c8324ce354c3eba4d20147c1ad6f4282", size = 10397178, upload-time = "2026-07-22T22:17:48.274Z" }, + { url = "https://files.pythonhosted.org/packages/31/b4/0eafac990a431561187694126de01f9b12559549b4d86360c0c4bd870fde/pandas-3.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:71ecc8fb7ed1a7aa4392316b5309a6347e8e7f832f38fd897846b3a1457a9298", size = 9990736, upload-time = "2026-07-22T22:17:52.388Z" }, + { url = "https://files.pythonhosted.org/packages/de/21/359880af3ea9b7cb23bea5b51e8e70ef3866c03be09da9a2787e18e330a8/pandas-3.0.5-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b173f5951ff6b8b0ec7675e20dff3c97b7e7a57dfcce387c2d7c5afe87cb7899", size = 10814438, upload-time = "2026-07-22T22:17:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/d1/50/d6cc4d7e508bbccf5d6027314a8312bc7ac73d0ec7f195f53838daafab40/pandas-3.0.5-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c0cf1dd9b55a22d105fc46c1b489af3bd42264fcba7c66297bf47a9a1d9c78a", size = 11323634, upload-time = "2026-07-22T22:17:56.858Z" }, + { url = "https://files.pythonhosted.org/packages/70/2b/d5f0a8c90dd0ae04e64ba53b871afb796ec026b615086d382ddc2ade729b/pandas-3.0.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0fac0010c75e4efb6b99e249c183a8993ce0dc95c240f9b120a5e67c727b7928", size = 11850860, upload-time = "2026-07-22T22:17:59.1Z" }, + { url = "https://files.pythonhosted.org/packages/5c/30/183aec2e19adf778a98d29b5729a0a68f4cc4ebf9b9c3b70d0297355bcb1/pandas-3.0.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:08d24fe11a17dc33bd6e937dc9c665f9cba08fbdc9f657f405713515febe300d", size = 12411100, upload-time = "2026-07-22T22:18:01.485Z" }, + { url = "https://files.pythonhosted.org/packages/fa/9a/31f4983f191af51ab2a8f2d0c7b33dff3a84da26533f982fff02c2f9e28b/pandas-3.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:b1261758dfb6cf12c3cff8300e21cefad30e7ec709abb4c24ac7318e6a52462a", size = 9968804, upload-time = "2026-07-22T22:18:03.903Z" }, + { url = "https://files.pythonhosted.org/packages/49/97/7886c89a39045c69ad82cbceaf3343810480c8ef49a216319ce8183860a6/pandas-3.0.5-cp311-cp311-win_arm64.whl", hash = "sha256:679f4e85b30ddb1515458ab1e788d3e260eae369b1f78da7a3aa4cac8ebf4a2a", size = 9205447, upload-time = "2026-07-22T22:18:06.134Z" }, + { url = "https://files.pythonhosted.org/packages/1c/54/1dc810ea558d1320b597aa140a514f2fdf1d2ea09c38cf556f13ea712ec9/pandas-3.0.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fa290c16964d4963fbfbc358928239cf3bd755b20e988ce944877def2f44471d", size = 10411717, upload-time = "2026-07-22T22:18:08.307Z" }, + { url = "https://files.pythonhosted.org/packages/68/56/fbe81c09195924d8b7b8d4461a20458fe80a6a5ed6b24f0314da684277e1/pandas-3.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c2e26bb46934b8a2ca0c3de1d3d606fc5f6746584791b2db264d58cf370e08dc", size = 9957095, upload-time = "2026-07-22T22:18:10.6Z" }, + { url = "https://files.pythonhosted.org/packages/e0/51/fac252f4a913ed5eabf3c11b880a9e8d5a6c10f0b2129d0462212d238b4d/pandas-3.0.5-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:73fa87b08a7ef706f8aafda39ddaccf2a99047bea62d8c88a0361bcafb2237bc", size = 10485458, upload-time = "2026-07-22T22:18:12.834Z" }, + { url = "https://files.pythonhosted.org/packages/12/98/e976540c1addf70442be7842a18cf70884a964abbf69442504f4d2939989/pandas-3.0.5-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d373ce03ffd84010ed9839fa73672a9c8256990532e158440c0085db7d914b34", size = 10998091, upload-time = "2026-07-22T22:18:15.209Z" }, + { url = "https://files.pythonhosted.org/packages/a4/8c/1f29b5be8d3fc47dd7567eb167fabba2085879b31e0287ce7cba6d3d2ff4/pandas-3.0.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2a29c53d85ea98c5e792c59ef82ee9fbe6ca902c0d0adb6b23f45ef894cd7bf6", size = 11499501, upload-time = "2026-07-22T22:18:17.689Z" }, + { url = "https://files.pythonhosted.org/packages/9d/e2/bd9c98ad2df7b38bde002adde4cdf353519da51881634323b126c55997f9/pandas-3.0.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a5ad3b02ed6bc7d7ae9b70804b2c6aa31827489d150f8e623ce82491b82085d7", size = 12060559, upload-time = "2026-07-22T22:18:20.147Z" }, + { url = "https://files.pythonhosted.org/packages/f3/9a/ffbd852d58bd74a617fe2f8ee6a58a96982271ce41cf981eab22190b4a4b/pandas-3.0.5-cp312-cp312-pyemscripten_2024_0_wasm32.whl", hash = "sha256:b2acb4650527eec6822c3dadb2b771277b65e7dae7a267d4bccf65fd1bb3fbce", size = 7197652, upload-time = "2026-07-22T22:18:22.502Z" }, + { url = "https://files.pythonhosted.org/packages/70/b5/d2d3e9ae73362ba4229651b0ee1455cf78073a1ce585f6ff693782ce263e/pandas-3.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:80a611068e8a3ac23f7398c6c14eb46dc974e5cc9997f653e2dcfd1da74edd41", size = 9831691, upload-time = "2026-07-22T22:18:24.534Z" }, + { url = "https://files.pythonhosted.org/packages/52/51/dea1e89d6a6796b9c43f85a09b484ee03edb8a4c4842e73e200a8c11301c/pandas-3.0.5-cp312-cp312-win_arm64.whl", hash = "sha256:25ff585b972a18ef1fe9ffa3ac6544d9950508aa76832e5147640b6022821e49", size = 9105796, upload-time = "2026-07-22T22:18:27.064Z" }, + { url = "https://files.pythonhosted.org/packages/bf/09/7b95c4a0025227d6f118c4039b423412ac6a982db02864166185d812fbc7/pandas-3.0.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c1c05a767fe8e5b4fe9e1c29806829c582052eaedb9120a3da83ba3f69e24a5b", size = 10385742, upload-time = "2026-07-22T22:18:29.346Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0c/dc78fd8c4da477b4b5e8ad37295af352190d21ef63a9ee1bc071753074cc/pandas-3.0.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b86765f268b56f7e665b93bce9d5df69dee7f99e595cf8fb839483ab315942a3", size = 9932067, upload-time = "2026-07-22T22:18:31.833Z" }, + { url = "https://files.pythonhosted.org/packages/3e/71/3592c055cf44df9808550f9368ceda80ff2b224d355ef73fe251dcda1802/pandas-3.0.5-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c597ecf5616b5c420372c1d4d4c00dbbfba7398bea857dcc984347e1ea48417b", size = 10466756, upload-time = "2026-07-22T22:18:34.195Z" }, + { url = "https://files.pythonhosted.org/packages/e3/70/4363150359f95b4cb4bcbb34ca23572bb5495749a621a8f3d5a1ddfd293c/pandas-3.0.5-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b11c36e218331d0387cbe3a0a5f75162357a1d92d57b2b08a336ff94b19b2be", size = 10938525, upload-time = "2026-07-22T22:18:36.81Z" }, + { url = "https://files.pythonhosted.org/packages/f7/d0/317e7a0c67c0e69fa905a0161409397a7dc2d46ff611f6ca4803352c042b/pandas-3.0.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cf52e1f61d229496da17dc7ab54acdee627357e7008fd4fecba3d0ba2937fa58", size = 11489303, upload-time = "2026-07-22T22:18:39.287Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8d/36dade89b49e4f9d5cbdbe863772581f98c0c6d78fc39ad4c557f6f2e17e/pandas-3.0.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:db172144bb56422bd157812f3b021eacc255451470b31e2c633c349490a1cfee", size = 11989004, upload-time = "2026-07-22T22:18:42.208Z" }, + { url = "https://files.pythonhosted.org/packages/9c/ba/18c4ec8a746e177da05a9e7a7963781d8ea195780724f854601b6ebd6b78/pandas-3.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:0d298e951f23016ce4699951d044ae6418dbc91bf68cefca0f77666fcbb4e5c6", size = 9826896, upload-time = "2026-07-22T22:18:44.539Z" }, + { url = "https://files.pythonhosted.org/packages/de/ec/28a57266b753799a87b8bc79e7887ac6fd981b8c6d2978a0b7e7b6bd708c/pandas-3.0.5-cp313-cp313-win_arm64.whl", hash = "sha256:66266d3442a5e8b3c90274c2b8b230bee42dd1c286bc822cc2f9f2c7e12b883e", size = 9094790, upload-time = "2026-07-22T22:18:47.468Z" }, + { url = "https://files.pythonhosted.org/packages/51/2f/cf6aae281264f4463f0875bcbb15fd2bb6d291cc535187dad1732475e4a9/pandas-3.0.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2f264fc46911cc8131a7322a16199bbf8e353d27c10bb211f5bd0c814324dc36", size = 10390034, upload-time = "2026-07-22T22:18:49.818Z" }, + { url = "https://files.pythonhosted.org/packages/06/ec/5189518c7a7659c4bdcc6b1eb32c46c6f3c86b0661ffd84143d1112c7732/pandas-3.0.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:53730687fcd161883b24e10411c06d6a4c0f2275d2faf3bb2bc25deb4ba8007c", size = 9980065, upload-time = "2026-07-22T22:18:52.249Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f1/598503ce8d7e3c35601e0747ba288c7864baae66380725bc12f13f884dfe/pandas-3.0.5-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:960d3ebcf249f75206899fcd2c6de53f736b7265759ced0d3e559df0b8b709b0", size = 10545532, upload-time = "2026-07-22T22:18:54.813Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/ceae2adf7034e07e9910299fe412e1819c4f0dd520700a888bcb03625448/pandas-3.0.5-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e94c2c5ca43bd3ca32bf64d32308887b65e5f9bfd8023ea52755107a999f93b", size = 10963120, upload-time = "2026-07-22T22:18:57.42Z" }, + { url = "https://files.pythonhosted.org/packages/66/25/86e0f4451874eb79e688deeebe3c451fec4557f8952005818d800ee8ac7e/pandas-3.0.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e819dd5f62966b481a8cb649d3299ebd886a1ea91ed5a99bf7ce77c98d18ab94", size = 11563178, upload-time = "2026-07-22T22:18:59.729Z" }, + { url = "https://files.pythonhosted.org/packages/f3/45/8643daa3b4147e433adfcccefdd0380d3aad79d86b15d8999730fe1944d5/pandas-3.0.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3c5ed2e7c06e91d340dfd091d7934f9bc82e4a36b95f647f090b9d1c9ac649da", size = 12028708, upload-time = "2026-07-22T22:19:02.164Z" }, + { url = "https://files.pythonhosted.org/packages/96/58/ad979ae617615576e8aafd569c9d4b62f1191d896e38f51d66ba06f3b89a/pandas-3.0.5-cp314-cp314-win_amd64.whl", hash = "sha256:cd8f7c6dc98527058ee6264219343f5392240a6f1bfa654fc5d79023020d0c92", size = 9951806, upload-time = "2026-07-22T22:19:04.596Z" }, + { url = "https://files.pythonhosted.org/packages/69/32/7ac03886b304049a9d2625ee88f59af760d8a93bd30ed9239bce7b9869a8/pandas-3.0.5-cp314-cp314-win_arm64.whl", hash = "sha256:5183427f5a8156d480f30333777bc978be93650a49a7c01db26adffe95b31e85", size = 9238297, upload-time = "2026-07-22T22:19:06.836Z" }, + { url = "https://files.pythonhosted.org/packages/be/ed/1d1f2ee5547d5167face2376d11c8b2a4c7bfff5a416ee7a9046891fab1e/pandas-3.0.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:303da736987d481074ca720ada325f8bd80c64ebc2d45ed79b29df3aaa4a26ca", size = 10849690, upload-time = "2026-07-22T22:19:09.391Z" }, + { url = "https://files.pythonhosted.org/packages/57/55/17e17152e98fbb0c4b1e562bc65387a2f20a80db0f4a86bf8d3a0e4248d4/pandas-3.0.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3b2801bbb049d0136f6c213eae02b5fca969384fc2064dd728d8620552aa49da", size = 10509945, upload-time = "2026-07-22T22:19:11.773Z" }, + { url = "https://files.pythonhosted.org/packages/88/90/817d44dbf83facf9556f33576d9af0a241981e7bb5c00606c0bcb5df8dda/pandas-3.0.5-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cce3a9d11d2b1f82c69a27ec1f4948a170e2c403c4bbfa8cca62e3fdebe2ef3a", size = 10392197, upload-time = "2026-07-22T22:19:14.024Z" }, + { url = "https://files.pythonhosted.org/packages/f1/da/889f00c0a6f5aa1545add70abbf01502dff87ab577adb855bd631c54d2f2/pandas-3.0.5-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef01af4d8dc6cd2c8d6c7736f149574ef93fe043811eeb5e445f2647154b5040", size = 10862726, upload-time = "2026-07-22T22:19:16.351Z" }, + { url = "https://files.pythonhosted.org/packages/bc/98/f1e934fb3c98fce859c6147c6785816c7b5b9ab7821115c5d8c4de9842b9/pandas-3.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e2759e890db96dfcffdbd9b86c3c2cb6afaf58def482820317e06163ec1066cd", size = 11414864, upload-time = "2026-07-22T22:19:18.981Z" }, + { url = "https://files.pythonhosted.org/packages/fe/be/d448af7d657d82e1888dd8551f79c6d6fb161080b5b9752d84d910ec2319/pandas-3.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b58b1b39d46a5862e3fb18f50d1a201398619d16a0f9f73f57eea5583cf0e63c", size = 11925105, upload-time = "2026-07-22T22:19:21.515Z" }, + { url = "https://files.pythonhosted.org/packages/29/c1/ccb4238212c8c4f496c584f3044d94e0c030ed8e1d68999db46c91c2242f/pandas-3.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:1c10461f6eeb35d8f05b6184c65c8b9991663b66c46b1d559b682cb34ae7c6ea", size = 10387612, upload-time = "2026-07-22T22:19:24.257Z" }, + { url = "https://files.pythonhosted.org/packages/d2/cf/6a51b2c38980e04c279fd2fa908a1b0982064e860444acfca4ec2e2c8359/pandas-3.0.5-cp314-cp314t-win_arm64.whl", hash = "sha256:3c5015fd1730fbf883647e88068176c839c102cea883ba1769a6f4593bfc1f8c", size = 9509776, upload-time = "2026-07-22T22:19:26.694Z" }, +] + +[[package]] +name = "partd" +version = "1.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "locket" }, + { name = "toolz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b2/3a/3f06f34820a31257ddcabdfafc2672c5816be79c7e353b02c1f318daa7d4/partd-1.4.2.tar.gz", hash = "sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c", size = 21029, upload-time = "2024-05-06T19:51:41.945Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl", hash = "sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f", size = 18905, upload-time = "2024-05-06T19:51:39.271Z" }, +] + +[[package]] +name = "pathlib-abc" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/cb/448649d7f25d228bf0be3a04590ab7afa77f15e056f8fa976ed05ec9a78f/pathlib_abc-0.5.2.tar.gz", hash = "sha256:fcd56f147234645e2c59c7ae22808b34c364bb231f685ddd9f96885aed78a94c", size = 33342, upload-time = "2025-10-10T18:37:20.524Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/29/c028a0731e202035f0e2e0bfbf1a3e46ad6c628cbb17f6f1cc9eea5d9ff1/pathlib_abc-0.5.2-py3-none-any.whl", hash = "sha256:4c9d94cf1b23af417ce7c0417b43333b06a106c01000b286c99de230d95eefbb", size = 19070, upload-time = "2025-10-10T18:37:19.437Z" }, ] [[package]] @@ -1126,6 +2509,91 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" }, ] +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/c8/0a78b0e02d7ac54bc03e5321c9220da52f0c2ea83b21f7c40e7f3169c502/pillow-12.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:00808c5e14ef63ac5161091d242999076604ff74b883423a11e5d7bbb38bf756", size = 5392415, upload-time = "2026-07-01T11:53:47.162Z" }, + { url = "https://files.pythonhosted.org/packages/b2/5b/a02d30018abd97ced9f5a6c63d28597694a00d066516b9c1c6de45859fc9/pillow-12.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37d6d0a00072fd2948eb22bce7e1475f34569d90c87c59f7a2ec59541b77f7a6", size = 4785266, upload-time = "2026-07-01T11:53:49.079Z" }, + { url = "https://files.pythonhosted.org/packages/c8/98/766667a4be768150a202836acd9fad19c06824ca86c4286d3cf6b274964e/pillow-12.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bcb46e2f9feff8d06323983bd83ed00c201fdcab3d74973e7072a889b3979fcd", size = 6263814, upload-time = "2026-07-01T11:53:51.32Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2d/ede717bc1144f63886c21fd349bb95860b0d1a21149ff16f2bb362b612b6/pillow-12.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:23d27a3e0307ec2244cc51e7287b919aa68d097504ebe19df4e76a98a3eea5bd", size = 6934408, upload-time = "2026-07-01T11:53:53.487Z" }, + { url = "https://files.pythonhosted.org/packages/a3/48/9c58b685e69d49c31af6c8eb9012055fab7e665785165c84796e2c73ce72/pillow-12.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f883547d4b7f0495ebe7056b0cc2aea76094e7a4abc8e933540f3271df27d9c", size = 6337160, upload-time = "2026-07-01T11:53:55.457Z" }, + { url = "https://files.pythonhosted.org/packages/ff/fa/dc2a5c0ba6df93f67c31d34b808b7ce440b40cdbf96f0b81cde1d1e6fa93/pillow-12.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:236ff70b9312fb68943c703aa842ca6a758abfa45ac187a5e7c1452e96ef72b5", size = 7045172, upload-time = "2026-07-01T11:53:57.736Z" }, + { url = "https://files.pythonhosted.org/packages/86/a5/444817a4d4c4c2417df00513086ca196f388d8f9ef40c2e4ccd1ad1af54b/pillow-12.3.0-cp311-cp311-win32.whl", hash = "sha256:10e41f0fbf1eec8cfd234b8fe17a4caac7c9d0db4c204d3c173a8f9f6ef3232b", size = 6472232, upload-time = "2026-07-01T11:53:59.767Z" }, + { url = "https://files.pythonhosted.org/packages/63/c6/4bad1b18d132a50b27e1365e1ab163616f7a5bb56d330f66f9d1d9d4f9d4/pillow-12.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8e95e1385e4998ae9694eeaa4730ba5457ff61185b3a55e2e7bea0880aef452a", size = 7233653, upload-time = "2026-07-01T11:54:02.066Z" }, + { url = "https://files.pythonhosted.org/packages/fd/16/00f91ab7760dc842f5aad55217e80fc4a7067a0604535249bc8a2d6d9870/pillow-12.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:ebaea975e03d3141d9d3a507df75c9b3ec90fa9d2ffd07567b3a978d9d790b26", size = 2568195, upload-time = "2026-07-01T11:54:04.622Z" }, + { url = "https://files.pythonhosted.org/packages/37/bf/fb3ebff8ddcb76aac5a01389251bbbb9519922a9b520d8247c1ca864a25d/pillow-12.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ba09209fbe443b4acccebe845d8a138b89a8f4fbaeedd44953490b5315d5e965", size = 5345969, upload-time = "2026-07-01T11:54:06.397Z" }, + { url = "https://files.pythonhosted.org/packages/d8/66/9a386a92561f402389a4fc70c18838bf6d35eb5eb5c6850b4b2dc64f5048/pillow-12.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffd0c5368496f41b0944be820fcb7a838aa6e623d250b01acf2643939c3f99d7", size = 4780323, upload-time = "2026-07-01T11:54:09.351Z" }, + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/20/20/25e0f4dc178a6bc0696793720055519a0de89e7661dae886992decbd2f81/pillow-12.3.0-cp312-cp312-win32.whl", hash = "sha256:dbce0b29841537a2fa4a214c2bbf14de3587c9680caa9b4e217568472490b28f", size = 6472684, upload-time = "2026-07-01T11:54:19.839Z" }, + { url = "https://files.pythonhosted.org/packages/45/89/da2f7971a317f83d807fdd4065c0af40208e59e692cc43d315a71a0e96d1/pillow-12.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a2b55dd6b2a4c4b7d87ffa56bdb33fdc5fdb9a462173861a7bc097f17d91cb09", size = 7227137, upload-time = "2026-07-01T11:54:22.025Z" }, + { url = "https://files.pythonhosted.org/packages/de/47/4845a0a6c0dbf1db8456bd9fc791f13c5ced7ced20606d08a0aacfd25b49/pillow-12.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:331b624368d4f1d069149002f25f44bc61c8919ce8ddb3c45bdad8f6e2d89510", size = 2568267, upload-time = "2026-07-01T11:54:24.051Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" }, + { url = "https://files.pythonhosted.org/packages/42/92/2fc3ffad878ae8dd5469ec1bc8eb83b71f48e13efdf68f02709003982a32/pillow-12.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7a743ff716f746fc19a9557f60dab1600d4613255f8a7aeb3cdde4db7eb15a66", size = 5345889, upload-time = "2026-07-01T11:54:31.97Z" }, + { url = "https://files.pythonhosted.org/packages/10/76/8803c13605b763d33d156c4678fc77f8443389c0c51c8aef707bb02015f4/pillow-12.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d69141514cc30b774ceea5e3ed3a6635c8d8a96edf664689b890f4089111fb35", size = 4780109, upload-time = "2026-07-01T11:54:34.026Z" }, + { url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" }, + { url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" }, + { url = "https://files.pythonhosted.org/packages/c9/f9/066794cca041b969964f779ee5fa66a9498bbf34248ac39c5d7954e4198f/pillow-12.3.0-cp313-cp313-win32.whl", hash = "sha256:a876864214e136f0eb367788dbd7df045f4806801518e2cfe9e13229cfe06d8f", size = 6473287, upload-time = "2026-07-01T11:54:44.9Z" }, + { url = "https://files.pythonhosted.org/packages/a6/9b/7a58e61d62be561da3a356fe2384d4059a6345fc130e23ef1c36a5b81d24/pillow-12.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:1cca606cd25738df4ed873d5ad46bbdb3d83b5cbca291f6b4ff13a4df6b0bbe8", size = 7239691, upload-time = "2026-07-01T11:54:47.141Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b0/c4ed4f0ef8f8fa5ee8351537db6650bb8189f7e118842978dd6589065692/pillow-12.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:b629de27fda84b42cde7edef0d85f13b958b47f6e9bbcbba9b673c562a89bd8b", size = 2568185, upload-time = "2026-07-01T11:54:49.137Z" }, + { url = "https://files.pythonhosted.org/packages/dc/01/001f65b68192f0228cc1dbbc8d2530ab5d58b61037ba0587f946fea607cd/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330", size = 4161736, upload-time = "2026-07-01T11:54:51.156Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d2/0219746d0fd16fc8a84498e79452375be3797d3ce4044596ce565164b84f/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217", size = 4255435, upload-time = "2026-07-01T11:54:53.414Z" }, + { url = "https://files.pythonhosted.org/packages/c8/02/8d0bc62ef0302318c46ff2a512822d2610e81c7aa46c9b3abe6cbaca5ad0/pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930", size = 3696262, upload-time = "2026-07-01T11:54:55.739Z" }, + { url = "https://files.pythonhosted.org/packages/85/e2/73c77d218410b14f5f2d565e8a998d5317b7b9c75368d29985139f7a46f0/pillow-12.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ba54cfebe86920a559a7c4d6b9050791c20513650a1952ebe3368c7dc70306f8", size = 5350344, upload-time = "2026-07-01T11:54:57.657Z" }, + { url = "https://files.pythonhosted.org/packages/c7/da/32c752228ae345f489e3a42499d817b6c3996da7e8a3bc7a04fc806b243b/pillow-12.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e158cb00350dc278f3b91551101aa7d12415a66ebf2c91d8d5ac14e56ddd3ad0", size = 4780131, upload-time = "2026-07-01T11:54:59.713Z" }, + { url = "https://files.pythonhosted.org/packages/b1/9d/8b2c807dbef61a5197c047afe99823787eb66f63daf9fb2432f91d6f0462/pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321", size = 6263757, upload-time = "2026-07-01T11:55:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/5c/44/c85361f65dbe00eea8576ee467c768d25129989efb76e94f205e9ca9bb46/pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b", size = 6936962, upload-time = "2026-07-01T11:55:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/e483414b35800b86b6f08dbbc7803fb5cd52c4d6f897f47d53ea2c7e6f65/pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198", size = 6339171, upload-time = "2026-07-01T11:55:05.989Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f4/68c491844841ede6bed70189546b3ee9731cf9f2cbad396faff5e1ccba45/pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130", size = 7048116, upload-time = "2026-07-01T11:55:08.131Z" }, + { url = "https://files.pythonhosted.org/packages/a3/34/77f3f793fed8efc7d243f21b33c5a3f0d1c97ee70346d3db855587e155ff/pillow-12.3.0-cp314-cp314-win32.whl", hash = "sha256:af8d94b0db561cf68b88a267c5c44b49e134f525d0dc2cb7ed413a66bc23559a", size = 6467209, upload-time = "2026-07-01T11:55:10.408Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e0/492879f69d94f91f60fc8cd05ba03650e9520afebb2fb7aa12777d7c7f38/pillow-12.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:fdafc9cce40277e0f7a0feabce0ee50dd2fa1800f3b38015e51296b5e814048d", size = 7237707, upload-time = "2026-07-01T11:55:12.745Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ac/6b11f2875f1c2ac040d84e1bbf9cf22a88038f901ca1037898b280b38365/pillow-12.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:e91206ee562682b51b98ef4b26a6ef48fd84e15fd4c4bc5ec768eb641d206838", size = 2565995, upload-time = "2026-07-01T11:55:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/52/69/c2208e56af9bfc1913afb24020297a691eb1d4ef688474c8a04913f65e04/pillow-12.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:164b31cd1a0490ab6efae01aa5df49da7061be0af1b30e035b6e9a1bfe34ee6e", size = 5352503, upload-time = "2026-07-01T11:55:17.076Z" }, + { url = "https://files.pythonhosted.org/packages/07/70/e5686d753e898a45d778ff1718dba8516ead6ab6b95d85fc8c4b70650cf2/pillow-12.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5afb51d599ea772b8365ae807ae557f18bccfe46ab261fd1c2a9ed700fc6eb17", size = 4782956, upload-time = "2026-07-01T11:55:19.448Z" }, + { url = "https://files.pythonhosted.org/packages/d5/37/25c6692f06927ee973ff18c8d9ee98ad0b4d84ee67a09610c2dd1447958e/pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385", size = 6322855, upload-time = "2026-07-01T11:55:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/cc/91/420637fcb8f1bc11029e403b4538e6694744428d8246118e45719f944556/pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c", size = 6989642, upload-time = "2026-07-01T11:55:24.006Z" }, + { url = "https://files.pythonhosted.org/packages/10/08/b94d7811281ccf0d143a1cf768d1c49e1e54af63e7b708ab2ee3eb87face/pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d", size = 6391281, upload-time = "2026-07-01T11:55:26.252Z" }, + { url = "https://files.pythonhosted.org/packages/d2/87/24233f785f55474dc02ce3e739c5528a77e3a862e9333d1dd7a25cc31f70/pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931", size = 7096716, upload-time = "2026-07-01T11:55:28.318Z" }, + { url = "https://files.pythonhosted.org/packages/23/26/fcb2f6e37175b04f53570b59937867e2b80ee1685e744023153028fc14f9/pillow-12.3.0-cp314-cp314t-win32.whl", hash = "sha256:4b0a7fe987b14c31ebda6083f74f22b561fd3739bc0ac51e019622e3d72668c7", size = 6474125, upload-time = "2026-07-01T11:55:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/90/de/3634abee5f1c9e13c56787b7d5517b0ba8d6de51700b95578cf338349c9f/pillow-12.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:962864dc93511324d51ddbb5b9f8731bf71675b93ca612a07441896f4688fb8c", size = 7242939, upload-time = "2026-07-01T11:55:34.044Z" }, + { url = "https://files.pythonhosted.org/packages/ce/2a/fd13f8eb24de5714a6eb444a3d67e2842c6c576e159a43793adf23051351/pillow-12.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0740a512dc522224c77d9aa5a8d70d8b7d73fb91f2c21125d8d025d3b8990e45", size = 2567506, upload-time = "2026-07-01T11:55:35.988Z" }, + { url = "https://files.pythonhosted.org/packages/5d/dc/8fdce34ec725a33c81c6ba122b904d6b9024e50ea9ac7bede62fab54506c/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139", size = 4162063, upload-time = "2026-07-01T11:55:37.941Z" }, + { url = "https://files.pythonhosted.org/packages/76/66/2044b9a63d3b84ff048228dfcb7cd9bf0df983e8470971bf7d4c57b693de/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402", size = 4255549, upload-time = "2026-07-01T11:55:40.022Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/1f67e6f4ece6b582ee4b539decbcc9f848dc245a93ed8cd7338bafef72f1/pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c", size = 3696331, upload-time = "2026-07-01T11:55:41.98Z" }, + { url = "https://files.pythonhosted.org/packages/12/40/d306fc2c8e4d45d7f175c77edca7063be7b86fe7fe6e68f4353bf71d808c/pillow-12.3.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:dc624f6bc473dacdf7ef7eb8678d0d08edf15cd94fad6ae5c7d6cc67a4e4902f", size = 5350370, upload-time = "2026-07-01T11:55:44.028Z" }, + { url = "https://files.pythonhosted.org/packages/dd/44/668fb1437e8ce420f62d6106eb66e44a5971602a4d794615bdf79315d82d/pillow-12.3.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:71d6097b330eea8fd15097780c8e89cb1a8ce7838669f48c5bacd6f663dd4701", size = 4780147, upload-time = "2026-07-01T11:55:46.073Z" }, + { url = "https://files.pythonhosted.org/packages/0c/08/93fa2e70e30a2d81547e481b6ee2bb9522117221fb1e0ce4b5df70967677/pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace", size = 6273659, upload-time = "2026-07-01T11:55:48.264Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4", size = 6947439, upload-time = "2026-07-01T11:55:50.503Z" }, + { url = "https://files.pythonhosted.org/packages/af/92/ba71d2ee2ac0edf3fa33bd9d5ee9ee080da70b1766f3ca3934f9938ddac9/pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39", size = 6353577, upload-time = "2026-07-01T11:55:52.697Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ce/e63064e2122923ff687c8ad792d0d736a7b3920a56a46982e81a7fdd25d6/pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71", size = 7060394, upload-time = "2026-07-01T11:55:55.149Z" }, + { url = "https://files.pythonhosted.org/packages/54/76/a09cc3ccc8d773a7283d34c38bec1708f9e3cc932093cbc4c5e71ac4060b/pillow-12.3.0-cp315-cp315-win32.whl", hash = "sha256:57b3d78c95ba9059768b10e28b813002261d3f3dfc55cc48b0c988f625175827", size = 6467375, upload-time = "2026-07-01T11:55:57.769Z" }, + { url = "https://files.pythonhosted.org/packages/3e/03/1846c49ba3b1d5550392a4bbd06d6fb4578e1cd91a803198b5c90f5f7d53/pillow-12.3.0-cp315-cp315-win_amd64.whl", hash = "sha256:fa4ecea169a355be7a3ade2c783e2ed12f0e40d2c5621cda8b3297faf7fbb9f5", size = 7237048, upload-time = "2026-07-01T11:55:59.975Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bb/89f35dcc79610423f9f195504d7def7f0d1416a711541b42867e25fe3412/pillow-12.3.0-cp315-cp315-win_arm64.whl", hash = "sha256:877c3f311ff35410f690861c4409e7ccbf0cd2f878e50628a28e5a0bb689e658", size = 2566006, upload-time = "2026-07-01T11:56:02.143Z" }, + { url = "https://files.pythonhosted.org/packages/30/88/707027ba09942dfa2c28759b5c222d769290a41c6d20ea60ec250801941f/pillow-12.3.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:e9871b1ffbfa9656b60aeee92ed5136a5742696006fa322b29ea3d8da0ecc9cf", size = 5352509, upload-time = "2026-07-01T11:56:04.2Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6d/00352fa25332c2569cd387851f568cc5a4b75a9adbfb37ac4fbce4c02eec/pillow-12.3.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:53aa02d20d10c3d814d536aa4e5ac9b84ca0ff5a88377963b085ad6822f93e64", size = 4783167, upload-time = "2026-07-01T11:56:06.631Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/9e049dfa21af7c22427275720e2490267ba8138120add5c4c574deb69782/pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e", size = 6329237, upload-time = "2026-07-01T11:56:08.868Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/cf6eeaae8d0fce8dd390a33437cf68c5d5bd73834a2bc6e2f14efda0ab45/pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777", size = 6997047, upload-time = "2026-07-01T11:56:11.379Z" }, + { url = "https://files.pythonhosted.org/packages/1e/69/dbf769bdd55f48bf5733cac28edc6364ffaa072ec9ba336266e4fe66be55/pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1", size = 6400440, upload-time = "2026-07-01T11:56:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e1/ffc9cfc2eea0d178da8018e18e959301ad9d6bc9f3edb7181e748a474b97/pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9", size = 7105895, upload-time = "2026-07-01T11:56:16.575Z" }, + { url = "https://files.pythonhosted.org/packages/18/f0/a5595c1e8c3ae44b9828cb2f0fa8155e5095ef04d6327b8f61cf44a3df85/pillow-12.3.0-cp315-cp315t-win32.whl", hash = "sha256:1657923d2d45afb66526e5b933e5b3052e6bdea196c90d3abb2424e18c77dae8", size = 6474384, upload-time = "2026-07-01T11:56:18.855Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/62bcd9f844984c5938d3b05264a61d797a29d3e0812341a8204af70bbdee/pillow-12.3.0-cp315-cp315t-win_amd64.whl", hash = "sha256:8cd2f7bdda092d99c9fc2fb7391354f306d01443d22785d0cbfafa2e2c8bb418", size = 7243537, upload-time = "2026-07-01T11:56:21.214Z" }, + { url = "https://files.pythonhosted.org/packages/3d/68/1f3066acedf37673694a7141381d8f811ae97f30d34413d236abe7d489f1/pillow-12.3.0-cp315-cp315t-win_arm64.whl", hash = "sha256:06ff022112bc9cbf83b60f8e028d94ad87b60621706487e65f673de61610ab59", size = 2567491, upload-time = "2026-07-01T11:56:23.506Z" }, + { url = "https://files.pythonhosted.org/packages/75/18/2e8b40223153ccbc60df07f9e8928dc0c76202aa4e55ae9f53962b6510d6/pillow-12.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b3c777e849237620b022f7f297dd67705f9f5cf1685f09f02e46f93e92725468", size = 5302510, upload-time = "2026-07-01T11:56:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/46/3e/51fabf59d5ab801ceab709453d3ab6b180083496579549de4c45ced6528a/pillow-12.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:b343699e8308bdc51978310e1c959c584e7869cc8c40780058c87da7781a1e94", size = 4736058, upload-time = "2026-07-01T11:56:28.041Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/22fe9384b7949e25fb1293bcfc84fb82590ff4ea6b37c95b24d26d793d86/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbd139c8447d25dd750ab79ee274cc5e1fe80fc56340ab10b18a195e1b6eca3e", size = 5237776, upload-time = "2026-07-01T11:56:30.263Z" }, + { url = "https://files.pythonhosted.org/packages/08/14/f6ba68107680ffa74b39985f3f30884e41318fbc4250caa423c79b4788bb/pillow-12.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e7e480451b9fa137494bccd3a7d69adbe8ac65a87d97be61e11f1b1050a5bac3", size = 5860358, upload-time = "2026-07-01T11:56:32.68Z" }, + { url = "https://files.pythonhosted.org/packages/36/54/0169bc772ec491108b62f644f8ecf1fe5d8ae5ebafde2ee2142210166903/pillow-12.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:04f01d28a6aaff387bf842a13be313df23ba0597a44f1a976c9feb3c6ff4711a", size = 7231786, upload-time = "2026-07-01T11:56:35.046Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -1135,6 +2603,145 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "propcache" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/44/c87281c333769159c50594f22610f77398a47ccbfbbf23074e744e86f87c/propcache-0.5.2.tar.gz", hash = "sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427", size = 50208, upload-time = "2026-05-08T21:02:12.199Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/f1/8a8cc1c2c7e7934ab77e0163414f736fadbc0f5e8dd9673b952355ac175b/propcache-0.5.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78", size = 90744, upload-time = "2026-05-08T20:59:45.799Z" }, + { url = "https://files.pythonhosted.org/packages/c2/f4/651b1225e976bd1a2ba5cfba0c29d096581c2636b437e3a9a7ab6276270a/propcache-0.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959", size = 52033, upload-time = "2026-05-08T20:59:47.408Z" }, + { url = "https://files.pythonhosted.org/packages/15/a8/8ede85d6aa1f79fc7dc2f8fd2c8d65920b8272c3892903c8a1affde48cfb/propcache-0.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7", size = 52754, upload-time = "2026-05-08T20:59:49.202Z" }, + { url = "https://files.pythonhosted.org/packages/7d/fe/b3551b41bbc2f5b5bb088fc6920567cd43101253e68fbaa261339eb96fe1/propcache-0.5.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511", size = 57573, upload-time = "2026-05-08T20:59:50.778Z" }, + { url = "https://files.pythonhosted.org/packages/83/27/ab851ebd1b7172e3e161f5f8d39e315d54a91bea246f01f4d872d3376aef/propcache-0.5.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660", size = 60645, upload-time = "2026-05-08T20:59:52.227Z" }, + { url = "https://files.pythonhosted.org/packages/95/7d/466b3d18022e9897cbda9c735c493c5bd747d7a4c6f5ea1480b4cec434b6/propcache-0.5.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66", size = 61563, upload-time = "2026-05-08T20:59:53.866Z" }, + { url = "https://files.pythonhosted.org/packages/27/1b/16ab7f2cf2041da2f60d156ba64c2484eadf9168075b4ff43c3ef60045af/propcache-0.5.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b", size = 58888, upload-time = "2026-05-08T20:59:55.457Z" }, + { url = "https://files.pythonhosted.org/packages/0a/67/bb777ffd907633563bf35fd859c4ce97b0512c32f4633cf5d1eb7c33512b/propcache-0.5.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67", size = 59253, upload-time = "2026-05-08T20:59:57.075Z" }, + { url = "https://files.pythonhosted.org/packages/b9/42/64f8d90b73fd9cdc1499b48057ff6d9cd2a98a25734c9bb62ecf07e87061/propcache-0.5.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f", size = 57558, upload-time = "2026-05-08T20:59:58.602Z" }, + { url = "https://files.pythonhosted.org/packages/eb/02/dba5bc03c9041f2092ea55a449caf5dfe68352c6654511b29ba0654ddb69/propcache-0.5.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c", size = 55007, upload-time = "2026-05-08T20:59:59.837Z" }, + { url = "https://files.pythonhosted.org/packages/14/c0/43f649c7aa2a77a3b100d84e9dea3a483120ecb608bfe36ce49eaff517fe/propcache-0.5.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0", size = 60355, upload-time = "2026-05-08T21:00:01.144Z" }, + { url = "https://files.pythonhosted.org/packages/83/c0/435dafd27f1cb4a495381dae60e25883ccfe4020bb72818e8184c1678092/propcache-0.5.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6", size = 59057, upload-time = "2026-05-08T21:00:02.401Z" }, + { url = "https://files.pythonhosted.org/packages/53/ae/6e292df9135d659944e96cb3389258e4a663e5b2b5f6c217ef0ddc8d2f73/propcache-0.5.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27", size = 61938, upload-time = "2026-05-08T21:00:03.638Z" }, + { url = "https://files.pythonhosted.org/packages/0b/42/314ebc50d8159055411fd6b0bda322ff510e4b1f7d2e4927940ad0f6af20/propcache-0.5.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f", size = 59731, upload-time = "2026-05-08T21:00:04.881Z" }, + { url = "https://files.pythonhosted.org/packages/b8/9b/2da6dee38871c3c8772fabc2758325a5c9077d6d18c597737dc04dd884cd/propcache-0.5.2-cp311-cp311-win32.whl", hash = "sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0", size = 38966, upload-time = "2026-05-08T21:00:06.511Z" }, + { url = "https://files.pythonhosted.org/packages/42/4e/f17363fb58c0afe05b067361cb6d86ed2d29de6506779a27547c4d183075/propcache-0.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82", size = 42135, upload-time = "2026-05-08T21:00:08.088Z" }, + { url = "https://files.pythonhosted.org/packages/c6/eb/6af6685077d22e8b33358d3c548e3282706a0b3cd85044ffba4e5dd08e3b/propcache-0.5.2-cp311-cp311-win_arm64.whl", hash = "sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab", size = 38381, upload-time = "2026-05-08T21:00:09.692Z" }, + { url = "https://files.pythonhosted.org/packages/4a/cb/e27bc2b2737a0bb49962b275efa051e8f1c35a936df7d5139b6b658b7dc9/propcache-0.5.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba", size = 95887, upload-time = "2026-05-08T21:00:11.277Z" }, + { url = "https://files.pythonhosted.org/packages/e6/13/b8ae04c59392f8d11c6cd9fb4011d1dc7c86b81225c770280300e259ffe1/propcache-0.5.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a", size = 54654, upload-time = "2026-05-08T21:00:12.604Z" }, + { url = "https://files.pythonhosted.org/packages/2c/7d/49777a3e20b55863d4794384a38acd460c04157b0a00f8602b0d508b8431/propcache-0.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf", size = 55190, upload-time = "2026-05-08T21:00:13.935Z" }, + { url = "https://files.pythonhosted.org/packages/44/c7/085d0cd63062e84044e3f05797749c3f8e3938ff3aeb0eb2f69d43fafc91/propcache-0.5.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144", size = 59995, upload-time = "2026-05-08T21:00:15.526Z" }, + { url = "https://files.pythonhosted.org/packages/9c/42/32cf8e3009e92b2645cf1e944f701e8ea4e924dffde1ee26db860bcbf7e4/propcache-0.5.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9", size = 63422, upload-time = "2026-05-08T21:00:16.824Z" }, + { url = "https://files.pythonhosted.org/packages/9e/1b/f112433f99fc979431b87a39ef169e3f8df070d99a72792c56d6937ac48b/propcache-0.5.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42", size = 64342, upload-time = "2026-05-08T21:00:18.362Z" }, + { url = "https://files.pythonhosted.org/packages/14/15/5574111ae50dd6e879456888c0eadd4c5a869959775854e18e18a6b345f3/propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476", size = 61639, upload-time = "2026-05-08T21:00:19.692Z" }, + { url = "https://files.pythonhosted.org/packages/cc/da/4d775080b1490c0ae604acda868bd71aabe3a89ed16f2aa4339eb8a283e7/propcache-0.5.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba", size = 61588, upload-time = "2026-05-08T21:00:21.155Z" }, + { url = "https://files.pythonhosted.org/packages/04/ac/f076982cbe2195ee9cf32de5a1e46951d9fb399fc207f390562dd0fd8fb2/propcache-0.5.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a", size = 60029, upload-time = "2026-05-08T21:00:22.713Z" }, + { url = "https://files.pythonhosted.org/packages/70/60/189be62e0dd898dce3b331e1b8c7a543cd3a405ac0c81fe8ee8a9d5d77e1/propcache-0.5.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64", size = 56774, upload-time = "2026-05-08T21:00:24.001Z" }, + { url = "https://files.pythonhosted.org/packages/ea/9e/93377b9c7939c1ffae98f878dee955efadfd638078bc86dbc21f9d52f651/propcache-0.5.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913", size = 63532, upload-time = "2026-05-08T21:00:25.545Z" }, + { url = "https://files.pythonhosted.org/packages/14/f9/590ef6cfb9b8028d516d287812ece32bb0bc5f11fbb9c8bf6b2e6313fec8/propcache-0.5.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1", size = 61592, upload-time = "2026-05-08T21:00:27.186Z" }, + { url = "https://files.pythonhosted.org/packages/b4/5e/70958b3034c297a630bba2f17ca7abc2d5f39a803ad7e370ab79d1ecd022/propcache-0.5.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33", size = 64788, upload-time = "2026-05-08T21:00:28.8Z" }, + { url = "https://files.pythonhosted.org/packages/12/fd/77fe5936d8c3086ca9048f7f415f122ed82e53884a9ec193646b42deef06/propcache-0.5.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a", size = 62514, upload-time = "2026-05-08T21:00:30.098Z" }, + { url = "https://files.pythonhosted.org/packages/cf/74/66bd798b5b3be70aa1b391f5cc9d6a0a5532d7fd3b19ec0b213e72e6ad9d/propcache-0.5.2-cp312-cp312-win32.whl", hash = "sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031", size = 39018, upload-time = "2026-05-08T21:00:31.622Z" }, + { url = "https://files.pythonhosted.org/packages/61/7c/5c0d34aa3024694d6dcb9271cdbdd08c4e47c1c0ad95ec7e7bc74cdea145/propcache-0.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42", size = 42322, upload-time = "2026-05-08T21:00:32.918Z" }, + { url = "https://files.pythonhosted.org/packages/4d/91/875812f1a3feb20ceba818ef39fbe4d92f1081e04ac815c822496d0d038b/propcache-0.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84", size = 38172, upload-time = "2026-05-08T21:00:35.124Z" }, + { url = "https://files.pythonhosted.org/packages/c5/09/f049e45385503fe67db75a6b6186a7b9f0c3930366dc960522c312a825b1/propcache-0.5.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a", size = 94457, upload-time = "2026-05-08T21:00:36.355Z" }, + { url = "https://files.pythonhosted.org/packages/6b/65/83d1d05655baf63113731bd5a1008435e14f8d1e5a06cbe4ec5b23ad7a31/propcache-0.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117", size = 53835, upload-time = "2026-05-08T21:00:38.072Z" }, + { url = "https://files.pythonhosted.org/packages/a9/12/a6ba6482bb5ea3260c000c9b20881c95fa11c6b30173715668259f844ed7/propcache-0.5.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098", size = 54545, upload-time = "2026-05-08T21:00:39.319Z" }, + { url = "https://files.pythonhosted.org/packages/a9/19/7fa086f5764c59ec8a8e157cd93aa8497acc00aba9dcdec56bfffb32602d/propcache-0.5.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4", size = 59886, upload-time = "2026-05-08T21:00:40.621Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e4/5d7663dc8235956c8f5281698a3af1d351d8820341ddd890f59d9a9127f2/propcache-0.5.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e", size = 63261, upload-time = "2026-05-08T21:00:41.775Z" }, + { url = "https://files.pythonhosted.org/packages/4a/4a/15a03adee24d6350da4292caeac44c34c033d2afe5e87eb370f38854560f/propcache-0.5.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7", size = 64184, upload-time = "2026-05-08T21:00:43.018Z" }, + { url = "https://files.pythonhosted.org/packages/8b/c6/979176efdaa3d239e36d503d5af63a0a773b36662ed8f52e5b6a6d9fd40e/propcache-0.5.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d", size = 61534, upload-time = "2026-05-08T21:00:44.507Z" }, + { url = "https://files.pythonhosted.org/packages/c8/22/63e8cd1bae4c2d2be6493b6b7d10566ddafad88137cfbc99964a1119853c/propcache-0.5.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a", size = 61500, upload-time = "2026-05-08T21:00:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/60/5a/28e5d9acbac1cc9ccb67045e8c1b943aa8d79fdf39c93bd73cacd68008ea/propcache-0.5.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2", size = 59994, upload-time = "2026-05-08T21:00:47.093Z" }, + { url = "https://files.pythonhosted.org/packages/f3/40/db650677f554a95b9c01a7c9d93d629e93a15562f5deb4573c9ee136fed2/propcache-0.5.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa", size = 56884, upload-time = "2026-05-08T21:00:48.376Z" }, + { url = "https://files.pythonhosted.org/packages/80/45/70b39b89516ff8b96bf732fa6fded8cef20f293cb1508690101c3c07ec51/propcache-0.5.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853", size = 63464, upload-time = "2026-05-08T21:00:49.954Z" }, + { url = "https://files.pythonhosted.org/packages/f9/e2/fa59d3a89eac5534293124af4f1d0d0ada091ce4a0ab4610ce03fd2bdd8d/propcache-0.5.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a", size = 61588, upload-time = "2026-05-08T21:00:51.281Z" }, + { url = "https://files.pythonhosted.org/packages/0b/97/efb547a55c4bc7381cfb202d6a2239ac621045277bc1ea5dfd3a7f0516c0/propcache-0.5.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704", size = 64667, upload-time = "2026-05-08T21:00:52.602Z" }, + { url = "https://files.pythonhosted.org/packages/92/56/f5c7d9b4b7595d5127da38974d791b2153f3d1eae6c674af3583ace92ad3/propcache-0.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4", size = 62463, upload-time = "2026-05-08T21:00:54.303Z" }, + { url = "https://files.pythonhosted.org/packages/bd/3b/484a3a65fc9f9f60c41dcd17b428bace5389544e2c680994534a20755066/propcache-0.5.2-cp313-cp313-win32.whl", hash = "sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d", size = 38621, upload-time = "2026-05-08T21:00:55.808Z" }, + { url = "https://files.pythonhosted.org/packages/1c/fd/3f0f10dba4dabad3bf53102be007abf55481067952bde0fdddff439e7c61/propcache-0.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757", size = 41649, upload-time = "2026-05-08T21:00:57.061Z" }, + { url = "https://files.pythonhosted.org/packages/90/ec/6ce619cc32bb500a482f811f9cd509368b4e58e638d13f2c68f370d6b475/propcache-0.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f", size = 37636, upload-time = "2026-05-08T21:00:58.646Z" }, + { url = "https://files.pythonhosted.org/packages/1b/82/c1d268bbbf2ef981c5bf0fbbe746db617c66e3bcefe431a1aa8943fbe23a/propcache-0.5.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d", size = 98872, upload-time = "2026-05-08T21:00:59.889Z" }, + { url = "https://files.pythonhosted.org/packages/f4/d4/52c871e73e864e6b34c0e2d58ac1ec5ccd149497ddc7ad2137ae98323a35/propcache-0.5.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa", size = 56257, upload-time = "2026-05-08T21:01:01.195Z" }, + { url = "https://files.pythonhosted.org/packages/67/f0/9b90ca2a210b3d09bcfcd96ecd0f55545c091535abce2a45de2775cfd357/propcache-0.5.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94", size = 56696, upload-time = "2026-05-08T21:01:02.941Z" }, + { url = "https://files.pythonhosted.org/packages/9d/0e/6e9d4ba07c8e56e21ddec1e75f12148142b21ca83a51871babce095334f4/propcache-0.5.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164", size = 62378, upload-time = "2026-05-08T21:01:04.475Z" }, + { url = "https://files.pythonhosted.org/packages/65/19/c10badaa463dde8a27ce884f8ee2ec37e6035b7c9f5ff0c8f74f06f08dac/propcache-0.5.2-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f", size = 65283, upload-time = "2026-05-08T21:01:05.959Z" }, + { url = "https://files.pythonhosted.org/packages/b0/b6/93bea99ca80e19cef6512a8580e5b7857bbe09422d9daa7fd4ef5723306c/propcache-0.5.2-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c", size = 66616, upload-time = "2026-05-08T21:01:07.228Z" }, + { url = "https://files.pythonhosted.org/packages/83/e4/5c7462e50625f051f37fb38b8224f7639f667184bbd34424ec83819bb1b7/propcache-0.5.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc", size = 63773, upload-time = "2026-05-08T21:01:08.514Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b6/99238894047b13c823be25027e736626cd414a52a5e30d2c3347c2733529/propcache-0.5.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f", size = 63664, upload-time = "2026-05-08T21:01:09.874Z" }, + { url = "https://files.pythonhosted.org/packages/85/1e/a3a1a63116a2b8edb415a8bb9a6f0c34bd03830b1e18e8ce2904e1dc1cf4/propcache-0.5.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb", size = 62643, upload-time = "2026-05-08T21:01:11.132Z" }, + { url = "https://files.pythonhosted.org/packages/e4/03/893cf147de2fc6543c5eaa07ad833170e7e2a2385725bbebe8c0503723bb/propcache-0.5.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751", size = 59595, upload-time = "2026-05-08T21:01:12.387Z" }, + { url = "https://files.pythonhosted.org/packages/86/3b/04c1a2e12c57766568ba75ba72b3bf2042818d4c1425fab6fc07155c7cff/propcache-0.5.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836", size = 65711, upload-time = "2026-05-08T21:01:13.676Z" }, + { url = "https://files.pythonhosted.org/packages/1c/34/80f8d0099f8d6bacc4de1624c85672681c8cd1149ca2da0e38fd120b817f/propcache-0.5.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f", size = 64247, upload-time = "2026-05-08T21:01:14.936Z" }, + { url = "https://files.pythonhosted.org/packages/f3/1a/8b08f3a5f1037e9e370c55883ceeeee0f6dd0416fb2d2d67b8bfc91f2a79/propcache-0.5.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55", size = 67102, upload-time = "2026-05-08T21:01:16.281Z" }, + { url = "https://files.pythonhosted.org/packages/34/68/8bdb7bb7756d76e005490649d10e4a8369e610c74d619f71e1aedf889e9c/propcache-0.5.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568", size = 64964, upload-time = "2026-05-08T21:01:17.57Z" }, + { url = "https://files.pythonhosted.org/packages/0a/aa/50fb0b5d3968b61a510926ff8b8465f1d6e976b3ab74496d7a4b9fc42515/propcache-0.5.2-cp313-cp313t-win32.whl", hash = "sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191", size = 42546, upload-time = "2026-05-08T21:01:18.946Z" }, + { url = "https://files.pythonhosted.org/packages/ae/4c/0ddbae64321bd4a95bcbfc19307238016b5b1fee645c84626c8d539e5b74/propcache-0.5.2-cp313-cp313t-win_amd64.whl", hash = "sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7", size = 46330, upload-time = "2026-05-08T21:01:20.162Z" }, + { url = "https://files.pythonhosted.org/packages/00/d9/9cddc8efb78d8af264c5ec9f6d10b62f57c515feda8d321595f56010fb23/propcache-0.5.2-cp313-cp313t-win_arm64.whl", hash = "sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96", size = 40521, upload-time = "2026-05-08T21:01:21.399Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ea/23ee535d90ce8bcc465a3028eb3cc0ce3bd1005f4bb27710b30587de798d/propcache-0.5.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999", size = 94662, upload-time = "2026-05-08T21:01:22.683Z" }, + { url = "https://files.pythonhosted.org/packages/b5/06/c5a52f419b5d8972f8d46a7577476090d8e3263ff589ce40b5ca4968d5be/propcache-0.5.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e", size = 53928, upload-time = "2026-05-08T21:01:23.986Z" }, + { url = "https://files.pythonhosted.org/packages/63/b1/4260d67d6bd85e58a66b72d54ce15d5de789b6f3870cc6bedf8ff9667401/propcache-0.5.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539", size = 54650, upload-time = "2026-05-08T21:01:25.305Z" }, + { url = "https://files.pythonhosted.org/packages/70/06/2f46c318e3307cd7a6a7481def374ce838c0fe20084b39dd54b0879d0e99/propcache-0.5.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e", size = 59912, upload-time = "2026-05-08T21:01:26.545Z" }, + { url = "https://files.pythonhosted.org/packages/4c/29/fe1aebec2ce57ab985a9c382bded1124431f85078113aa222c5d278430d4/propcache-0.5.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979", size = 63300, upload-time = "2026-05-08T21:01:27.937Z" }, + { url = "https://files.pythonhosted.org/packages/b4/18/2334b26768b6c82be8c69e83671b767d5ef426aa09b0cba6c2ea47816774/propcache-0.5.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80", size = 64208, upload-time = "2026-05-08T21:01:29.484Z" }, + { url = "https://files.pythonhosted.org/packages/2b/76/7f1bfd6afff4c5e38e36a3c6d68eb5f4b7311ea80baf693db78d95b603c4/propcache-0.5.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825", size = 61633, upload-time = "2026-05-08T21:01:31.068Z" }, + { url = "https://files.pythonhosted.org/packages/c4/46/b3ff8aba2b4953a3e50de2cf72f1b5748b8eca93b15f3dc2c84339084c09/propcache-0.5.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39", size = 61724, upload-time = "2026-05-08T21:01:32.374Z" }, + { url = "https://files.pythonhosted.org/packages/c5/01/814cfcafbcff954f94c01cf30e097ddc88a076b5440fbcf4570753437d40/propcache-0.5.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4", size = 60069, upload-time = "2026-05-08T21:01:33.67Z" }, + { url = "https://files.pythonhosted.org/packages/da/68/5c6f7622d510cc666a300687e06fd060c1a43361c0c9b20d284f06d8096a/propcache-0.5.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5", size = 57099, upload-time = "2026-05-08T21:01:34.915Z" }, + { url = "https://files.pythonhosted.org/packages/55/27/9cb0b4c679124085327957d42521c99dba04c88c90c3e55a6f0b633ebccc/propcache-0.5.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702", size = 63391, upload-time = "2026-05-08T21:01:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/f0/9d/7258aaa5bdf60fc6f27591eef6fe52768cb0beda7140be477c8b12c9794a/propcache-0.5.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3", size = 61626, upload-time = "2026-05-08T21:01:37.545Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0d/41c602003e8a9b16fe1e7eadf62c7bfba9d5474370b24200bf48b315f45f/propcache-0.5.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5", size = 64781, upload-time = "2026-05-08T21:01:38.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f3/38e66b1856e9bd079deea015bc4a55f7767c0e4db2f7dcf69e7e680ba4ce/propcache-0.5.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4", size = 62570, upload-time = "2026-05-08T21:01:40.415Z" }, + { url = "https://files.pythonhosted.org/packages/95/ca/bbfe9b910ce57dde8bb4876b4520fc02a4e89497c10de26be936758a3aaa/propcache-0.5.2-cp314-cp314-win32.whl", hash = "sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0", size = 39436, upload-time = "2026-05-08T21:01:41.654Z" }, + { url = "https://files.pythonhosted.org/packages/61/d2/45c9defbaa1ea297035d9d4cce9e8f80daafbf19319c6007f157c6256ea9/propcache-0.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c", size = 42373, upload-time = "2026-05-08T21:01:43.041Z" }, + { url = "https://files.pythonhosted.org/packages/44/68/9ea5103f41d5217d7d6ec24db90018e23aebec070c3f9a6e54d12b841fd8/propcache-0.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0", size = 38554, upload-time = "2026-05-08T21:01:44.336Z" }, + { url = "https://files.pythonhosted.org/packages/8a/81/fadf555f42d3b762eea8a53950b0489fdc0aa9da5f8ed9e10ce0a4e01b48/propcache-0.5.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb", size = 99395, upload-time = "2026-05-08T21:01:45.883Z" }, + { url = "https://files.pythonhosted.org/packages/f5/c9/c61e134a686949cf7971af3a390148b1156f7be81c73bc0cd12c873e2d48/propcache-0.5.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078", size = 56653, upload-time = "2026-05-08T21:01:47.307Z" }, + { url = "https://files.pythonhosted.org/packages/cb/73/daf935ea7048ddd7ec8eec5345b4a40b619d2d178b3c0a0900796bc3c794/propcache-0.5.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa", size = 56914, upload-time = "2026-05-08T21:01:48.573Z" }, + { url = "https://files.pythonhosted.org/packages/79/9f/aba959b435ea18617edd7cf0a7ad0b9c574b8fc7e3d2cd55fb59cb255d33/propcache-0.5.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917", size = 62567, upload-time = "2026-05-08T21:01:49.903Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a1/859942de9a791ff42f6141736f5b37749b8f53e65edfa49638c67dd67e6a/propcache-0.5.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe", size = 65542, upload-time = "2026-05-08T21:01:51.204Z" }, + { url = "https://files.pythonhosted.org/packages/b5/61/315bc0fd6c0fc7f80a528b8afd209e5fc4a875ea79571b91b8f50f442907/propcache-0.5.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03", size = 66845, upload-time = "2026-05-08T21:01:52.539Z" }, + { url = "https://files.pythonhosted.org/packages/47/f7/9f8122e3132e8e354ac41975ef8f1099be7d5a16bc7ae562734e993665c0/propcache-0.5.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335", size = 63985, upload-time = "2026-05-08T21:01:53.847Z" }, + { url = "https://files.pythonhosted.org/packages/c8/54/c317819ec157cbf6f35df9df9657a6f82daf34d5faf15948b2f639c2192e/propcache-0.5.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285", size = 63999, upload-time = "2026-05-08T21:01:55.179Z" }, + { url = "https://files.pythonhosted.org/packages/5a/56/387e3f7dfce0a9233df41fb888aa1c30222cb4bbbf09537c02dd9bd85fe2/propcache-0.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837", size = 62779, upload-time = "2026-05-08T21:01:57.489Z" }, + { url = "https://files.pythonhosted.org/packages/a1/9c/596784cb5824ed61ee960d3f8655a3f0993e107c6e98ab6c818b7fb92ccb/propcache-0.5.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8", size = 59796, upload-time = "2026-05-08T21:01:58.736Z" }, + { url = "https://files.pythonhosted.org/packages/c2/3d/1a6cfa1726a48542c1e8784a0761421476a5b68e09b7f36bf95eb954aaba/propcache-0.5.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366", size = 66023, upload-time = "2026-05-08T21:02:00.228Z" }, + { url = "https://files.pythonhosted.org/packages/e4/0e/05fd6990369477076e4e280bcb970de760fddf0161a46e988bc95f7940ec/propcache-0.5.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56", size = 64448, upload-time = "2026-05-08T21:02:01.888Z" }, + { url = "https://files.pythonhosted.org/packages/cd/86/5f8da315a4309c62c10c0b2516b17492d5d3bbe1bb862b96604db67e2a37/propcache-0.5.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d", size = 67329, upload-time = "2026-05-08T21:02:03.484Z" }, + { url = "https://files.pythonhosted.org/packages/da/d3/3368efe79ab21f0cdf86ef49895811c9cc933131d4cde1f28a624e22e712/propcache-0.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2", size = 65172, upload-time = "2026-05-08T21:02:04.745Z" }, + { url = "https://files.pythonhosted.org/packages/d5/07/127e8b0bacfb325396196f9d976a22453049b89b9b2b08477cc3145faa44/propcache-0.5.2-cp314-cp314t-win32.whl", hash = "sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821", size = 43813, upload-time = "2026-05-08T21:02:06.025Z" }, + { url = "https://files.pythonhosted.org/packages/88/fb/46dad6c0ae49ed230ab1b16c890c2b6314e2403e6c412976f4a72d64a527/propcache-0.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370", size = 47764, upload-time = "2026-05-08T21:02:07.353Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c4/a47d0a63aa309d10d59ede6e9d4cff03a344a79d1f0f4cd0cd74997b53e0/propcache-0.5.2-cp314-cp314t-win_arm64.whl", hash = "sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6", size = 41140, upload-time = "2026-05-08T21:02:09.065Z" }, + { url = "https://files.pythonhosted.org/packages/3a/ed/1cdcab6ba3d6ab7feca11fc14f0eeea80755bb53ef4e892079f31b10a25f/propcache-0.5.2-py3-none-any.whl", hash = "sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe", size = 14036, upload-time = "2026-05-08T21:02:10.673Z" }, +] + +[[package]] +name = "psutil" +version = "7.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" }, + { url = "https://files.pythonhosted.org/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" }, + { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" }, + { url = "https://files.pythonhosted.org/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" }, + { url = "https://files.pythonhosted.org/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" }, + { url = "https://files.pythonhosted.org/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" }, + { url = "https://files.pythonhosted.org/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" }, + { url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" }, + { url = "https://files.pythonhosted.org/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" }, + { url = "https://files.pythonhosted.org/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" }, + { url = "https://files.pythonhosted.org/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" }, + { url = "https://files.pythonhosted.org/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" }, + { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, + { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, + { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, + { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, + { url = "https://files.pythonhosted.org/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" }, + { url = "https://files.pythonhosted.org/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" }, +] + [[package]] name = "pyarrow" version = "24.0.0" @@ -1343,6 +2950,66 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, ] +[[package]] +name = "pyqtgraph" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama" }, + { name = "numpy" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/36/4c242f81fdcbfa4fb62a5645f6af79191f4097a0577bd5460c24f19cc4ef/pyqtgraph-0.14.0-py3-none-any.whl", hash = "sha256:7abb7c3e17362add64f8711b474dffac5e7b0e9245abdf992e9a44119b7aa4f5", size = 1924755, upload-time = "2025-11-16T19:43:22.251Z" }, +] + +[[package]] +name = "pyside6" +version = "6.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyside6-addons" }, + { name = "pyside6-essentials" }, + { name = "shiboken6" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/a6/27ba5947ed48918f7b74b7c43a1e280aac069e36f25adeb4c9adfac835c4/pyside6-6.11.1-cp310-abi3-macosx_13_0_universal2.whl", hash = "sha256:537682c3b7530817203e667c1f5a2f00486b37bf52c52eeab438544c7a0917f6", size = 571921, upload-time = "2026-05-13T09:47:36.402Z" }, + { url = "https://files.pythonhosted.org/packages/d8/de/af89d71410c83b10654d86ff9aff2a4f87c30163658f1cc145242e222526/pyside6-6.11.1-cp310-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b1fc521ba2bb5109425ab8add06bddbdd524abcad06cfa012cc39a22a189feb2", size = 572102, upload-time = "2026-05-13T09:47:38.249Z" }, + { url = "https://files.pythonhosted.org/packages/b6/0e/d583bd3f7bf5046a4497b36f3902cfb64aa29554489a5a25c18e6b4ac0ac/pyside6-6.11.1-cp310-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:75f0005c3eb95c07cfb65522ec50d0815ac007a96482c21dc3cb4b4c04895d84", size = 572098, upload-time = "2026-05-13T09:47:39.44Z" }, + { url = "https://files.pythonhosted.org/packages/57/f2/d9d8ce1373dabb37e5919f63cd18446556079631d3f2eea3ada03c29f6b8/pyside6-6.11.1-cp310-abi3-win_amd64.whl", hash = "sha256:0968877ab1fb4ef3587a284da6fe05e8647ada56a6a3750b6395188e01f4aba6", size = 578377, upload-time = "2026-05-13T09:47:40.76Z" }, + { url = "https://files.pythonhosted.org/packages/96/02/a6057d8bd2bdb1940820fff2d627fdf4013148c9c57adf69fa40d3452ac3/pyside6-6.11.1-cp310-abi3-win_arm64.whl", hash = "sha256:acee467cb5f256cc47ebb9d815a054c1d8416da380c191b247a76d164aa3f805", size = 561765, upload-time = "2026-05-13T09:47:41.9Z" }, +] + +[[package]] +name = "pyside6-addons" +version = "6.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyside6-essentials" }, + { name = "shiboken6" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/6b/8bc94aff48b63f788f2d84e5467c12362d68906ba742c0942f46cb04c879/pyside6_addons-6.11.1-cp310-abi3-macosx_13_0_universal2.whl", hash = "sha256:54733c77f789bef5f03c6aff4ad3bec8b2eff021f0cfcbc53d5e6c250ded24f9", size = 331714589, upload-time = "2026-05-13T09:39:12.36Z" }, + { url = "https://files.pythonhosted.org/packages/dd/62/fb1428a523b2a4541e232aab50d9e789e6b4526f37fd9593452a7ea5b6b3/pyside6_addons-6.11.1-cp310-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:8e6c65fbd73a512d6f72cda8d8277444a85a34dc99dd1dae9c21d35b8671bb1f", size = 175063224, upload-time = "2026-05-13T09:39:34.185Z" }, + { url = "https://files.pythonhosted.org/packages/ee/9b/2ccd52f66db55c06de65d0501170a1935d04d64d0a230c0d892284a02ce3/pyside6_addons-6.11.1-cp310-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:bf1c6c4e954e5eba3d2a7c661ad4b9689e8f09c7f4a16bdf29713371d11af993", size = 170553429, upload-time = "2026-05-13T09:39:54.424Z" }, + { url = "https://files.pythonhosted.org/packages/9a/bd/8adc4d350b3b363f3dfc8fccdcf5bfed25f7e36c2fff30c64e106f4f1572/pyside6_addons-6.11.1-cp310-abi3-win_amd64.whl", hash = "sha256:0d13c4dfd671b050a48e4f8d8ddc724b7248f9c0437e7fc47fdf316278572923", size = 168816308, upload-time = "2026-05-13T09:40:13.541Z" }, + { url = "https://files.pythonhosted.org/packages/65/b7/9a840d97f0f0f04e372a87e205dd30ee285b4e3b021b188459a917c9dc76/pyside6_addons-6.11.1-cp310-abi3-win_arm64.whl", hash = "sha256:3494f480dee92f415be2f2d989c0b3f4755ac332b28045cbf4ba0f5c5a22ba37", size = 35759347, upload-time = "2026-05-13T09:40:21.199Z" }, +] + +[[package]] +name = "pyside6-essentials" +version = "6.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "shiboken6" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/da/10d9197e7370eb4fed8df5fc547b7548dec88e5c5949e2d450db4ae96feb/pyside6_essentials-6.11.1-cp310-abi3-macosx_13_0_universal2.whl", hash = "sha256:228de53c2bc26b07e5021fbe3614fc44ca08e4dab9999af08c2b389d2c239957", size = 110352945, upload-time = "2026-05-13T09:43:08.006Z" }, + { url = "https://files.pythonhosted.org/packages/5c/49/0e1237c4400bec7e335d2c4eeb49bc40d9fd88a9ac44ca9083ce1abdc308/pyside6_essentials-6.11.1-cp310-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:e3ef7027b41e4e55fadb56e3b3257dc8ee92154b639fe67fc4c8e05e9d976c60", size = 79908535, upload-time = "2026-05-13T09:43:24.836Z" }, + { url = "https://files.pythonhosted.org/packages/4c/c5/da4c5f23c6540ac5211a1f60177c8dee84b1bf40f2719479587ab8c60731/pyside6_essentials-6.11.1-cp310-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:a039b6da68a3a4b9d243217b2b98d475eed3f617159ef6be925badab53c11b0d", size = 78960051, upload-time = "2026-05-13T09:43:35.423Z" }, + { url = "https://files.pythonhosted.org/packages/64/0e/b663ecc96ca57b5c91b83b6615d6b174380b0faf30338125c26e053d6aa7/pyside6_essentials-6.11.1-cp310-abi3-win_amd64.whl", hash = "sha256:63311bd48e32c584599ab04b9ef7c324082374cd2c9fa533f978fb893bb47e40", size = 77549267, upload-time = "2026-05-13T09:43:44.92Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/eb6723faf5cb7fa581145da1c15f40d641b96e080f0491af2f1859fdeedb/pyside6_essentials-6.11.1-cp310-abi3-win_arm64.whl", hash = "sha256:11253ea52aabecefe9febddbbe78b43a824129e3af1cec98431028fba7fa954f", size = 57964512, upload-time = "2026-05-13T09:43:52.968Z" }, +] + [[package]] name = "pytest" version = "9.1.1" @@ -1364,7 +3031,7 @@ name = "pytest-cov" version = "7.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "coverage", extra = ["toml"] }, + { name = "coverage", extra = ["toml"], marker = "extra == 'extra-8-cuperiod-dev'" }, { name = "pluggy" }, { name = "pytest" }, ] @@ -1373,6 +3040,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, ] +[[package]] +name = "pytest-qt" +version = "4.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pluggy" }, + { name = "pytest" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d3/61/8bdec02663c18bf5016709b909411dce04a868710477dc9b9844ffcf8dd2/pytest_qt-4.5.0.tar.gz", hash = "sha256:51620e01c488f065d2036425cbc1cbcf8a6972295105fd285321eb47e66a319f", size = 128702, upload-time = "2025-07-01T17:24:39.889Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/d0/8339b888ad64a3d4e508fed8245a402b503846e1972c10ad60955883dcbb/pytest_qt-4.5.0-py3-none-any.whl", hash = "sha256:ed21ea9b861247f7d18090a26bfbda8fb51d7a8a7b6f776157426ff2ccf26eff", size = 37214, upload-time = "2025-07-01T17:24:38.226Z" }, +] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -1394,6 +3075,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, ] +[[package]] +name = "pytz" +version = "2026.3.post1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/48/fb042503b6ca6cd271261dc559fd6432f7d8c713153e9ec5c591af4dfc1c/pytz-2026.3.post1.tar.gz", hash = "sha256:2211d3fcf9a797d3405cac96ac7f61d80e6a644f72a3309607282fe8a2010c5d", size = 319745, upload-time = "2026-07-25T15:12:07.385Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/7b/39c34ca613b0b198cb866466651b26b045e2009864c5183c979a3b83f383/pytz-2026.3.post1-py2.py3-none-any.whl", hash = "sha256:dd95840dd199baea12d9cc096a1d452caa6596a1c1e4b5f3dbd1541855d5e815", size = 508283, upload-time = "2026-07-25T15:12:05.782Z" }, +] + [[package]] name = "pyyaml" version = "6.0.3" @@ -1516,12 +3206,17 @@ name = "scipy" version = "1.17.1" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version < '3.12' and sys_platform == 'win32'", - "python_full_version < '3.12' and sys_platform == 'emscripten'", - "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", ] dependencies = [ - { name = "numpy", marker = "python_full_version < '3.12'" }, + { name = "numpy", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } wheels = [ @@ -1592,18 +3287,28 @@ name = "scipy" version = "1.18.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15' and sys_platform == 'win32'", - "python_full_version >= '3.15' and sys_platform == 'emscripten'", - "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'emscripten'", - "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", ] dependencies = [ - { name = "numpy", marker = "python_full_version >= '3.12'" }, + { name = "numpy", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a7/25/c2700dfaf6442b4effaa91af24ebce5dc9d31bb4a69706313aae70d72cd0/scipy-1.18.0.tar.gz", hash = "sha256:67b2ad2ad54c72ca6d04975a9b2df8c3638c34ddd5b28738e94fc2b57929d378", size = 30774447, upload-time = "2026-06-19T15:01:43.456Z" } wheels = [ @@ -1649,6 +3354,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/19/969dc072906c84dd0a3b05dcf57ea750936087d7873549e408b35cfc3f97/scipy-1.18.0-cp314-cp314t-win_arm64.whl", hash = "sha256:368e0a705903c466aa5f08eefb39e6b1b6b2d659e7352a31fd9e2438365be0f8", size = 25279661, upload-time = "2026-06-19T15:01:40.817Z" }, ] +[[package]] +name = "setuptools" +version = "84.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/44/f5da03a8ef95d369145c5bb53050e7877c9f3d312e128605fd9504829143/setuptools-84.0.0.tar.gz", hash = "sha256:f4695c21257f0d9b537ec2692c941d02ee143b7cc1276941349a546573b2ef73", size = 1168449, upload-time = "2026-08-08T18:27:58.365Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl", hash = "sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670", size = 818216, upload-time = "2026-08-08T18:27:56.719Z" }, +] + [[package]] name = "shellingham" version = "1.5.4" @@ -1658,6 +3372,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] +[[package]] +name = "shiboken6" +version = "6.11.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/f3/f2b63df0251e7cd3172ea28e32ede52739de9566bcefcd0178681538ac81/shiboken6-6.11.1-cp310-abi3-macosx_13_0_universal2.whl", hash = "sha256:1a16867f103ef1c662a5f09dfed03273a9f81688b174555162c58e83650a3f02", size = 476874, upload-time = "2026-05-13T09:47:01.091Z" }, + { url = "https://files.pythonhosted.org/packages/c7/9b/e0355d8897b5c150770f1d95718aad17d432fcc9c035c04f3f58427d4693/shiboken6-6.11.1-cp310-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:9a8bccfafc8805254cabcfa1edfaf55cd52889f4998c91ad0d9a4433fb1bcdbe", size = 272222, upload-time = "2026-05-13T09:47:02.653Z" }, + { url = "https://files.pythonhosted.org/packages/57/d5/dd4f1defed400be03340f2ede34b61f846776650b4e7ed9ebaf4c71979a2/shiboken6-6.11.1-cp310-abi3-manylinux_2_39_aarch64.whl", hash = "sha256:1bd2f4314414df2d122d9f646e03b731bc6d6b5f77a5f53f99a4fe4e97d84e6f", size = 270350, upload-time = "2026-05-13T09:47:04.02Z" }, + { url = "https://files.pythonhosted.org/packages/52/b5/3f6fb2ee65b534193fb4ef713dd619dc31dadff5d12c16979a7699ad58be/shiboken6-6.11.1-cp310-abi3-win_amd64.whl", hash = "sha256:c2c6863aa80ec18c0f82cea3417837b279cdc60024ac17123461dc9042577df7", size = 1223647, upload-time = "2026-05-13T09:47:05.924Z" }, + { url = "https://files.pythonhosted.org/packages/98/d1/f15ca0e1666faae02c945f48e745ea35f8fcd8243b176109b4e2c4251f47/shiboken6-6.11.1-cp310-abi3-win_arm64.whl", hash = "sha256:7c8d9af17db4495d4fa5b1c393f218311c4855546b9dfa6a0bd21bcd66b55e9d", size = 1784170, upload-time = "2026-05-13T09:47:07.617Z" }, +] + [[package]] name = "six" version = "1.17.0" @@ -1699,28 +3425,33 @@ name = "sphinx" version = "9.0.4" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version < '3.12' and sys_platform == 'win32'", - "python_full_version < '3.12' and sys_platform == 'emscripten'", - "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -dependencies = [ - { name = "alabaster", marker = "python_full_version < '3.12'" }, - { name = "babel", marker = "python_full_version < '3.12'" }, - { name = "colorama", marker = "python_full_version < '3.12' and sys_platform == 'win32'" }, - { name = "docutils", marker = "python_full_version < '3.12'" }, - { name = "imagesize", marker = "python_full_version < '3.12'" }, - { name = "jinja2", marker = "python_full_version < '3.12'" }, - { name = "packaging", marker = "python_full_version < '3.12'" }, - { name = "pygments", marker = "python_full_version < '3.12'" }, - { name = "requests", marker = "python_full_version < '3.12'" }, - { name = "roman-numerals", marker = "python_full_version < '3.12'" }, - { name = "snowballstemmer", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.12'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.12'" }, + "python_full_version < '3.12' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version < '3.12' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", +] +dependencies = [ + { name = "alabaster", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "babel", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "colorama", marker = "(python_full_version < '3.12' and sys_platform == 'win32') or (python_full_version >= '3.12' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "docutils", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "imagesize", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "jinja2", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "packaging", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "pygments", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "requests", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "roman-numerals", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "snowballstemmer", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/50/a8c6ccc36d5eacdfd7913ddccd15a9cee03ecafc5ee2bc40e1f168d85022/sphinx-9.0.4.tar.gz", hash = "sha256:594ef59d042972abbc581d8baa577404abe4e6c3b04ef61bd7fc2acbd51f3fa3", size = 8710502, upload-time = "2025-12-04T07:45:27.343Z" } wheels = [ @@ -1732,34 +3463,44 @@ name = "sphinx" version = "9.1.0" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.15' and sys_platform == 'win32'", - "python_full_version >= '3.15' and sys_platform == 'emscripten'", - "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'win32'", - "python_full_version == '3.14.*' and sys_platform == 'emscripten'", - "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", -] -dependencies = [ - { name = "alabaster", marker = "python_full_version >= '3.12'" }, - { name = "babel", marker = "python_full_version >= '3.12'" }, - { name = "colorama", marker = "python_full_version >= '3.12' and sys_platform == 'win32'" }, - { name = "docutils", marker = "python_full_version >= '3.12'" }, - { name = "imagesize", marker = "python_full_version >= '3.12'" }, - { name = "jinja2", marker = "python_full_version >= '3.12'" }, - { name = "packaging", marker = "python_full_version >= '3.12'" }, - { name = "pygments", marker = "python_full_version >= '3.12'" }, - { name = "requests", marker = "python_full_version >= '3.12'" }, - { name = "roman-numerals", marker = "python_full_version >= '3.12'" }, - { name = "snowballstemmer", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12'" }, - { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12'" }, + "python_full_version >= '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.15' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version == '3.14.*' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform == 'emscripten' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", + "python_full_version >= '3.12' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32' and extra != 'extra-8-cuperiod-dev' and extra != 'extra-8-cuperiod-lsdb'", +] +dependencies = [ + { name = "alabaster", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "babel", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "colorama", marker = "(python_full_version >= '3.12' and sys_platform == 'win32') or (python_full_version < '3.12' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform != 'win32' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "docutils", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "imagesize", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "jinja2", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "packaging", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "pygments", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "requests", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "roman-numerals", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "snowballstemmer", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-applehelp", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-devhelp", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-htmlhelp", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-jsmath", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-qthelp", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinxcontrib-serializinghtml", marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } wheels = [ @@ -1771,8 +3512,8 @@ name = "sphinx-basic-ng" version = "1.0.0b2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/98/0b/a866924ded68efec7a1759587a4e478aec7559d8165fac8b2ad1c0e774d6/sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9", size = 20736, upload-time = "2023-07-08T18:40:54.166Z" } wheels = [ @@ -1784,8 +3525,8 @@ name = "sphinx-copybutton" version = "0.5.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039, upload-time = "2023-04-14T08:10:22.998Z" } wheels = [ @@ -1797,8 +3538,8 @@ name = "sphinx-design" version = "0.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12'" }, - { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" }, + { name = "sphinx", version = "9.0.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "sphinx", version = "9.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, ] sdist = { url = "https://files.pythonhosted.org/packages/13/7b/804f311da4663a4aecc6cf7abd83443f3d4ded970826d0c958edc77d4527/sphinx_design-0.7.0.tar.gz", hash = "sha256:d2a3f5b19c24b916adb52f97c5f00efab4009ca337812001109084a740ec9b7a", size = 2203582, upload-time = "2026-01-19T13:12:53.297Z" } wheels = [ @@ -1859,6 +3600,42 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" }, ] +[[package]] +name = "supersmoother" +version = "0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/73/d7/44f69557f2685e80ef7d558b605b080cbb9ae9500c154e4105dbdddb017e/supersmoother-0.4.tar.gz", hash = "sha256:aeef4e1b00c32316d624ea7e3ac87c244bf2e59abbb6c042e7791f69ae0669cb", size = 233774, upload-time = "2017-05-06T03:15:23.08Z" } + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + +[[package]] +name = "tabulate" +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/46/58/8c37dea7bbf769b20d58e7ace7e5edfe65b849442b00ffcdd56be88697c6/tabulate-0.10.0.tar.gz", hash = "sha256:e2cfde8f79420f6deeffdeda9aaec3b6bc5abce947655d17ac662b126e48a60d", size = 91754, upload-time = "2026-03-04T18:55:34.402Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl", hash = "sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3", size = 39814, upload-time = "2026-03-04T18:55:31.284Z" }, +] + +[[package]] +name = "tblib" +version = "3.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/8a/14c15ae154895cc131174f858c707790d416c444fc69f93918adfd8c4c0b/tblib-3.2.2.tar.gz", hash = "sha256:e9a652692d91bf4f743d4a15bc174c0b76afc750fe8c7b6d195cc1c1d6d2ccec", size = 35046, upload-time = "2025-11-12T12:21:16.572Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/be/5d2d47b1fb58943194fb59dcf222f7c4e35122ec0ffe8c36e18b5d728f0b/tblib-3.2.2-py3-none-any.whl", hash = "sha256:26bdccf339bcce6a88b2b5432c988b266ebbe63a4e593f6b578b1d2e723d2b76", size = 12893, upload-time = "2025-11-12T12:21:14.407Z" }, +] + [[package]] name = "tomli" version = "2.4.1" @@ -1913,13 +3690,111 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, ] +[[package]] +name = "toolz" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/d6/114b492226588d6ff54579d95847662fc69196bdeec318eb45393b24c192/toolz-1.1.0.tar.gz", hash = "sha256:27a5c770d068c110d9ed9323f24f1543e83b2f300a687b7891c1a6d56b697b5b", size = 52613, upload-time = "2025-10-17T04:03:21.661Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl", hash = "sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8", size = 58093, upload-time = "2025-10-17T04:03:20.435Z" }, +] + +[[package]] +name = "torch" +version = "2.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cuda-bindings", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "cuda-toolkit", extra = ["cublas", "cudart", "cufft", "cufile", "cupti", "curand", "cusolver", "cusparse", "nvjitlink", "nvrtc", "nvtx"], marker = "sys_platform == 'linux' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx" }, + { name = "nvidia-cudnn-cu13", marker = "sys_platform == 'linux' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-cusparselt-cu13", marker = "sys_platform == 'linux' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-nccl-cu13", marker = "sys_platform == 'linux' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "nvidia-nvshmem-cu13", marker = "sys_platform == 'linux' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "setuptools" }, + { name = "sympy" }, + { name = "triton", marker = "(python_full_version < '3.15' and sys_platform == 'linux') or (python_full_version >= '3.15' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb') or (sys_platform != 'linux' and extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/fe/cba54dc58523434919b66f13a667e36e436deddd77ca519e96553617d4ec/torch-2.13.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:e76f9bcecc52b8ff711239a2f7547d5353df95878ab232f0773c1d95928b92f8", size = 111187938, upload-time = "2026-07-08T16:05:17.065Z" }, + { url = "https://files.pythonhosted.org/packages/c2/59/1e3160e18e12aa3038390efab3ce02b36a9d4d6a527ecdd8520dca2e68d8/torch-2.13.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:092790c696a760c729fd5722835f50b9d81fd7c8f141571f3f3cf4081a8f664c", size = 427199369, upload-time = "2026-07-08T16:04:51.054Z" }, + { url = "https://files.pythonhosted.org/packages/01/79/1f2d34ad7034ee1c7ffc1cf8bf0f8213af2a81df6ecdb3997ecec107c09d/torch-2.13.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:60fcdcb2f3876e21146cb4524ef06397d727ca9ad5f020818547e25075fe3cb7", size = 526574961, upload-time = "2026-07-08T16:04:07.075Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fd/0f2ce40f58aefbdb3392f9acce3c8171940943ae2d661f70558bfa73befb/torch-2.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:a0d8b11f16a48d60e2015d8213aa0390744cbebb98e58b62b3514dddc656e330", size = 122015870, upload-time = "2026-07-08T16:05:27.59Z" }, + { url = "https://files.pythonhosted.org/packages/c4/3a/ed0f4d4d1dcde03bced7aac9a28e800abcdc0cbd06b6775044c9fbd877b7/torch-2.13.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2fe228aba290d14b9f31b049be550dbd469c3fd3013d7a19705b30454da97027", size = 111213045, upload-time = "2026-07-08T16:05:22.997Z" }, + { url = "https://files.pythonhosted.org/packages/df/a9/f6a2a4d763ff1df02e9a64c477029db614295bc9367f4131223791ccc243/torch-2.13.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:572df8be8ffb4599c88cbd6a0726f1f854f4da65d2e3c09f0e2c2283333cd6d4", size = 427210998, upload-time = "2026-07-08T16:04:37.708Z" }, + { url = "https://files.pythonhosted.org/packages/f3/82/fea946351658e6534db52d2cc12bc53087cbf87f9440c5f180f367c1950b/torch-2.13.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:796633c4cdf0fe2cdced72d8f88f22e73dbcfce83132763162f6d4bff13b820b", size = 526605292, upload-time = "2026-07-08T16:04:22.81Z" }, + { url = "https://files.pythonhosted.org/packages/21/d6/e8f3c6f7e01f626f77259de9860d2a78bc84c40539e28e79b7e98b0bb659/torch-2.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:024c6cc0c1b085f2f91f20a3dc27b0471d021c31ce84b81be3afdc39f791fd9d", size = 122057313, upload-time = "2026-07-08T16:03:53.43Z" }, + { url = "https://files.pythonhosted.org/packages/0d/fa/c1c10b7aff4a9a3e8956d4f0a5f468fa6db7abc3208805719076772b4833/torch-2.13.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:33449899ce5496c1b84b4853179d94fd102028ae1407314d9fb956bb79e70d09", size = 111213743, upload-time = "2026-07-08T16:03:28.579Z" }, + { url = "https://files.pythonhosted.org/packages/11/18/9ecb37b56293a0be8d80f810bf672a72fe7e02f8b475d5ef1b9bf8a0d748/torch-2.13.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:1e09d6a722504957c694faceca843acde562786df1144ebcc5a74075ec7f6005", size = 427213008, upload-time = "2026-07-08T16:03:44.106Z" }, + { url = "https://files.pythonhosted.org/packages/d4/5a/7c50ba1b7b713d71d34669c6d13dab0a11531a3eceb0307a5162dbfec0f7/torch-2.13.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:a3a9a21312872af8a26950b2c15680335a386a1f56ed03e780653d78b9607e9e", size = 526602329, upload-time = "2026-07-08T16:03:12.649Z" }, + { url = "https://files.pythonhosted.org/packages/91/3d/e7adcc6aaf36961cd18f56cf8ad0f3058c3a5c84ccf391762176c94581b8/torch-2.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:49b58f1e2c52440abb6f17c28f0335fe6c6d01ad1a7f55b0183b81e4b34d64e6", size = 122057920, upload-time = "2026-07-08T16:03:01.808Z" }, + { url = "https://files.pythonhosted.org/packages/36/76/6dcc7f0c07052102dd36f83cbc5800842a909c8c3fbf1a7f8a5844954de9/torch-2.13.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d849b390e07d8d333ce8ecaf91b273c656c598379a19c9acf1318a883f6b391c", size = 111227066, upload-time = "2026-07-08T16:03:33.6Z" }, + { url = "https://files.pythonhosted.org/packages/e9/09/2c10e8cd0e00fa5d23c052df6ce467eaa7182399f5e0f824f1e4ff42ccae/torch-2.13.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:a3893dc2da0a972a8ca5d698c85a9f967559ac5f8ee1797b77408aa8734d073c", size = 427226309, upload-time = "2026-07-08T16:02:53.127Z" }, + { url = "https://files.pythonhosted.org/packages/76/c6/22c2102bbef14ca6a6cb4c20e42f088e49c5f812be4e160ae57502e325f9/torch-2.13.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:49f1ea385c754e54919408a9bb3b5a72b0b755bbe2c916c1d6f70afbec4908a2", size = 526614507, upload-time = "2026-07-08T16:02:16.441Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0c/7d1deb6bce5bc3e6042caf39100ac768eba3b9a098e1dddd16f75bd6489b/torch-2.13.0-cp314-cp314-win_amd64.whl", hash = "sha256:4f8573e3ce9ebcd53fe922f01077a6085ccdfbe5f12fd215883a9d87d7a744fd", size = 122051871, upload-time = "2026-07-08T16:03:23.521Z" }, + { url = "https://files.pythonhosted.org/packages/f4/ce/aa8b7f9949d32e0f2f624f342bc3b48112c1b8a130288465938bc83bcbf9/torch-2.13.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:c28def70706c2f9ecc752574766e8ae4da9b810ab6676b611166761a78a9f1e1", size = 111537025, upload-time = "2026-07-08T16:02:44.28Z" }, + { url = "https://files.pythonhosted.org/packages/69/d1/491e3a0389430946145888b0203f2b6a759ce2a61481b96a85c2da4f2ced/torch-2.13.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:31061ff56ed8fbf26c749806905aeb749ebeb819810fd5d52508aa5afd90dddc", size = 427219769, upload-time = "2026-07-08T16:02:31.18Z" }, + { url = "https://files.pythonhosted.org/packages/9a/1d/38006e045bf0a1fc28ef01e757c554e59e59a8770c284bc4f47b14e60441/torch-2.13.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:cc26eead4cf51d0b544e31e364dcf000846549c273bd148936fe9d24d29acb92", size = 526571320, upload-time = "2026-07-08T16:01:59.348Z" }, + { url = "https://files.pythonhosted.org/packages/56/94/655c91992a882bd5071aa0b5d22a07dbb130d801e872be97c0b627a7c693/torch-2.13.0-cp314-cp314t-win_amd64.whl", hash = "sha256:a7de8a313090dc5c7d7ba4bfe5c3be222528f9a4dba1acc83bddb1157360c4b8", size = 122306773, upload-time = "2026-07-08T16:02:39.832Z" }, +] + +[[package]] +name = "tornado" +version = "6.5.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/10/d3/343e5bb989d6515b1646cf3d40135d73f3d5e45339bded401b56cdac24dd/tornado-6.5.8.tar.gz", hash = "sha256:9452e1b208a8bd771e2cb1f2ff564985b9b214bdebbe622793e1799e0a6bd23f", size = 520493, upload-time = "2026-08-07T02:12:42.971Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/d5/007086fd8df5489338e204f65adce33fd4f21a4999dbb2b9cff2f897b5f4/tornado-6.5.8-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:cc6aa787d7cfab7c3d35189dc7a56fbd2399a569624c730c6b55b3d6531d0403", size = 449487, upload-time = "2026-08-07T02:12:28.682Z" }, + { url = "https://files.pythonhosted.org/packages/70/c8/5a24a99495903f594f6a199dd7beead1cbc0a13e2cb9102727bcaaf2a997/tornado-6.5.8-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9715b5eb79735b2bcd454ce216a9275b7c0470e64ea1bf5742f78b2f72b26eeb", size = 447649, upload-time = "2026-08-07T02:12:30.306Z" }, + { url = "https://files.pythonhosted.org/packages/6e/de/f2e733f386b85962d1b1dc82cd63d169b5b4580062b35397eac9244a41fe/tornado-6.5.8-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:547d63f450d570c14fe0e8db2cfb14c9bbd1c2503b4a6612586267955aa47b58", size = 450707, upload-time = "2026-08-07T02:12:31.95Z" }, + { url = "https://files.pythonhosted.org/packages/0b/94/20efeee9a01c141e9ac47c397f81679dfda24b32768fc4fff24e76d36c2c/tornado-6.5.8-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e2360a0ffbe145eca8af0b19cb7203d79b1a98dd4cccdd6b368f6f49c2e3808", size = 451677, upload-time = "2026-08-07T02:12:33.512Z" }, + { url = "https://files.pythonhosted.org/packages/42/ec/a96ccb8ccf0de2b7bc2c5fa1608a4803735018242e90c4882365a9fd418f/tornado-6.5.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5d242290bdf7ab3151bc1065fdd75c0dcc21cbc7b49f22a4c56329c2d6566d22", size = 451510, upload-time = "2026-08-07T02:12:35.346Z" }, + { url = "https://files.pythonhosted.org/packages/29/b5/93185859245ad3f00e62175f29607346788b696369347f0146e0421286bb/tornado-6.5.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7b94ff0e128fe0542f3bd331fb44d06260fc4ac16881545159f34ef08aad4195", size = 450917, upload-time = "2026-08-07T02:12:36.963Z" }, + { url = "https://files.pythonhosted.org/packages/97/cf/fe33cf062834487d34d1559746a4a12521033c22645b6d74d4bca702e018/tornado-6.5.8-cp39-abi3-win32.whl", hash = "sha256:67832909c4779c64942380cb5f044a5c6163d00831472d80e25e115de9917836", size = 451952, upload-time = "2026-08-07T02:12:38.512Z" }, + { url = "https://files.pythonhosted.org/packages/cb/e1/468ad54333e92ccb62627e62cb88e5fc14a2171daa67ed47b1b8542d5b86/tornado-6.5.8-cp39-abi3-win_amd64.whl", hash = "sha256:11881db6b7c168494be2c2d12e65931451bdf7ee718535418ae1d8855dd5a0ee", size = 452391, upload-time = "2026-08-07T02:12:39.971Z" }, + { url = "https://files.pythonhosted.org/packages/ad/3e/cd5e4f06e34cde33b8ef66cf36aa2b5ad46354cc1af7d2136bbe365fee1d/tornado-6.5.8-cp39-abi3-win_arm64.whl", hash = "sha256:68a7468c7e289f8514d7d664101753903217eff1bb6822c6b5994a0b5f5bcb26", size = 451411, upload-time = "2026-08-07T02:12:41.469Z" }, +] + +[[package]] +name = "tqdm" +version = "4.70.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/21/3b/6c24bec5be5e743ffd99576daa5cc077722fc7d5bbc00bd133fa0c698dc6/tqdm-4.70.0.tar.gz", hash = "sha256:55b0b0dbd97462d06ebee91e4dac24ed4d4702be82b24f07e6c1d27e08cea220", size = 795438, upload-time = "2026-07-27T11:33:15.271Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/1c/01bfd571a64e7f270e6bab5e33777debe0edc56759233ce84f27dec92d14/tqdm-4.70.0-py3-none-any.whl", hash = "sha256:7f585706bfddbdebf89daac705b2dfcc16890130727d3197ca62c732b4310953", size = 80184, upload-time = "2026-07-27T11:33:13.167Z" }, +] + +[[package]] +name = "triton" +version = "3.7.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/f9/19d842d06a08559534fa1eaab6ca551b1bcf40f06620bddec1babaa2772d/triton-3.7.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4a0e1cd4c4a76370ed74a8432a53cea28716827d19e40ffc732233e35ceb3f6", size = 184664887, upload-time = "2026-06-17T20:03:42.913Z" }, + { url = "https://files.pythonhosted.org/packages/cd/5e/fce69606f7f240297f163e25539906732b199530d486ce67ae319877e821/triton-3.7.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6744957e9fd610a29680ec2346057d0c86948ed3812468670719f391e94b44a5", size = 197701306, upload-time = "2026-06-17T19:53:13.673Z" }, + { url = "https://files.pythonhosted.org/packages/94/fa/f856e24deb462d5f18bd4b5a746957862ab9b6ee5834bda60605ec348366/triton-3.7.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9497f2e696ee368862a181a90b2dcc03ca978cc4f602abd67c7d81022a6988e1", size = 184692359, upload-time = "2026-06-17T20:03:48.288Z" }, + { url = "https://files.pythonhosted.org/packages/c4/6f/fb96d15db6f36d6eae4cafb998c2e0353bf59d7c4ea1662d7497f269134a/triton-3.7.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7e40869937a68206ec70d7f25bb7ec6433cb083f9135e1f36dbd318dc449a728", size = 197719725, upload-time = "2026-06-17T19:53:20.419Z" }, + { url = "https://files.pythonhosted.org/packages/00/42/c5089d4d9327fcd1e862c599cc2927f39418f84dd11a84cb2ccff9d4787a/triton-3.7.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cdbfc09d9ec58bc5e68321525653220de7515c199e7a8097a97c85e62b52cd0a", size = 184694629, upload-time = "2026-06-17T20:03:53.444Z" }, + { url = "https://files.pythonhosted.org/packages/07/42/2c3ac59253ae8892b6f307875263dd23dc875cdf732d3aea40d6d41fb7cb/triton-3.7.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:58c0e131da05134a2a4788ccbcc0c1105cf0f54c8e98f19e34cd465396dc15eb", size = 197729241, upload-time = "2026-06-17T19:53:27.801Z" }, + { url = "https://files.pythonhosted.org/packages/40/71/e01aa7ad573883ed9456f130226babdec70b005e098c4d6226a6238e761b/triton-3.7.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe4ea396a06171f1f1f58cbd39c70b09294398f7dd7c620939bab54ad6f934fa", size = 184705764, upload-time = "2026-06-17T20:03:59.064Z" }, + { url = "https://files.pythonhosted.org/packages/a4/09/5683146fda6a2b569deb78ccfd8fbfea8bfe55f726b081c0a6bb18dd6f28/triton-3.7.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2020153b08280415ec0da6607834e79166442147e78e144df06b508c75b186d2", size = 197729537, upload-time = "2026-06-17T19:53:35.516Z" }, + { url = "https://files.pythonhosted.org/packages/e9/f8/448220c3092019f9fdfab39ec47985968181d67da34b44f6a7f6280a5cbb/triton-3.7.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c58e4c61f0c73b5dba3b5d19b4a7093c32f90dc18b2a7f121a7c16ccd31107b7", size = 184814760, upload-time = "2026-06-17T20:04:04.984Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ac/229b7d4589d2e5937310e72c6d46e89599d16a4a12b479ffa1499fee8eb8/triton-3.7.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10ba85fa2cca4a2fbdeb36bf1cb082f2c252bda55bf9fccd74f65ec5bc647e68", size = 197824404, upload-time = "2026-06-17T19:53:42.772Z" }, +] + [[package]] name = "typer" version = "0.26.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-doc" }, - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32' or (extra == 'extra-8-cuperiod-dev' and extra == 'extra-8-cuperiod-lsdb')" }, { name = "rich" }, { name = "shellingham" }, ] @@ -1958,6 +3833,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" }, ] +[[package]] +name = "universal-pathlib" +version = "0.3.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fsspec" }, + { name = "pathlib-abc" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/6e/d997a70ee8f4c61f9a7e2f4f8af721cf072a3326848fc881b05187e52558/universal_pathlib-0.3.10.tar.gz", hash = "sha256:4487cbc90730a48cfb64f811d99e14b6faed6d738420cd5f93f59f48e6930bfb", size = 261110, upload-time = "2026-02-22T14:40:58.87Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/1a/5d9a402b39ec892d856bbdd9db502ff73ce28cdf4aff72eb1ce1d6843506/universal_pathlib-0.3.10-py3-none-any.whl", hash = "sha256:dfaf2fb35683d2eb1287a3ed7b215e4d6016aa6eaf339c607023d22f90821c66", size = 83528, upload-time = "2026-02-22T14:40:57.316Z" }, +] + [[package]] name = "urllib3" version = "2.7.0" @@ -1966,3 +3854,204 @@ sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e wheels = [ { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, ] + +[[package]] +name = "wrapt" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2b/b0/c1f5a970721f06b85c0cd5142e0ff8fe067708abd779b0c4f4be7d61d09f/wrapt-2.3.0.tar.gz", hash = "sha256:681a2d0eefd721998f90642762b8e75c2159ec531b20ad5e437245ea7b06a107", size = 131509, upload-time = "2026-07-28T06:06:14.895Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/b8/9182e4c618a847be0baccb68e4602b070d0fa22c782cf058f4bc66b32709/wrapt-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5ab559e1b2551d23d54db2a0001c6d73bad022a254639561c5f6c382a9d6c2fe", size = 81427, upload-time = "2026-07-28T06:04:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/84/ca/613cefd9c5977366b1587e61c0b428176d382e6d75b454084c5e58503042/wrapt-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bff9a671bc00709cab5a7f745c592b5671873449db0ee2a569af994f16b29a4d", size = 82360, upload-time = "2026-07-28T06:04:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/71/71/4cd2151a236f44a6e2dd4ed8011838d7ba0be3d656c8bafdfc65a2ed1917/wrapt-2.3.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fc648a335d7e01adb3640b25f02fd0ea05886cf04d0af7f4ee902bc7b5e466e8", size = 161700, upload-time = "2026-07-28T06:04:22.723Z" }, + { url = "https://files.pythonhosted.org/packages/49/2c/bc508fee75eb2919ed69769800b09968e4aab16897f909a23f39c81e323f/wrapt-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d0077f3d65541925fa83002f967b22ad6550d24813ac64cb905f717194128d9c", size = 162922, upload-time = "2026-07-28T06:04:24.177Z" }, + { url = "https://files.pythonhosted.org/packages/4d/e5/04f34d38e66d857dfc2fc4088d60e70c0e422467822defa49b2b4a26e17b/wrapt-2.3.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9790ea25190a4e0fe4cdf4eeb868e9d75f8a024a70a5b6bf9c348a3a2b72e731", size = 156125, upload-time = "2026-07-28T06:04:25.58Z" }, + { url = "https://files.pythonhosted.org/packages/23/41/c35940ea1c423f129ebe4361db853bc80d4def6326242e1206fa15bf94f4/wrapt-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:816877aa749253149f9ecfd2635d4d948ecfa338e1a0311d187b1acb1bb8a3eb", size = 162039, upload-time = "2026-07-28T06:04:27.154Z" }, + { url = "https://files.pythonhosted.org/packages/0e/60/9bda34c3d7d182aa703fe35339ae0ed4c4dad5e5c587f93890143e1f87fb/wrapt-2.3.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:3d1c2c1b808600d2ea808e6360910a60ed5f409a4011655e10f9164ba0a414a6", size = 155110, upload-time = "2026-07-28T06:04:28.497Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ba/60bfd9b1a751f4fcb2d603668fc272d651ccdd339a56acf8c40ad21a0293/wrapt-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5ba1e5e08ddc46130e9682b2c249f2d1dd39bda9106ed4bd401b7519f18f41bd", size = 161089, upload-time = "2026-07-28T06:04:29.959Z" }, + { url = "https://files.pythonhosted.org/packages/0f/32/2bd358c6f4f1305c813479d1e9ba746bebdd794f4a20107ab2b3ee0cbd45/wrapt-2.3.0-cp311-cp311-win32.whl", hash = "sha256:45c9279b373d15649dfa2c2077cb3408ea1a6d3125afbdab9d6b809a66f68e14", size = 78030, upload-time = "2026-07-28T06:04:31.241Z" }, + { url = "https://files.pythonhosted.org/packages/4a/62/ecc969b13b141fef89b888c9760821cb01a86ac8fc953911592c8e1e1522/wrapt-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:195b1842b4122fb54e3cd3dd5b2b4aa49302a5a61da901df0481f5c97aedde84", size = 80944, upload-time = "2026-07-28T06:04:32.655Z" }, + { url = "https://files.pythonhosted.org/packages/c4/3d/9278ada8a2b3f24372b630361e84e9a7de7abc3784634860c26d1c37785a/wrapt-2.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:6db604ef0c67bdb2042ecdfd7b7f037cf09733557ca42360d1018285634f7b98", size = 80074, upload-time = "2026-07-28T06:04:33.811Z" }, + { url = "https://files.pythonhosted.org/packages/5b/4a/d17a0fad1bf1c5f2c887ff71fef75654141b0880bff71d157d955b5bec3a/wrapt-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:0a45ffae742ce91a16e11cb6c7cd71e7f9994f3cbd283b962ab093f5c6dcf525", size = 82139, upload-time = "2026-07-28T06:04:35.082Z" }, + { url = "https://files.pythonhosted.org/packages/6e/55/51b92daaf6defb57f4dc56bdcce985400f75c6984a03ca5e78ccac717028/wrapt-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:69e477046f2237ef0bc6547544ee73008dc764ca26eff44f09e976d221b34d5d", size = 82723, upload-time = "2026-07-28T06:04:36.502Z" }, + { url = "https://files.pythonhosted.org/packages/28/7f/cfd9bc4b1f5e424eeea83d0493e43f3b1b02707ce8e50c47945873982bd5/wrapt-2.3.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5d221a6e6ddd302b8397433184e96b59f259f50024b854db1c411a881586b6b8", size = 172381, upload-time = "2026-07-28T06:04:37.674Z" }, + { url = "https://files.pythonhosted.org/packages/cb/89/ff7814f6eb6856b479946117d1138a2fbb46cdb6b1f379db359056c69743/wrapt-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:392158c9a7f2ab1b8699418bfc0fe6f83548788c418b27d7bf2019ad3405cebb", size = 174120, upload-time = "2026-07-28T06:04:38.987Z" }, + { url = "https://files.pythonhosted.org/packages/12/1e/8eded8615d39e3ce81f626937a3a87b280a2a86239a2bf14a4b4bb345034/wrapt-2.3.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e5301c35cf75655eb33498f2bd6ae8703ca19940e3167dc9cdf740c712a39c60", size = 163035, upload-time = "2026-07-28T06:04:40.361Z" }, + { url = "https://files.pythonhosted.org/packages/35/ea/a0af2d9da62897af2a055484920de05dade30d2ba2c0d65cbdea875d3d8b/wrapt-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:418f54bb09d1762db02c7009b4051149893af3153a87f92d70356703c11eea02", size = 171887, upload-time = "2026-07-28T06:04:41.614Z" }, + { url = "https://files.pythonhosted.org/packages/7e/dd/63cd4c864c65ef4906df64bd2d378f4a62b54f28063f282dfb3bf93caead/wrapt-2.3.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1598becd30f8f2777d18564064eb4f4dbe1ab0e05a8f09786d0ef505ac782bf3", size = 161113, upload-time = "2026-07-28T06:04:42.864Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ee/82f1fc9e431b5c2c5a6d201aa865dbeae3984c311c6d11a185f0c8367cf6/wrapt-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3da470536bf9645143323dd41b32db55c6f4304ad382094c1a1da8a92061e10d", size = 170530, upload-time = "2026-07-28T06:04:44.212Z" }, + { url = "https://files.pythonhosted.org/packages/37/a5/5dc590e863a419930d988f8b7ca3e75a6befcfb10b6003b3a152f3d5f732/wrapt-2.3.0-cp312-cp312-win32.whl", hash = "sha256:fb8e2e6704a1e0b1b989546c69e2688371ef4a07fa5f61bde3eb6211186f5ac1", size = 78323, upload-time = "2026-07-28T06:04:45.484Z" }, + { url = "https://files.pythonhosted.org/packages/51/f9/4a6925a07951df56394f7e6ebe14f69f1c5ef9d87aa63e0839acf15aa63a/wrapt-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:cdc021cb0b62471d6aac7f2bd92f3b4658073775f9ee7fcd325c511129e7bcc8", size = 81180, upload-time = "2026-07-28T06:04:47.021Z" }, + { url = "https://files.pythonhosted.org/packages/a8/4f/8b5de0395b2a72216751d41c9861df6facaeb611b619d8810ed2b3b23eb2/wrapt-2.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:67bfe2485f50368c3fcd2275fc1fd100e350d601e0058921a7c82678a465aeab", size = 80155, upload-time = "2026-07-28T06:04:48.373Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6e/0f88a072483e76b881e3fdcd6b6ffb4a5791002514fe541e72b1b73c859a/wrapt-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0d3fb71e65b001adfc42684522eeccd9c21d8ba679945abc993439567b66e59f", size = 81960, upload-time = "2026-07-28T06:04:49.622Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ff/b7e2776e7c294075eb712cc9ef573d1b818f393006d09787262b8fc871c4/wrapt-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:51a7a4181c1295774812271fbcd7c909df372bc25579d4ed9eb875caaf0ae86f", size = 82435, upload-time = "2026-07-28T06:04:50.9Z" }, + { url = "https://files.pythonhosted.org/packages/d8/90/343bb5d0f1f9669bc252a6073f085b4abf862511bd5c9c9eaec754341f1d/wrapt-2.3.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9045917809c63fdf7abe3a2ceaed3d670b8ee4500ddd9291192d30aeb34467c5", size = 170350, upload-time = "2026-07-28T06:04:52.187Z" }, + { url = "https://files.pythonhosted.org/packages/59/f8/13b79a392930bd0dd6b86cbfbfe1c40944110456e1dc6d809e5c46ece904/wrapt-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:54ca1d5573f69b5fe1d74f1f65799c68015e82f685efec9fd8cfa40a094c44d0", size = 170022, upload-time = "2026-07-28T06:04:53.599Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fc/4f1b6918f5290db959d6e0c07f77385d87cede29c39c9cf8f145e9c82954/wrapt-2.3.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:242b60c21e30866e6a2fa606c612b47c553fa60c0eaeeeb7797fb842ac0ce609", size = 161043, upload-time = "2026-07-28T06:04:54.936Z" }, + { url = "https://files.pythonhosted.org/packages/01/e1/45d3cf74414780bdff6d0380467e003f6eb0f028b6c9403db868dbc7209c/wrapt-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3f3d7ec0a51fbfe00d3aef047641ff2c58b25565b4717fc1f90e050be01cba8", size = 168576, upload-time = "2026-07-28T06:04:56.261Z" }, + { url = "https://files.pythonhosted.org/packages/f3/73/2fa58dd97f191c997755e2c6d569a68f0c433db4e4b36099bdd7227b6cac/wrapt-2.3.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:261f53870cd4fb2bf38f9f972c56c728fd224cb7c65721307de59d9e7e6741ae", size = 159140, upload-time = "2026-07-28T06:04:57.754Z" }, + { url = "https://files.pythonhosted.org/packages/29/a8/08a56e2000a8816d449dcbad8c8b081697acbbd490821ceca0f9d8e8d20c/wrapt-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8159ec0b0cb7608175eb150de94c19e34f4d47ac655f5ca9baf45df6b688ffd3", size = 169263, upload-time = "2026-07-28T06:04:59.161Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d4/354e1725e35a73b2af4fa70a3e024c7a5d1bf1802dfb862dcb668aae0253/wrapt-2.3.0-cp313-cp313-win32.whl", hash = "sha256:10461884b3014fbfc8eb7d09a93c5f246363e6711d9d881f95eb8c27fdef049f", size = 78241, upload-time = "2026-07-28T06:05:00.507Z" }, + { url = "https://files.pythonhosted.org/packages/6c/7e/34c87fa2174848dfee820322aaa318bab08913998ccecc8d2f57b4ad4639/wrapt-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:ac870cc97b73bb00ac353329e9559a4bebc47c4c86792ed9b23b58c15b6ad838", size = 81113, upload-time = "2026-07-28T06:05:01.839Z" }, + { url = "https://files.pythonhosted.org/packages/11/86/fcc9a530579e008c9478bb565a6cdfbfd33536660f069c8b91a6607c5050/wrapt-2.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:a65e8db2b4e90c2e7ade931086351c98ef420bf7a94ee08c95ac8a3cbbc43579", size = 80182, upload-time = "2026-07-28T06:05:03.152Z" }, + { url = "https://files.pythonhosted.org/packages/96/50/3864848b95b28ef73e17551fc8dccbff2628a834f52cf26a57f9c419fb83/wrapt-2.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:fd1f2f557dd3491fe75905e578f4db967393d40d1a8f468edc4d40ac7f2d5944", size = 83921, upload-time = "2026-07-28T06:05:04.476Z" }, + { url = "https://files.pythonhosted.org/packages/3b/4c/3d1921a60c3e8c71c540ff136e6a47a1fbccf7f671e818394889f7871d9c/wrapt-2.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9f5d2aec29dfc76c37e23897dee92766a3fd4f3bff3ae7fc9c6b4bf37d8c1360", size = 84412, upload-time = "2026-07-28T06:05:05.921Z" }, + { url = "https://files.pythonhosted.org/packages/fa/1a/4a796ff7adb26ada6d4b758c94d47a38320b085e7099afc088efbbcdb006/wrapt-2.3.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:646d20d413ffcd1b0a2f700076e2d0252d872dcb7754860a73e45a59ea883614", size = 207168, upload-time = "2026-07-28T06:05:07.256Z" }, + { url = "https://files.pythonhosted.org/packages/1d/3e/d7777776806c579b761bac2f91721dda9f04c7a1b380213c5935cc750ae6/wrapt-2.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:379f670f45b7bb8993edd9f6fc36c6cc65edb81cffa0b504be34acb0303fff0a", size = 214351, upload-time = "2026-07-28T06:05:08.945Z" }, + { url = "https://files.pythonhosted.org/packages/63/27/2d64d394df7bf181955b3bb562bf33c4492fb4be113f53071106d43ad8b5/wrapt-2.3.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6208f302f110295d64b22a7ac96500c791bf492dce4366e622e4912b077c9687", size = 199020, upload-time = "2026-07-28T06:05:10.418Z" }, + { url = "https://files.pythonhosted.org/packages/3e/3d/fb31d3db7d9834d265fb1a27a2adf0ddf51557c67458c97b22439ad6ae3d/wrapt-2.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ed635a9ca4f3a5a2b900c10c69e823373bc00ebc114b459383596d3487da3570", size = 209969, upload-time = "2026-07-28T06:05:11.983Z" }, + { url = "https://files.pythonhosted.org/packages/1f/d1/8724b5da582e62070dc9bf4d8bf1972f317297eefd7ba1f2b5c6393ccf6c/wrapt-2.3.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:e3b9eaa742ae7a0aaaaad4ca4b69469d757af2d6e6663ef1dadc47adec0aeb41", size = 196324, upload-time = "2026-07-28T06:05:13.557Z" }, + { url = "https://files.pythonhosted.org/packages/0d/5c/3d9ef411149543016ee6bcf3af707f787cebd946527452b94bf122e9b7b4/wrapt-2.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d0f7284f88f4833705132d06d3b425a43095c2cbd07c58166aac3ab646ba12a4", size = 202610, upload-time = "2026-07-28T06:05:15.048Z" }, + { url = "https://files.pythonhosted.org/packages/13/9b/4fc042ceb757866dd4a5fc057b3b736f2b360d3703ce9f830d83dc9226e0/wrapt-2.3.0-cp313-cp313t-win32.whl", hash = "sha256:7ebb274aba688b043429eb1500ff8a76ce0cb8ac0812ca3e301f06247b8722b3", size = 79178, upload-time = "2026-07-28T06:05:16.469Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ff/b94878f8eed809ca042685276bcea9f24e8c2ca7c9653bb80bbb920a68a5/wrapt-2.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:c4bded758ad6f03b965830944a2f0bc5b2eb3767fe5a7310134315d1a6610e98", size = 82634, upload-time = "2026-07-28T06:05:18.026Z" }, + { url = "https://files.pythonhosted.org/packages/80/fb/663e1de5332a71685a729754312d327d4cada767c36e1c5a2db4c8de49e6/wrapt-2.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:d2cc64539da63e39ffb9c7ede849b6e8ddaaf7b3876b5cfb04efd85a5f3f4eb6", size = 81387, upload-time = "2026-07-28T06:05:19.417Z" }, + { url = "https://files.pythonhosted.org/packages/58/10/b073beaea89bc0d3670a75ff51139430a54b6af7ba7796507730634536dd/wrapt-2.3.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ea52a0d0f08c584943d5764be0e84efa912c8da23c23e1e285ff2f5641c18fcc", size = 81978, upload-time = "2026-07-28T06:05:21.133Z" }, + { url = "https://files.pythonhosted.org/packages/b3/31/0916d9cebf848ed3f1a0c1888faee421747df77331e4db2bc527a9a85988/wrapt-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd85b0aa88efdb189d6ae2f35f4526943a8f091c38599c9c31478241c819e6a1", size = 82518, upload-time = "2026-07-28T06:05:22.562Z" }, + { url = "https://files.pythonhosted.org/packages/f5/73/31c1bf0f3384062751c2094dadb314916d70aa9b6bfd26d994b4a7b393fa/wrapt-2.3.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:141ed6211286a9660d8d6702de598b43f0934b4f0eda16393f100a80f501d945", size = 170187, upload-time = "2026-07-28T06:05:23.904Z" }, + { url = "https://files.pythonhosted.org/packages/ed/25/fce087d54b79b8905f3c3c9dd5f454bbd8d8acb80b960c4a6aee5b4659b3/wrapt-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e49885a62ec4ee854d1b9e6371fda6afd219917225752abf729a3f36d4df9a5", size = 169288, upload-time = "2026-07-28T06:05:25.378Z" }, + { url = "https://files.pythonhosted.org/packages/c7/30/0d09e6dddc6b7a7230ac77f50254b5980ab4fcd22976f72f8cc8a0404458/wrapt-2.3.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1d6159c9b2fefec02314e1332dbbbfaf960e369dfd26bcf7f8b258b5732065b3", size = 160932, upload-time = "2026-07-28T06:05:27.022Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ca/0913af0d2ec0c43865d32d615f518fea66c13c5c930e489e9b0de248e9a8/wrapt-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:24da48596326ef8e448cfa837b454f638713d3531262375f00e5a9681682fc07", size = 169017, upload-time = "2026-07-28T06:05:28.501Z" }, + { url = "https://files.pythonhosted.org/packages/c3/f2/3d1e47ea81b822210f5df1bf942fd90780a75c055243d569b664529dea88/wrapt-2.3.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:cd3a2edf0427013736b8127955cec62608c56e53ea47e82812ea32059cda407f", size = 159065, upload-time = "2026-07-28T06:05:30.01Z" }, + { url = "https://files.pythonhosted.org/packages/43/a5/ef2066ced8e5fca204e2b361e9708e36555b40949c583d997ea3b590817d/wrapt-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4fa0df3bff4e7ce45759f33fd39335fe2f60477bb9ecf7b8aa41e7d07ee36a23", size = 168821, upload-time = "2026-07-28T06:05:31.649Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e1/016104650d4e572fa91506eb396b3dd8efbccc9284fdc1c9479c3d21db28/wrapt-2.3.0-cp314-cp314-win32.whl", hash = "sha256:2935d5454b3f179a29b12cf390ee47246740ba2c3a7545b1b46ba31a5f2a4a0b", size = 78700, upload-time = "2026-07-28T06:05:33.391Z" }, + { url = "https://files.pythonhosted.org/packages/3d/97/6fdc20a9f2ca304748b3f0819cbf377d55260562777bf0b615431bc3c181/wrapt-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:cc2cea812e5cb179a796b766747e7d3b21088760d8deb95676d482b8c8e6fa7d", size = 81422, upload-time = "2026-07-28T06:05:34.774Z" }, + { url = "https://files.pythonhosted.org/packages/5e/a4/9cbd53bf05746bea2c392af39cb052427a8ec95cbd494d930733d8f44681/wrapt-2.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:22cc5c0a717bd4da87018ae0bffd4c19c6fb679d3ff357216ba566ab26c76cab", size = 80639, upload-time = "2026-07-28T06:05:36.228Z" }, + { url = "https://files.pythonhosted.org/packages/43/bb/6c5e4a0f66ea0d2b2dd267e8dd05a0014eea56840b3c8595d40b0a5d1f91/wrapt-2.3.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a6b5984cd65dd639546f0eb4b8eacf1c31cb2fe9fb5c27bffe240987cdb2cf84", size = 84030, upload-time = "2026-07-28T06:05:37.714Z" }, + { url = "https://files.pythonhosted.org/packages/6a/eb/a1aedf03283bc9cbf8a1783995ddc54e3c5a86878f19002d2c428494f4c5/wrapt-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c88abcf53daef80e01a75c7530e727fa6e2c1888fe83e3dcdba4c96216a1f5c7", size = 84419, upload-time = "2026-07-28T06:05:39.131Z" }, + { url = "https://files.pythonhosted.org/packages/63/61/50d511c0dc5105563849e86daa3e16ac7feef699f79fb05af45ea70107d5/wrapt-2.3.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:85de890ff968196e92dd1ae73a9fb8970495e7650a457b1c9ef0ac3dd550bce2", size = 207171, upload-time = "2026-07-28T06:05:40.69Z" }, + { url = "https://files.pythonhosted.org/packages/3f/59/9b538cf7795217e810699d16bc88b96a830d9b5c403eb2ec2db6b5f2ae81/wrapt-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:50f416b74d092bb9f41b424e90dd457f365f7ba4b11de62a23679769a21bd85c", size = 214329, upload-time = "2026-07-28T06:05:42.287Z" }, + { url = "https://files.pythonhosted.org/packages/b3/28/9935d62b1499e5c8b3d191e99ba4eb31ca237a0b699142011a837e9dc7ea/wrapt-2.3.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:39febbee6d77301d31da6996b152ce52452da7c7ef72aba10c2fa976dff9c295", size = 199079, upload-time = "2026-07-28T06:05:43.958Z" }, + { url = "https://files.pythonhosted.org/packages/2b/01/4446b80fa2ffa47a3449b250d004ba1c1937f07f64a179608fec735df866/wrapt-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:93513bec052c6cd987f9f580c3df068c8bc4ebae6543736be3ca7ec5959cafcd", size = 209992, upload-time = "2026-07-28T06:05:45.677Z" }, + { url = "https://files.pythonhosted.org/packages/d4/07/56f26c9f9979586a021e8148747004aba4498f49458c90b0502969b904e1/wrapt-2.3.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:729126e667da34d251b8ebf8a45ef0c5ddadc21542b3d6e1abf4259ece6508df", size = 196334, upload-time = "2026-07-28T06:05:47.608Z" }, + { url = "https://files.pythonhosted.org/packages/8b/41/6d7bcc895b0f28b2250e10908f060687b9165429dcd7f22ddb3d4c031b74/wrapt-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:626b69db2021aa01671ec7bbc9740e558522bd44c18cf2ce69bf3d666a014109", size = 202644, upload-time = "2026-07-28T06:05:49.183Z" }, + { url = "https://files.pythonhosted.org/packages/cd/25/7860927edba06b758b8852a6f02e832be715563c67a6795d94350bc81099/wrapt-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:629d73378082c00a8173031f9fb30a3ac6abbc894a5bfdfae71fabc60642d501", size = 79685, upload-time = "2026-07-28T06:05:50.976Z" }, + { url = "https://files.pythonhosted.org/packages/c4/0f/270bafe92fde3b069a39bc01e39ee79340895b335640df861d43d2a51885/wrapt-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:42869085687f0aefd57c0f636c3f9354f8ffb321a8ba9cb52d19beb796e561c5", size = 83104, upload-time = "2026-07-28T06:05:52.405Z" }, + { url = "https://files.pythonhosted.org/packages/55/b3/af176d79a8515a8a720eccdad9a96f6e31a30abf2865430c8c42adf2fd13/wrapt-2.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:b1e5aa486e269b00ed35e64771c7d0ab8096cfd2643405ca8cd60ebedc099a51", size = 81774, upload-time = "2026-07-28T06:05:53.902Z" }, + { url = "https://files.pythonhosted.org/packages/00/39/3daf9f47be208606586de4568ba6713db53ebc8fd7a575aea1fe57983b69/wrapt-2.3.0-py3-none-any.whl", hash = "sha256:d8c7ed08477429752b8c44991f40ad7838b18332a160698740a6bfbc10d998a2", size = 61866, upload-time = "2026-07-28T06:06:12.9Z" }, +] + +[[package]] +name = "xyzservices" +version = "2026.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/08/3cb9f67a8d48021aca2a02292cc26eecd71d949ae70ad66420a8730cc302/xyzservices-2026.3.0.tar.gz", hash = "sha256:d226866a5d8e9fef337034d8da37a8298f0a1d9d1489b4018e69579eb321fea4", size = 1135736, upload-time = "2026-03-30T14:42:25.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/a9/d23012099dc88ec69a29c6407b41d89681cb674c2043cd5b467c7e299c08/xyzservices-2026.3.0-py3-none-any.whl", hash = "sha256:503183d4b322bfebc3c50cdd21192aa3e81e36c5efbf9133d54ae82143e0576b", size = 94101, upload-time = "2026-03-30T14:42:24.608Z" }, +] + +[[package]] +name = "yarl" +version = "1.24.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/31/33/ebe9e3d1f86c7a0b51094c0a146392045ca1631d2664889539dec8088a33/yarl-1.24.5.tar.gz", hash = "sha256:e81b83143bee16329c23db3c1b2d82b29892fcbcb849186d2f6e98a5abe9a57f", size = 228679, upload-time = "2026-07-20T02:07:45.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/db/3cb5df059756a45761cc3dee8fd25ec82b83a6585ea3542b969fda850f99/yarl-1.24.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2c1fe720934a16ea8e7146175cba2126f87f54912c8c5435e7f7c7a51ef808d3", size = 135043, upload-time = "2026-07-20T02:04:52.39Z" }, + { url = "https://files.pythonhosted.org/packages/44/f8/767d6bd5a03db63bc467df2fb56d6fafeae9667d74aea92cd6af399f828b/yarl-1.24.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c687ed078e145f5fd53a14854beff320e1d2ab76df03e2009c98f39a0f68f39a", size = 96942, upload-time = "2026-07-20T02:04:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/ce/97/10b939c44d7b28d1dbc389cfc7012306d1ea8dba01eaef44b39fffaee52a/yarl-1.24.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:709f1efed56c4a145793c046cd4939f9959bcd818979a787b77d8e09c57a0840", size = 97046, upload-time = "2026-07-20T02:04:56.638Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7a/b410dbe39b6255c55fb2a2bcee96eb844d0789235ddc381a889a90dc72d6/yarl-1.24.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:874019bd513008b009f58657134e5d0c5e030b3559bd0553976837adf52fe966", size = 110512, upload-time = "2026-07-20T02:04:58.955Z" }, + { url = "https://files.pythonhosted.org/packages/83/c7/da591971f78a5617e1f21f5699858ebccd836fe181a6493788ffc91ba69b/yarl-1.24.5-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a4582acf7ef76482f6f511ebaf1946dae7f2e85ec4728b81a678c01df63bd723", size = 102454, upload-time = "2026-07-20T02:05:00.623Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8e/73b0ed4de47289a78a96045d76d1cfe5e41848bf0da59ce25b2ec87ee05d/yarl-1.24.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2cabe6546e41dabe439999a23fcb5246e0c3b595b4315b96ef755252be90caeb", size = 117617, upload-time = "2026-07-20T02:05:02.325Z" }, + { url = "https://files.pythonhosted.org/packages/cf/14/b744747bc4f57a8d55bd744df463457524583e1e9f7538b5ace0346ab92e/yarl-1.24.5-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:17f57620f5475b3c69109376cc87e42a7af5db13c9398e4292772a706ff10780", size = 116135, upload-time = "2026-07-20T02:05:04.05Z" }, + { url = "https://files.pythonhosted.org/packages/66/ca/95aa4d0e5b7ea4f20e4d577c42d001ed9df207569fdb063cc5ed4ebb496b/yarl-1.24.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:570fec8fbd22b032733625f03f10b7ff023bc399213db15e72a7acaef28c2f4e", size = 111935, upload-time = "2026-07-20T02:05:05.738Z" }, + { url = "https://files.pythonhosted.org/packages/72/0d/d2ad8d6b147832d177a4e720ba1962fe686eb0913b74503b3eca094b8bba/yarl-1.24.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5fede79c6f73ff2c3ef822864cb1ada23196e62756df53bc6231d351a49516a2", size = 110010, upload-time = "2026-07-20T02:05:07.471Z" }, + { url = "https://files.pythonhosted.org/packages/50/18/eb335e4120903903f4865041355ae46256a2406eb2865bc24827f4f27b61/yarl-1.24.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8ccf9aca873b767977c73df497a85dbedee4ee086ae9ae49dc461333b9b79f58", size = 110058, upload-time = "2026-07-20T02:05:09.246Z" }, + { url = "https://files.pythonhosted.org/packages/44/70/97353add32c62ad6f206d948ac5a5ee84398225e534dc6ed6433d1b335b6/yarl-1.24.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ad5d8201d310b031e6cd839d9bac2d4e5a01533ce5d3d5b50b7de1ef3af1de61", size = 103308, upload-time = "2026-07-20T02:05:11.31Z" }, + { url = "https://files.pythonhosted.org/packages/68/39/5e7398d4b6f6b3c9062823ebc60802df5b272e3fe9e788f9734c6ee46c85/yarl-1.24.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:841f0852f48fefea3b12c9dfec00704dfa3aef5215d0e3ce564bb3d7cd8d57c6", size = 116898, upload-time = "2026-07-20T02:05:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c9/09e52f2239e8b96357eccca05915382e4ba5405ebfb623b6036040d99654/yarl-1.24.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9baafc71b04f8f4bb0703b21d6fc9f0c30b346c636a532ff16ec8491a5ea4b1f", size = 109400, upload-time = "2026-07-20T02:05:14.821Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6a/e94133d4c2d1a14d2384310bf3e79d9cf32c9d1eae1c6f034fb80d098fa1/yarl-1.24.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d897129df1a22b12aeed2c2c98df0785a2e8e6e0bde87b389491d0025c187077", size = 115934, upload-time = "2026-07-20T02:05:17.78Z" }, + { url = "https://files.pythonhosted.org/packages/4e/3c/34955ed967b976fc38edcbb6d538dee79dbda4cb7fc7f72a0907a7c78e0f/yarl-1.24.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dd625535328fd9882374356269227670189adfcc6a2d90284f323c05862eecbd", size = 112178, upload-time = "2026-07-20T02:05:19.675Z" }, + { url = "https://files.pythonhosted.org/packages/f5/46/d7bd3a8859d47dcfaffd7127af7076032a7da278a9a02e17b5f37bfb6712/yarl-1.24.5-cp311-cp311-win_amd64.whl", hash = "sha256:f4239bbec5a3577ddb49e4b50aeb32d8e5792098262ae2f63723f916a29b1a25", size = 97544, upload-time = "2026-07-20T02:05:21.523Z" }, + { url = "https://files.pythonhosted.org/packages/01/69/c1bfd21e32c638974ea2c542a0b8c53ef1fa9eff336020f5d014f9503ff2/yarl-1.24.5-cp311-cp311-win_arm64.whl", hash = "sha256:3ac6aff147deb9c09461b2d4bbdf6256831198f5d8a23f5d37138213090b6d8a", size = 93359, upload-time = "2026-07-20T02:05:23.493Z" }, + { url = "https://files.pythonhosted.org/packages/1b/84/71d051c850b5af41d168c679d9eb67eb7c55283ac4ee131673edf134bc4e/yarl-1.24.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d693396e5aea78db03decd60aec9ece16c9b40ba00a587f089615ff4e718a81d", size = 136035, upload-time = "2026-07-20T02:05:25.489Z" }, + { url = "https://files.pythonhosted.org/packages/03/4d/8ad27f9a1b7e69313cca5d695b925b48efe51208d3490e0844bae97cabc0/yarl-1.24.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3363fcc96e665878946ad7a106b9a13eac0541766a690ef287c0232ac768b6ec", size = 97642, upload-time = "2026-07-20T02:05:27.429Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b4/05b4131c407006cd1e410e9c6539f16a0945724677e5364447313c15ea3e/yarl-1.24.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9d399bdcfb4a0f659b9b3788bbc89babe63d9a6a65aacdf4d4e7065ff2e6316c", size = 97323, upload-time = "2026-07-20T02:05:29.441Z" }, + { url = "https://files.pythonhosted.org/packages/20/16/e618c875c73e0e39611f20a581b3d5e8d59b8857bf001bee3263044c6deb/yarl-1.24.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90333fd89b43c0d08ac85f3f1447593fc2c66de18c3d6378d7125ea118dc7a54", size = 107741, upload-time = "2026-07-20T02:05:31.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c4defeaf3ed33fcb346aacf9c6e971a8d4e2bde04a0310e79abb208e7965/yarl-1.24.5-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:665b0a2c463cc9423dd647e0bfd9f4ccc9b50f768c55304d5e9f80b177c1de12", size = 103570, upload-time = "2026-07-20T02:05:33.303Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e7/0e0e0de5865ebd5914537ef486f36c727a59865c3ac0cf5ff1b32aececbf/yarl-1.24.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e006d3a974c4ee19512e5f058abedb6eef36a5e553c14812bdeba1758d812e6d", size = 115815, upload-time = "2026-07-20T02:05:35.292Z" }, + { url = "https://files.pythonhosted.org/packages/2b/27/ca56b700cb170aba25a3893b75355b213935657dc5714d2383354a270e62/yarl-1.24.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e7d42c531243450ef0d4d9c172e7ed6ef052640f195629065041b5add4e058d1", size = 116025, upload-time = "2026-07-20T02:05:37.503Z" }, + { url = "https://files.pythonhosted.org/packages/d6/d0/d56c859b8222116f5d68459199f48359e0bf121b6f65a69bf329b3602ba0/yarl-1.24.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f08c7513ecef5aad65687bfdf6bc601ae9fccd04a42904501f8f7141abad9eb9", size = 109835, upload-time = "2026-07-20T02:05:39.506Z" }, + { url = "https://files.pythonhosted.org/packages/70/a2/3a35557e4d1a79425040eba202ccaf08bdc8717680fc77e2498a1ad2e0a5/yarl-1.24.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6c95b17fe34ed802f17e205112e6e10db92275c34fee290aa9bdc55a9c724027", size = 108884, upload-time = "2026-07-20T02:05:41.584Z" }, + { url = "https://files.pythonhosted.org/packages/e4/35/ef4c26356b7913c68983bac2d72a4212b3347af551cb8d250b99b5ed7b7f/yarl-1.24.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56b149b22de33b23b0c6077ab9518c6dcb538ad462e1830e68d06591ccf6e38b", size = 107308, upload-time = "2026-07-20T02:05:43.697Z" }, + { url = "https://files.pythonhosted.org/packages/d5/91/ff0dc66c2ccf3e0153ab97ff61eabab4400e6a5264af427ab30cd69f1857/yarl-1.24.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a8fe66b8f300da93798025a785a5b90b42f3810dc2b72283ff84a41aaaebc293", size = 103646, upload-time = "2026-07-20T02:05:45.895Z" }, + { url = "https://files.pythonhosted.org/packages/74/f0/33b9271c7f881766359d58266fa0811d2e5210ed860e28da7dc6d7786344/yarl-1.24.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:377fe3732edbaf78ee74efdf2c9f49f6e99f20e7f9d2649fda3eb4badd77d76e", size = 115305, upload-time = "2026-07-20T02:05:47.832Z" }, + { url = "https://files.pythonhosted.org/packages/ef/65/fd79fb1868c4a80db8661091de525bf430f63c3bea1b20e8b6a84fc7d359/yarl-1.24.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e8ffa78582120024f476a611d7befc123cee59e47e8309d470cf667d806e613b", size = 108404, upload-time = "2026-07-20T02:05:49.604Z" }, + { url = "https://files.pythonhosted.org/packages/ff/ba/dbabe6b262f17a816c70cfc09558dbf03ece3ec76684d02f911a3d3a189c/yarl-1.24.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:daba5e594f06114e37db186efd2dd916609071e59daca901a0a2e71f02b142ce", size = 115940, upload-time = "2026-07-20T02:05:51.741Z" }, + { url = "https://files.pythonhosted.org/packages/a5/43/fab2d1dad9d340a268cdde63756a123d069723efff6a372d123fa74a9517/yarl-1.24.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:65be18ec59496c13908f02a2472751d9ef840b4f3fb5726f129306bf6a2a7bba", size = 110006, upload-time = "2026-07-20T02:05:53.554Z" }, + { url = "https://files.pythonhosted.org/packages/c4/27/41eb51bbd1b8d89546b83897cfb0164f1e109304fd408dbb151b639eec0f/yarl-1.24.5-cp312-cp312-win_amd64.whl", hash = "sha256:a929d878fec099030c292803b31e5d5540a7b6a31e6a3cc76cb4685fc2a2f51b", size = 97618, upload-time = "2026-07-20T02:05:55.57Z" }, + { url = "https://files.pythonhosted.org/packages/3c/25/b2553764b3d65db711d8f45416351ec4f420847558eb669edcbcaadf5780/yarl-1.24.5-cp312-cp312-win_arm64.whl", hash = "sha256:7ce27823052e2013b597e0c738b13e7e36b8ccb9400df8959417b052ab0fd92c", size = 93018, upload-time = "2026-07-20T02:05:57.554Z" }, + { url = "https://files.pythonhosted.org/packages/e1/63/64ef361967cc983573149dc1515d531db5da8a4c92d22bb833d59e01b313/yarl-1.24.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:79af890482fc94648e8cde4c68620378f7fef60932710fa17a66abc039244da2", size = 135075, upload-time = "2026-07-20T02:05:59.671Z" }, + { url = "https://files.pythonhosted.org/packages/bb/89/55920fd853ce43e608adbc3962456f0d649d6bb15250dc2988321da0fe1c/yarl-1.24.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:46c2f213e23a04b93a392942d782eb9e413e6ef6bf7c8c53884e599a5c174dcb", size = 97225, upload-time = "2026-07-20T02:06:01.769Z" }, + { url = "https://files.pythonhosted.org/packages/15/f0/7688d3f2cfff7590df2af38ec46d969f4281a4dddb08a9ad2eafbcdddf98/yarl-1.24.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92ab3e11448f2ff7bf53c5a26eff0edc086898ec8b21fb154b85839ce1d88075", size = 96751, upload-time = "2026-07-20T02:06:03.676Z" }, + { url = "https://files.pythonhosted.org/packages/05/1a/a851a0f94aaaf379dd4f901bfc80f634280bec51eb260b47363e2a4cd62e/yarl-1.24.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ebb0ec7f17803063d5aeb982f3b1bd2b2f4e4fae6751226cbd6ba1fcfe9e63ff", size = 107960, upload-time = "2026-07-20T02:06:05.699Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a8/faea066c12f9c77ca0de90641f1655f9dd7b412477bf28c76d692f3aecff/yarl-1.24.5-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:82632daed195dcc8ea664e8556dc9bdbd671960fb3776bd92806ce05792c2448", size = 103500, upload-time = "2026-07-20T02:06:07.556Z" }, + { url = "https://files.pythonhosted.org/packages/fb/9c/1e67084c2a6e2f2db0e3be798328cb3be42c0119b621d25461479a224d21/yarl-1.24.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:53e549287ef628fecba270045c9701b0c564563a9b0577d24a4ec75b8ab8040f", size = 115780, upload-time = "2026-07-20T02:06:09.599Z" }, + { url = "https://files.pythonhosted.org/packages/58/86/1f94664e147474337e3359f52012cf3d02f825f694317b178bfba1078c62/yarl-1.24.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fcd3b77e2f17bbe4ca56ec7bcb07992647d19d0b9c05d84886dcd6f9eb810afd", size = 115308, upload-time = "2026-07-20T02:06:11.352Z" }, + { url = "https://files.pythonhosted.org/packages/0a/43/8e55ae7538ba5f28ccb3c845c6dd4549cf7016d5992e5326512519107cdd/yarl-1.24.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d46b86567dd4e248c6c159fcbcdcce01e0a5c8a7cd2334a0fff759d0fa075b16", size = 110574, upload-time = "2026-07-20T02:06:13.129Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ba/a889ec8765cedcf2ac44dcb02d6a21e4861399b243b263c5f2dde27ee740/yarl-1.24.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7f72c74aa99359e27a2ee8d6613fefa28b5f76a983c083074dfc2aaa4ab46213", size = 109914, upload-time = "2026-07-20T02:06:15.243Z" }, + { url = "https://files.pythonhosted.org/packages/9c/c3/e45f821af67b791c2dbbe4a9f4137a1d33f8d386654a05a0c3f47bdfa25d/yarl-1.24.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3f45789ce415a7ec0820dc4f82925f9b5f7732070be1dec1f5f23ec381435a24", size = 107712, upload-time = "2026-07-20T02:06:17.443Z" }, + { url = "https://files.pythonhosted.org/packages/02/00/2ab0f42c9857fcb490bfaa6647b14540b53d241ab209f23220b958cc5832/yarl-1.24.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6e73e7fe93f17a7b191f52ec9da9dd8c06a8fe735a1ecbd13b97d1c723bff385", size = 104251, upload-time = "2026-07-20T02:06:19.259Z" }, + { url = "https://files.pythonhosted.org/packages/7a/70/709d9a286e98af2c7fd8e4e6cada658b5c0e30d87dd7e2a63c2fb5767217/yarl-1.24.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4a36f9becdd4c5c52a20c3e9484128b070b1dcfc8944c006f3a528295a359a9c", size = 115319, upload-time = "2026-07-20T02:06:21.207Z" }, + { url = "https://files.pythonhosted.org/packages/5c/6c/3eaa515142991fe84cfc483ff986492211f1978f90161ccefdbec919d09b/yarl-1.24.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:7bcbe0fcf850eae67b6b01749815a4f7161c560a844c769ad7b48fcd99f791c4", size = 109163, upload-time = "2026-07-20T02:06:23.006Z" }, + { url = "https://files.pythonhosted.org/packages/bb/64/711dafce66c323a3144d470547a71c5384c57623308ac8bb5e4b903ac148/yarl-1.24.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:24e861e9630e0daddcb9191fb187f60f034e17a4426f8101279f0c475cd74144", size = 115435, upload-time = "2026-07-20T02:06:24.923Z" }, + { url = "https://files.pythonhosted.org/packages/cf/f3/9b9d0e6d84bea851eb1ba99e4bdc755b86fd813e49ec86dfe42f26befdef/yarl-1.24.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9335a099ad87287c37fe5d1a982ff392fa5efe5d14b40a730b1ec1d6a41382b4", size = 110691, upload-time = "2026-07-20T02:06:26.973Z" }, + { url = "https://files.pythonhosted.org/packages/86/e4/62a06b7e87c4246ac76b7c2da136f972eb4a3a1fc94abb07e7022d6fdb0a/yarl-1.24.5-cp313-cp313-win_amd64.whl", hash = "sha256:2dbe06fc16bc91502bca713704022182e5729861ae00277c3a23354b40929740", size = 97454, upload-time = "2026-07-20T02:06:29.163Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c9/5fc8025b318ab10db413b61056bd0d95c557a70e8df4210c7511f866329c/yarl-1.24.5-cp313-cp313-win_arm64.whl", hash = "sha256:6b8536851f9f65e7f00c7a1d49ba7f2be0ffe2c11555367fc9f50d9f842410a1", size = 92813, upload-time = "2026-07-20T02:06:31.113Z" }, + { url = "https://files.pythonhosted.org/packages/a9/08/5f3085fef9564217074db9dd8573de1795bc82cde61a7ad10b6a7234a569/yarl-1.24.5-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:2729fcfc4f6a596fb0c50f32090400aa9367774ac296a00387e65098c0befa76", size = 135680, upload-time = "2026-07-20T02:06:33.273Z" }, + { url = "https://files.pythonhosted.org/packages/98/35/ba9436e579bd48a8801f2021d842d9ab4994c26e4c7dd3a4c1f1bcb57a9e/yarl-1.24.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ff330d3c30db4eb6b01d79e29d2d0b407a7ecad39cfd9ec993ece57396a2ec0d", size = 97395, upload-time = "2026-07-20T02:06:35.259Z" }, + { url = "https://files.pythonhosted.org/packages/18/a9/a07f76f3c44e02b25cc743af5ef93eef27f7013eadca770451b6a6ccb5db/yarl-1.24.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e42d75862735da90e7fc5a7b23db0c976f737113a54b3c9777a9b665e9cbff75", size = 97223, upload-time = "2026-07-20T02:06:37.216Z" }, + { url = "https://files.pythonhosted.org/packages/77/f7/a9a1d6fa7dd9e388f95b30f6ad3ec4e285f6c8f61f44ce16070c3fcfe414/yarl-1.24.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3732e66413163e72508da9eff9ce9d2846fde51fae45d3605393d3e6cd303e9", size = 108777, upload-time = "2026-07-20T02:06:39.292Z" }, + { url = "https://files.pythonhosted.org/packages/2f/44/e0b86c302471fabd6f02808ecf2ac52b8412b624787849d4bf2cdb466f6f/yarl-1.24.5-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b8ee53be440a0cffc991a27be3057e0530122548dbe7c0892df08822fce5ede", size = 103119, upload-time = "2026-07-20T02:06:41.456Z" }, + { url = "https://files.pythonhosted.org/packages/d1/16/9c16d180bf8faaf223225eb50e1245870ff1ae0e302a27153988e65c51fd/yarl-1.24.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:af3aefa655adb5869491fa907e652290386800ae99cc50095cba71e2c6aefdca", size = 116471, upload-time = "2026-07-20T02:06:43.696Z" }, + { url = "https://files.pythonhosted.org/packages/d2/8d/b219b9df28a02ce95cfbdd41d2f7caa5669d0ff979c1c9975697145e33c5/yarl-1.24.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2120b96872df4a117cde97d270bac96aea7cc52205d305cf4611df694a487027", size = 115974, upload-time = "2026-07-20T02:06:45.874Z" }, + { url = "https://files.pythonhosted.org/packages/9b/e8/f20557aca240d88e69850ad1ee91756821d094bb1310565c04d25c6682a2/yarl-1.24.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:66410eb6345d467151934b49bfa70fb32f5b35a6140baa40ad97d6436abea2e9", size = 110830, upload-time = "2026-07-20T02:06:47.852Z" }, + { url = "https://files.pythonhosted.org/packages/db/18/199b85109a53eeca64ee19c9cca228287e8e4ab0cc1a09b28f530e65cce0/yarl-1.24.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4af7b7e1be0a69bee8210735fe6dcfc38879adfac6d62e789d53ba432d1ffa41", size = 110054, upload-time = "2026-07-20T02:06:49.84Z" }, + { url = "https://files.pythonhosted.org/packages/aa/2f/ed28147f8cd7f48c49367c90713b30a555284b6105a6a56f3a05568da795/yarl-1.24.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa139875ff98ab97da323cfadfaff08900d1ad42f1b5087b0b812a55c5a06373", size = 108312, upload-time = "2026-07-20T02:06:51.835Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c5/55e16ae0a5c227cea8df1c6871ba57d614a34243146c05729caf2a1bd9c5/yarl-1.24.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:0055afc45e864b92729ac7600e2d102c17bef060647e74bca75fa84d66b9ff36", size = 103662, upload-time = "2026-07-20T02:06:54.061Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ea/dbd7c2caec459c9a426f18b02688ecbfb58620d0f6a3422d24769fbaf8ab/yarl-1.24.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f0e466ed7511fe9d459a819edbc6c2585c0b6eabde9fa8a8947552468a7a6ef0", size = 116090, upload-time = "2026-07-20T02:06:56.015Z" }, + { url = "https://files.pythonhosted.org/packages/06/84/39ce4ce3059e07fece5fbdbee8c4053406af9aca911ce9fa5f8548aab6af/yarl-1.24.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f141474e85b7e54998ec5180530a7cda99ab29e282fa50e0756d89981a9b43c5", size = 109523, upload-time = "2026-07-20T02:06:57.926Z" }, + { url = "https://files.pythonhosted.org/packages/a9/8b/71ff44137b405c64a7788075669c24010019f57a7464b78c3a6cbee539d9/yarl-1.24.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:e2935f8c39e3b03e83519292d78f075189978f3f4adc15a78144c7c8e2a1cba5", size = 116084, upload-time = "2026-07-20T02:06:59.868Z" }, + { url = "https://files.pythonhosted.org/packages/62/c0/423078fdd4042e1862c11f0ffd977a0ffa393783c12bee94685923bc189e/yarl-1.24.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9d1216a7f6f77836617dba35687c5b78a4170afc3c3f18fc788f785ba26565c4", size = 111006, upload-time = "2026-07-20T02:07:01.907Z" }, + { url = "https://files.pythonhosted.org/packages/cf/52/6daa2ee9d95e5c98b8128f8df91eb692eb423ab274b8cf08db52152fad26/yarl-1.24.5-cp314-cp314-win_amd64.whl", hash = "sha256:5ba4f78df2bcc19f764a4b26a8a4f5049c110090ad5825993aacb052bf8003ad", size = 99215, upload-time = "2026-07-20T02:07:03.852Z" }, + { url = "https://files.pythonhosted.org/packages/ec/0e/464a847d7359e0da75dd9fc5c1d1aa35d0159ea31e5f8e66a3c1c29ff3d0/yarl-1.24.5-cp314-cp314-win_arm64.whl", hash = "sha256:9e4e16c73d717c5cf27626c524d0a2e261ad20e46932b2670f64ad5dde23e26f", size = 94566, upload-time = "2026-07-20T02:07:06.074Z" }, + { url = "https://files.pythonhosted.org/packages/e2/55/e03acc4446772660bc335e86e41ef31e4d0d838fd641531a11a5ee33b493/yarl-1.24.5-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e1ae548a9d901adca07899a4147a7c826bbcc06239d3ce9a59f57886a28a4c88", size = 142533, upload-time = "2026-07-20T02:07:08.284Z" }, + { url = "https://files.pythonhosted.org/packages/ae/71/4acd3a1fc7cf14345cdb302665ecd2097f62c365b4f14ca17d4f37775cf9/yarl-1.24.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ff405d91509d88e8d44129cd87b18d70acd1f0c1aeabd7bc3c46792b1fe2acba", size = 100776, upload-time = "2026-07-20T02:07:10.197Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/cfb76b7fe99686db264bff829779a539d923e7564ffd7ef18da6c54c3774/yarl-1.24.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:47e98aab9d8d82ff682e7b0b5dded33bf138a32b817fcf7fa3b27b2d7c412928", size = 100913, upload-time = "2026-07-20T02:07:12.357Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3f/7116e782992abbd4fb6948488aec72078895e929a23078290739e8396fce/yarl-1.24.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f0a658a6d3fafee5c6f63c58f3e785c8c43c93fbc02bf9f2b6663f8185e0971f", size = 106507, upload-time = "2026-07-20T02:07:14.173Z" }, + { url = "https://files.pythonhosted.org/packages/33/90/d4d2d73ee78229cc889872eb8e085d8f5c6f51abdb178409fd9b23cf74fd/yarl-1.24.5-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4377407001ca3c057773f44d8ddd6358fa5f691407c1ba92210bd3cf8d9e4c95", size = 99219, upload-time = "2026-07-20T02:07:16.019Z" }, + { url = "https://files.pythonhosted.org/packages/3e/fa/a6df1a9bccd644eec00abee0dff4277416222cec435330fd1f2858523ec1/yarl-1.24.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7c0494a31a1ac5461a226e7947a9c9b78c44e1dc7185164fa7e9651557a5d9bc", size = 111804, upload-time = "2026-07-20T02:07:18.141Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9e/7b2a1f4bcc20e9447156dd2b1c4d01f70d9df0759025ee7d09a84ffae134/yarl-1.24.5-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a7cff474ab7cd149765bb784cf6d78b32e18e20473fb7bda860bce98ab58e9da", size = 110943, upload-time = "2026-07-20T02:07:20.06Z" }, + { url = "https://files.pythonhosted.org/packages/08/ff/22c92affb0f9b623ca753d27d968b5625b868f12c6378d049d55ae247643/yarl-1.24.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cbb833ccacdb5519eff9b8b71ee618cc2801c878e77e288775d77c3a2ced858a", size = 108251, upload-time = "2026-07-20T02:07:22.217Z" }, + { url = "https://files.pythonhosted.org/packages/45/44/5769b96298c1e195fb412997b6090af2a84105cf59c17613558a2d011d1f/yarl-1.24.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:82f75e05912e84b7a0fe57075d9c59de3cb352b928330f2eb69b2e1f54c3e1f0", size = 106025, upload-time = "2026-07-20T02:07:24.083Z" }, + { url = "https://files.pythonhosted.org/packages/4c/40/009e8e791fd9762c0e1567e69248acb4f49064597e1680874c16dd8bb798/yarl-1.24.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:16a2f5010280020e90f5330257e6944bc33e73593b136cc5a241e6c1dc292498", size = 106573, upload-time = "2026-07-20T02:07:26.248Z" }, + { url = "https://files.pythonhosted.org/packages/20/c6/b7480578f8a0a80946f36ad6df547ecec704f9ba69d2de60f8aa6f1c1cbf/yarl-1.24.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ffcd54362564dc1a30fb74d8b8a6e5a6b11ebd5e27266adc3b7427a21a6c9104", size = 100751, upload-time = "2026-07-20T02:07:28.098Z" }, + { url = "https://files.pythonhosted.org/packages/d4/27/4476f3360b91a48c5cf125e91f59a3bd35299d84a431a258d57f5977bb11/yarl-1.24.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0465ec8cedc2349b97a6b595ace64084a50c6e839eca40aa0626f38b8350e331", size = 111643, upload-time = "2026-07-20T02:07:30.88Z" }, + { url = "https://files.pythonhosted.org/packages/4c/4b/5cdd3e5ee944e8af31e52f6cd3d3af5fd7b937e036ccbbba2c9ffebede95/yarl-1.24.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4db9aecb141cb7a5447171b57aa1ed3a8fee06af40b992ffc31206c0b0121550", size = 106312, upload-time = "2026-07-20T02:07:33.06Z" }, + { url = "https://files.pythonhosted.org/packages/18/86/f406b0c2a6f99575de2da671ef47aa06f89a5be83a27a46971c3b86cecdb/yarl-1.24.5-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f540c013589084679a6c7fac07096b10159737918174f5dfc5e11bf5bca4dfe6", size = 110379, upload-time = "2026-07-20T02:07:35.155Z" }, + { url = "https://files.pythonhosted.org/packages/f0/6c/9f3adfbd3b30b4fa0f7ccb3a83eba2c1152d3fff554d535e640ba0f7ba2b/yarl-1.24.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a61834fb15d81322d872eaafd333838ae7c9cea84067f232656f75965933d047", size = 108497, upload-time = "2026-07-20T02:07:37.35Z" }, + { url = "https://files.pythonhosted.org/packages/dd/37/91eb2e5ca883a529c1b390348a74cd9fc0512171727f547ce70bfe02be5c/yarl-1.24.5-cp314-cp314t-win_amd64.whl", hash = "sha256:5c88e5815a49d289e599f3513aa7fde0bc2092ff188f99c940f007f90f53d104", size = 102450, upload-time = "2026-07-20T02:07:39.578Z" }, + { url = "https://files.pythonhosted.org/packages/bf/f4/ed5c402ac8fde4403ed3366c2716bfddc8a6677ebd59f3d62772cc7fe468/yarl-1.24.5-cp314-cp314t-win_arm64.whl", hash = "sha256:cf139c02f5f23ef6532040a30ff662c00a318c952334f211046b8e60b7f17688", size = 97222, upload-time = "2026-07-20T02:07:41.55Z" }, + { url = "https://files.pythonhosted.org/packages/61/02/962c1cbfc401a30c1d034dc67ff395f64b52302c6d62de556c1fca99acc0/yarl-1.24.5-py3-none-any.whl", hash = "sha256:a33700d13d9b7d84fd10947b09ff69fb9a792e519c8cb9764a3ca70baa6c23a7", size = 58612, upload-time = "2026-07-20T02:07:43.461Z" }, +] + +[[package]] +name = "zict" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d1/ac/3c494dd7ec5122cff8252c1a209b282c0867af029f805ae9befd73ae37eb/zict-3.0.0.tar.gz", hash = "sha256:e321e263b6a97aafc0790c3cfb3c04656b7066e6738c37fffcca95d803c9fba5", size = 33238, upload-time = "2023-04-17T21:41:16.041Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/ab/11a76c1e2126084fde2639514f24e6111b789b0bfa4fc6264a8975c7e1f1/zict-3.0.0-py2.py3-none-any.whl", hash = "sha256:5796e36bd0e0cc8cf0fbc1ace6a68912611c1dbd74750a3f3026b9b9d6a327ae", size = 43332, upload-time = "2023-04-17T21:41:13.444Z" }, +] + +[[package]] +name = "zipp" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/d8/eab98a517c14134c0b2eb4e2387bc5f457334293ec5d2dd3857ec2966802/zipp-4.1.0.tar.gz", hash = "sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602", size = 26214, upload-time = "2026-05-18T20:08:57.967Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl", hash = "sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f", size = 10238, upload-time = "2026-05-18T20:08:57.045Z" }, +]