tdanalysis 1.0.0__tar.gz → 1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tdanalysis-1.2/CHANGELOG.md +198 -0
- tdanalysis-1.2/PKG-INFO +369 -0
- tdanalysis-1.2/README.md +121 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/pyproject.toml +18 -4
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/_compat.py +17 -20
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/covariance/covariance_calc.py +27 -24
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/covariance/psd.py +159 -136
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/dtypes.py +7 -9
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/exe/config.py +1 -1
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/exe/runner.py +47 -21
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/exe/tdpipe.py +14 -9
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/fitting_factor.py +9 -3
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/forms/cd.py +0 -1
- tdanalysis-1.2/tdanalysis/forms/gs.py +388 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/forms/gs_batched.py +16 -17
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/forms/invld.py +2 -7
- tdanalysis-1.2/tdanalysis/forms/levinson.py +107 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/forms/llt.py +0 -1
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/forms/pcg.py +2 -3
- tdanalysis-1.2/tdanalysis/forms/sliding.py +517 -0
- tdanalysis-1.2/tdanalysis/forms/toeplitz_solver.py +156 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/inference/nr_injection.py +5 -3
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/likelihoods/multi/consistency_test.py +62 -7
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/likelihoods/multi/pe.py +102 -8
- tdanalysis-1.2/tdanalysis/likelihoods/reduced_batch.py +186 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/likelihoods/single/consistency_test.py +11 -5
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/likelihoods/single/pe.py +468 -285
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/utils/bilby.py +13 -13
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/utils/conditioning.py +42 -19
- tdanalysis-1.2/tdanalysis/utils/filters.py +128 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/utils/io.py +4 -4
- tdanalysis-1.2/tdanalysis/utils/mode_power_peak.py +109 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/utils/plotting.py +12 -14
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/utils/serialize.py +1 -1
- tdanalysis-1.2/tdanalysis/utils/subsample_align.py +172 -0
- tdanalysis-1.2/tdanalysis/waveforms/__init__.py +8 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/waveforms/nraasur.py +149 -209
- tdanalysis-1.2/tests/_toeplitz_refs.py +24 -0
- tdanalysis-1.2/tests/test_filters.py +104 -0
- tdanalysis-1.2/tests/test_gwtransient_batch.py +410 -0
- tdanalysis-1.2/tests/test_highpass.py +37 -0
- tdanalysis-1.2/tests/test_imr_pol_sky_timing.py +83 -0
- tdanalysis-1.2/tests/test_invlij_cache.py +65 -0
- tdanalysis-1.2/tests/test_mode_power_peak.py +127 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tests/test_pe_smoke.py +45 -52
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tests/test_psd_band_patching.py +125 -50
- tdanalysis-1.2/tests/test_shared_batch_generation.py +251 -0
- tdanalysis-1.2/tests/test_shared_ct_generation.py +205 -0
- tdanalysis-1.2/tests/test_shared_scalar_generation.py +97 -0
- tdanalysis-1.2/tests/test_sliding_forms.py +217 -0
- tdanalysis-1.2/tests/test_start_taper_only.py +44 -0
- tdanalysis-1.2/tests/test_subsample_alignment.py +474 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tests/test_taper_conditioning.py +21 -26
- tdanalysis-1.2/tests/test_toeplitz_generators.py +119 -0
- tdanalysis-1.2/tests/test_toeplitz_solver.py +83 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tests/test_whitening_backends.py +12 -8
- tdanalysis-1.0.0/PKG-INFO +0 -174
- tdanalysis-1.0.0/README.md +0 -126
- tdanalysis-1.0.0/tdanalysis/data/acorrs/A1_aplus_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/A1_aplus_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE20_1p0MW_Aplus_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE20_1p0MW_Aplus_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE20_1p0MW_aLIGO_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE20_1p0MW_aLIGO_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE20_1p5MW_Aplus_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE20_1p5MW_Aplus_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE20_1p5MW_aLIGO_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE20_1p5MW_aLIGO_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE20_gwforge_default_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE20_gwforge_default_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE40_1p0MW_Aplus_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE40_1p0MW_Aplus_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE40_1p0MW_aLIGO_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE40_1p0MW_aLIGO_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE40_1p5MW_Aplus_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE40_1p5MW_Aplus_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE40_1p5MW_aLIGO_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE40_1p5MW_aLIGO_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE40_gwforge_default_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/CE40_gwforge_default_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/ET1ET2ET3_ET_D_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/ET1ET2ET3_ET_D_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/ET1ET2ET3_cryo_10km_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/ET1ET2ET3_cryo_10km_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/ET1ET2ET3_cryo_15km_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/ET1ET2ET3_cryo_15km_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/PROVENANCE.md +0 -1143
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_A1_aplus_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_A1_aplus_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE20_1p0MW_Aplus_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE20_1p0MW_Aplus_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE20_1p0MW_aLIGO_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE20_1p0MW_aLIGO_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE20_1p5MW_Aplus_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE20_1p5MW_Aplus_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE20_1p5MW_aLIGO_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE20_1p5MW_aLIGO_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE20_gwforge_default_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE20_gwforge_default_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE40_1p0MW_Aplus_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE40_1p0MW_Aplus_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE40_1p0MW_aLIGO_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE40_1p0MW_aLIGO_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE40_1p5MW_Aplus_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE40_1p5MW_Aplus_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE40_1p5MW_aLIGO_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE40_1p5MW_aLIGO_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE40_gwforge_default_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_CE40_gwforge_default_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_ET1ET2ET3_ET_D_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_ET1ET2ET3_ET_D_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_ET1ET2ET3_cryo_10km_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_ET1ET2ET3_cryo_10km_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_ET1ET2ET3_cryo_15km_acorr_4s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/acorrs/half_ET1ET2ET3_cryo_15km_acorr_8s_4096.npy +0 -0
- tdanalysis-1.0.0/tdanalysis/data/detectors/A1.interferometer +0 -13
- tdanalysis-1.0.0/tdanalysis/data/detectors/CE20.ifo +0 -11
- tdanalysis-1.0.0/tdanalysis/data/detectors/CE40.ifo +0 -11
- tdanalysis-1.0.0/tdanalysis/data/detectors/ET.ifo +0 -12
- tdanalysis-1.0.0/tdanalysis/data/detectors/PROVENANCE.md +0 -230
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/CE20-asd.txt +0 -1000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/CE20km_1p0MW_Aplus_coat_strain.txt +0 -1000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/CE20km_1p0MW_aLIGO_coat_strain.txt +0 -1000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/CE20km_1p5MW_Aplus_coat_strain.txt +0 -1000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/CE20km_1p5MW_aLIGO_coat_strain.txt +0 -1000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/CE40-asd.txt +0 -1000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/CE40km_1p0MW_Aplus_coat_strain.txt +0 -1000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/CE40km_1p0MW_aLIGO_coat_strain.txt +0 -1000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/CE40km_1p5MW_Aplus_coat_strain.txt +0 -1000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/CE40km_1p5MW_aLIGO_coat_strain.txt +0 -1000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/ET-psd.txt +0 -3000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/ET_cryo_10km_psd.txt +0 -3000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/ET_cryo_15km_psd.txt +0 -3000
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/PROVENANCE.md +0 -130
- tdanalysis-1.0.0/tdanalysis/data/noise_curves/aplus.txt +0 -3000
- tdanalysis-1.0.0/tdanalysis/detectors/__init__.py +0 -89
- tdanalysis-1.0.0/tdanalysis/detectors/xg.py +0 -1040
- tdanalysis-1.0.0/tdanalysis/forms/gs.py +0 -200
- tdanalysis-1.0.0/tdanalysis/likelihoods/reduced_batch.py +0 -203
- tdanalysis-1.0.0/tdanalysis/waveforms/__init__.py +0 -9
- tdanalysis-1.0.0/tests/test_xg_acorrs.py +0 -488
- {tdanalysis-1.0.0 → tdanalysis-1.2}/LICENSE +0 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/NOTICE.md +0 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/__init__.py +0 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/gpu/gpu_matrix_multiplier.py +0 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/gpu/kernels.py +0 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/likelihoods/comparison/discriminators.py +0 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/priors/bbh.py +0 -0
- {tdanalysis-1.0.0 → tdanalysis-1.2}/tdanalysis/priors/bilby.py +0 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# Release notes
|
|
2
|
+
|
|
3
|
+
## tdanalysis 1.2
|
|
4
|
+
|
|
5
|
+
- No code changes from 1.1. Corrected credits and wording in the 1.1 notes below:
|
|
6
|
+
the consistency-test `log_likelihood(parameters)` fix is credited jointly to
|
|
7
|
+
Viviana Cáceres, the scalar shared generation and the Toeplitz API cite the work
|
|
8
|
+
of Sayan Neogi and Viviana Cáceres they build on, and the tdpipe high-pass is
|
|
9
|
+
described as a time-domain IIR filter. *(Vaishak Prasad)*
|
|
10
|
+
|
|
11
|
+
## tdanalysis 1.1
|
|
12
|
+
|
|
13
|
+
### Bug fixes
|
|
14
|
+
|
|
15
|
+
These change the likelihood of IMR and inspiral analyses (`segment` `'IMR'` or
|
|
16
|
+
`'I'`) with `conditioning='pol'`, including both parts of the consistency test.
|
|
17
|
+
Results produced with 1.0.0 should be rerun.
|
|
18
|
+
|
|
19
|
+
- **Detector delay at the sampled sky.** The arrival time at each detector was
|
|
20
|
+
computed from the injection (or trigger) sky position, while the antenna
|
|
21
|
+
pattern used the sampled one, so the timing between detectors never followed
|
|
22
|
+
the sky. On a zero-noise H1/L1/V1 injection at network SNR 30 the 90% sky area
|
|
23
|
+
goes from about 295 to about 6 deg². *(Vaishak Prasad)*
|
|
24
|
+
- **Sub-sample template placement.** The template peak and the target time were
|
|
25
|
+
both rounded to the sample grid, so the likelihood was a staircase in
|
|
26
|
+
`geocent_time`, the sky and every parameter that moves the peak. Placement is
|
|
27
|
+
now exact to a fraction of a sample (band-limited peak location plus a local
|
|
28
|
+
Lanczos shift). `subsample_alignment=False` restores the old placement.
|
|
29
|
+
*(Sayan Neogi)*
|
|
30
|
+
- **Merger located at the peak of |h₊ + i h×|.** The peak was the argmax of a
|
|
31
|
+
complex array, which is the peak of h₊ alone. For precessing systems this is
|
|
32
|
+
far from the merger, and it jumps between cycles. *(Sayan Neogi)*
|
|
33
|
+
- **`taper_start=True` no longer tapers the end of the template.** The end was
|
|
34
|
+
ramped to zero over the same `taper_duration` (0.0625 s) as the start whenever
|
|
35
|
+
the template ends inside the analysis window. NRSur7dq4 ends about 100 M after
|
|
36
|
+
the peak (about 35 ms at 70 M☉), so the ramp reached back before the merger and
|
|
37
|
+
scaled down the last cycles. On GW250114 this pulled the fit to a high-spin,
|
|
38
|
+
unequal-mass template with a stronger merger that made up for the attenuation. Runs
|
|
39
|
+
with `taper_start=True` (off by default) should be rerun. *(Vaishak Prasad)*
|
|
40
|
+
- **tdpipe downloads data at `[runner] sampling_rate`.** The download read a
|
|
41
|
+
separate `[runner] sample_rate` key, 4096 Hz by default, so a configuration that
|
|
42
|
+
set only `sampling_rate` to another value got data at 4096 Hz. A configuration
|
|
43
|
+
that still sets `sample_rate` now stops with an error. *(Vaishak Prasad)*
|
|
44
|
+
- **Consistency-test likelihoods accept `log_likelihood(parameters)`,** as the
|
|
45
|
+
spectroscopic consistency test already did. Every `analysis_type = CT` run
|
|
46
|
+
stopped with a `TypeError` when the sampler started.
|
|
47
|
+
*(Viviana Cáceres, Vaishak Prasad)*
|
|
48
|
+
|
|
49
|
+
### New features
|
|
50
|
+
|
|
51
|
+
Default behaviour is unchanged unless stated.
|
|
52
|
+
|
|
53
|
+
- **`peak_definition="mode_power"`** (`GWTransientTD`): place the template by
|
|
54
|
+
the peak of Σ_{l≤2} Σ_m |h_lm|², which does not depend on the frame, on phase or
|
|
55
|
+
polarization conventions, or on the viewing angle. The modes come from one lal
|
|
56
|
+
`ChooseTDModes` call and the polarizations are built from them as
|
|
57
|
+
Σ h_lm ₋₂Y_lm(inclination, π/2 − φ_ref), which reproduces `ChooseTDWaveform`
|
|
58
|
+
to about 1e-15 for IMRPhenomTPHM, SEOBNRv4PHM, NRSur7dq4 and IMRPhenomTHM. This
|
|
59
|
+
is checked once per likelihood. Approximants that do not follow that
|
|
60
|
+
convention (e.g. SEOBNRv4HM) are refused. The highest `l` in the sum is
|
|
61
|
+
`mode_power_lmax` (default 2). *(Sayan Neogi)*
|
|
62
|
+
- **High-pass of downloaded strain in tdpipe:**
|
|
63
|
+
`[runner] highpass = {"frequency": 10, "order": 8, "pad": 8}`. The filter is
|
|
64
|
+
an 8th-order Butterworth (IIR) high-pass applied in the time domain, forward
|
|
65
|
+
and backward (`scipy.signal.sosfiltfilt`), so it has zero phase and an
|
|
66
|
+
effective response 1/(1 + (f_c/f)^16). The strain is downloaded with `pad`
|
|
67
|
+
extra seconds on each side, filtered, and cropped back, so the filter's edge
|
|
68
|
+
transients fall outside the analysed data. This is needed when the covariance
|
|
69
|
+
comes from a band-limited ACF: on GW250114 the whitened power d^T C⁻¹ d / N
|
|
70
|
+
goes from 18–52 unfiltered to 0.83–0.86 off-source. *(Vaishak Prasad)*
|
|
71
|
+
- **`PSDToAutocorr(..., in_band_limit="cap")`:** clip narrow spectral lines from
|
|
72
|
+
above, instead of raising the floor of the band, when the in-band dynamic
|
|
73
|
+
range exceeds the target condition number. On real-event Welch PSDs at
|
|
74
|
+
κ = 1e8, raising the floor kept as little as 2% of the SNR². Clipping the
|
|
75
|
+
lines keeps all of it, with cond(C) ≤ 4.4e7. *(Vaishak Prasad)*
|
|
76
|
+
- **Dense-free Gohberg–Semencul:** with `qform_method='gs'`,
|
|
77
|
+
`whitening_backend='cpu-qform'`, an `autocorrelation` and no `invLij`, the GS
|
|
78
|
+
generators and the whitening come from a Levinson–Durbin recursion
|
|
79
|
+
(`tdanalysis.forms.levinson`) and no N × N matrix is formed. This holds for every
|
|
80
|
+
detector of a network and for each part of the consistency test. A supplied `invLij` is still used
|
|
81
|
+
as given. The fitting factor works from the autocorrelation the same way.
|
|
82
|
+
*(Viviana Cáceres)*
|
|
83
|
+
- **Logging:** progress and diagnostics go through Python's `logging` module,
|
|
84
|
+
one logger per module, instead of `waveformtools.message()`. Use
|
|
85
|
+
`logging.getLogger("tdanalysis").setLevel(...)` to control verbosity.
|
|
86
|
+
*(Viviana Cáceres)*
|
|
87
|
+
- **Faster network likelihoods:** `GWTransientTDMultiDetector`, and each part of
|
|
88
|
+
`IMRConsistencyMultiDetector`, convert the parameters and generate the
|
|
89
|
+
waveform once per call instead of once per detector
|
|
90
|
+
(`share_generation=True`, the default). H1/L1/V1: 24.2 → 9.4 ms per call, with
|
|
91
|
+
identical results. This extends the shared-generation design of Sayan Neogi's
|
|
92
|
+
batched likelihood (PR #3) to the scalar one. *(Vaishak Prasad)*
|
|
93
|
+
- **Batched generation shared across detectors** in the batched likelihood.
|
|
94
|
+
*(Sayan Neogi)*
|
|
95
|
+
- **Toeplitz solves and sliding quadratic forms**, a public API for other
|
|
96
|
+
time-domain likelihoods, exact to rounding (see the docs page *Toeplitz solves
|
|
97
|
+
and sliding quadratic forms*):
|
|
98
|
+
- `tdanalysis.forms.gs`: `gs_generators_from_acorr(acorr)` (the
|
|
99
|
+
Gohberg–Semencul generators by Levinson with iterative refinement),
|
|
100
|
+
`check_acorr_positive_definite`, `GSQuadraticForm.from_acorr(acorr)` (no
|
|
101
|
+
dense matrix, no parent object) and `apply_Cinv_batch(V)` for a block of
|
|
102
|
+
vectors. The GS form follows Kailath and
|
|
103
|
+
Sayed (eds.), *Fast Reliable Algorithms for Matrices with Structure*
|
|
104
|
+
(SIAM 1999).
|
|
105
|
+
- `tdanalysis.forms.toeplitz_solver.ToeplitzSolver(acorr)`: `C^{-1}` by
|
|
106
|
+
Cholesky for short windows and GS for long ones (`apply_Cinv`), plus
|
|
107
|
+
whitening (`whiten`, `color`, `logdet`) with the Cholesky factor of `C`.
|
|
108
|
+
- `tdanalysis.forms.sliding`: `sliding_data_term` and `sliding_self_terms`,
|
|
109
|
+
the data and self terms of complex multi-mode templates at every shift through
|
|
110
|
+
a window, with several exact methods and an automatic choice among them; a
|
|
111
|
+
`support=` argument for the template's extent, and `PrefixNotApplicable` when
|
|
112
|
+
the prefix method is requested where it does not apply.
|
|
113
|
+
- `tdanalysis.utils.filters`: the zero-phase high-pass, and exact FIR filters
|
|
114
|
+
from a sampled frequency response.
|
|
115
|
+
|
|
116
|
+
It uses the dense-free GS generators, kernels and Levinson–Durbin module of
|
|
117
|
+
Viviana Cáceres (above). *(Vaishak Prasad)*
|
|
118
|
+
|
|
119
|
+
### Renamed
|
|
120
|
+
|
|
121
|
+
Each concept has one name across the package. The old names are removed, with
|
|
122
|
+
no aliases. Code written against 1.0.0 needs these changes. *(Vaishak Prasad)*
|
|
123
|
+
|
|
124
|
+
- `PSDToAutocorrConfig`: field `sample_rate` → `sampling_rate`.
|
|
125
|
+
- `PSDToAutocorr.from_curve_file` and `PSDToAutocorr.curve_file_config` take the
|
|
126
|
+
config's field names: `ifo_name` → `ifo`, `fs` → `sampling_rate`,
|
|
127
|
+
`is_asd` → `psd_is_asd`, `taper_bins` → `patch_taper_bins`.
|
|
128
|
+
- `PSDToAutocorr` attributes: `times` → `tau`, `times_half` → `tau_half`,
|
|
129
|
+
`frequencies` → `frequencies_raw`, `psd_input` → `psd_raw`.
|
|
130
|
+
- `GWTransientTD`: `batched_response` → `get_detector_response_batch`,
|
|
131
|
+
attribute `prefer_batched_generation` → `prefer_batch_generation`, and the
|
|
132
|
+
argument `v_batch` of the batch methods (`log_likelihood_batch` included,
|
|
133
|
+
here and in the network likelihoods) → `parameters_batch`.
|
|
134
|
+
- `tdanalysis.forms.gs_batched`: `batched_apply_Cinv` → `apply_Cinv_batch`,
|
|
135
|
+
`batched_compute` → `compute_batch`, `batched_chisq` → `chisq_batch`; the
|
|
136
|
+
arguments `U`, `V` → `u`, `v`.
|
|
137
|
+
- `ReducedBatchEvaluationMixin` (`tdanalysis.likelihoods.reduced_batch`):
|
|
138
|
+
`unit_cube_to_sampling_batch` → `reduced_to_sampling_batch`,
|
|
139
|
+
`reduced_to_physical_batch` → `reduced_to_model_batch`.
|
|
140
|
+
- `tdanalysis.waveforms.nraasur`: `nraasur_available` →
|
|
141
|
+
`check_nraasur_available`, `NRAASurWaveformModel.native_reach` →
|
|
142
|
+
`get_native_start`, `hybridisation_report` → `get_hybridization_info`; the
|
|
143
|
+
argument `params_rows` of `get_td_waveform_batch` → `parameters_dict_list`.
|
|
144
|
+
- `tdanalysis.utils.io.create_gwpy_ts`: argument `fs` → `sampling_rate`.
|
|
145
|
+
|
|
146
|
+
Names introduced during 1.1 development, for readers of earlier drafts of these
|
|
147
|
+
notes:
|
|
148
|
+
|
|
149
|
+
- `tdanalysis.forms.gs`: `toeplitz_generators` → `gs_generators_from_acorr`,
|
|
150
|
+
`validate_covariance_acf` → `check_acorr_positive_definite`,
|
|
151
|
+
`GSQuadraticForm.from_acf(acf, validate=)` →
|
|
152
|
+
`GSQuadraticForm.from_acorr(acorr, check=)`, `apply_Cinv_many` →
|
|
153
|
+
`apply_Cinv_batch`, `gs_kernel_columns` → `gs_kernels_td`; the argument
|
|
154
|
+
`ycol` of `gs_kernels` → `y`.
|
|
155
|
+
- `ToeplitzSolver(acf)` → `ToeplitzSolver(acorr)`; `apply` → `apply_Cinv`,
|
|
156
|
+
attributes `n` → `n_samples`, `acf` → `acorr`.
|
|
157
|
+
- `tdanalysis.forms.sliding`: `METHODS` → `SLIDING_METHODS`,
|
|
158
|
+
`turn_on_inside_window` → `is_turn_on_inside_window`, argument `want_V` →
|
|
159
|
+
`compute_V`.
|
|
160
|
+
- `tdanalysis.utils.filters`: `fir_from_response_full(R_pos)` →
|
|
161
|
+
`fir_taps_from_response(response)`, `fir_reach(..., pieces)` →
|
|
162
|
+
`fir_max_lag(..., segments)`, `fir_truncate_exact(taps_full, reach)` →
|
|
163
|
+
`fir_truncate_at_max_lag(taps_full, max_lag)`, `fir_truncate(taps_full, L)` →
|
|
164
|
+
`fir_truncate(taps_full, half_length)`, and `L_neg`, `L_pos` → `n_neg`,
|
|
165
|
+
`n_pos`. Its `highpass_zero_phase` is the same function as the one in
|
|
166
|
+
`tdanalysis.utils.conditioning`, with arguments `(x, sampling_rate, f_corner,
|
|
167
|
+
order=8)` instead of `(x, fs, f_corner, order=8)`.
|
|
168
|
+
- Module `tdanalysis.utils.mode_power_anchor` → `tdanalysis.utils.mode_power_peak`:
|
|
169
|
+
`AnchoredArray` → `PeakTaggedArray` (attribute `anchor` → `peak_tag`),
|
|
170
|
+
`tag` → `tag_peak_index`, `anchor_index` → `get_peak_index`,
|
|
171
|
+
`polarizations_and_anchor` → `polarizations_and_peak_index`, `modes_dict` →
|
|
172
|
+
`get_modes_dict`.
|
|
173
|
+
- `GWTransientTD` keyword `anchor_lmax` → `mode_power_lmax` (also forwarded by
|
|
174
|
+
`GWTransientTDMultiDetector`).
|
|
175
|
+
- `GWTransientTD.compute_batch_polarizations` → `generate_polarizations_batch`;
|
|
176
|
+
the arguments `rows` → `parameters_dict_list` and `reject` → `reject_mask` of
|
|
177
|
+
it, `get_detector_response_batch` and `log_likelihood_batch`.
|
|
178
|
+
- `tdanalysis.utils.conditioning.highpass_zero_phase(x, sample_rate, frequency,
|
|
179
|
+
order=8)` → `highpass_zero_phase(x, sampling_rate, f_corner, order=8)`.
|
|
180
|
+
|
|
181
|
+
### Removed
|
|
182
|
+
|
|
183
|
+
- `tdanalysis.detectors` (next-generation detector definitions), with its noise
|
|
184
|
+
curves and autocorrelations under `tdanalysis/data/`, is no longer shipped.
|
|
185
|
+
Nothing else in the package uses it. *(Vaishak Prasad)*
|
|
186
|
+
|
|
187
|
+
### Known issues
|
|
188
|
+
|
|
189
|
+
- **Nested sampling can miss a likelihood mode at high SNR.** In zero-noise 15D
|
|
190
|
+
NRSur7dq4 injections run with dynesty acceptance-walk and 1000 live points this
|
|
191
|
+
happened twice. For a GW230814-like signal (L1 only, SNR 45) the posterior held
|
|
192
|
+
only one of the two sky positions that give the same signal in L1 (the
|
|
193
|
+
likelihood is equal at both, to 0.006). For a GW250114-like signal (H1/L1,
|
|
194
|
+
SNR 82) it settled in a nearby mode (inclination near π minus the injected
|
|
195
|
+
value, a shifted sky, a different φ_jl), and the injection's log likelihood is
|
|
196
|
+
above every posterior sample. The cause is the sampler settings; the likelihood
|
|
197
|
+
is correct. Check that the injected or best-fit point is not well above the
|
|
198
|
+
posterior samples in log likelihood, and compare runs with different seeds.
|
tdanalysis-1.2/PKG-INFO
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: tdanalysis
|
|
3
|
+
Version: 1.2
|
|
4
|
+
Summary: Time-domain parameter estimation and multi-segment consistency tests for gravitational-wave data
|
|
5
|
+
Project-URL: Homepage, https://github.com/vaishakp/tdanalysis
|
|
6
|
+
Author: Vaishak Prasad, Viviana Cáceres
|
|
7
|
+
Maintainer-email: Vaishak Prasad <vbp5193@psu.edu>
|
|
8
|
+
License-Expression: LicenseRef-PolyForm-Noncommercial-1.0.0-with-AI-terms
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
License-File: NOTICE.md
|
|
11
|
+
Keywords: consistency-test,gravitational-waves,parameter-estimation,time-domain
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
17
|
+
Requires-Python: >=3.11
|
|
18
|
+
Requires-Dist: bilby-pipe
|
|
19
|
+
Requires-Dist: bilby<3,>=2.4
|
|
20
|
+
Requires-Dist: corner
|
|
21
|
+
Requires-Dist: dask
|
|
22
|
+
Requires-Dist: dynesty>=2.1
|
|
23
|
+
Requires-Dist: gwpy>=3.0
|
|
24
|
+
Requires-Dist: h5py
|
|
25
|
+
Requires-Dist: lalsuite>=7.20
|
|
26
|
+
Requires-Dist: matplotlib>=3.7
|
|
27
|
+
Requires-Dist: numba
|
|
28
|
+
Requires-Dist: numpy>=1.24
|
|
29
|
+
Requires-Dist: pandas>=2.0
|
|
30
|
+
Requires-Dist: pycbc>=2.3
|
|
31
|
+
Requires-Dist: scipy>=1.10
|
|
32
|
+
Requires-Dist: spectools
|
|
33
|
+
Requires-Dist: statsmodels
|
|
34
|
+
Requires-Dist: tqdm
|
|
35
|
+
Requires-Dist: waveformtools
|
|
36
|
+
Provides-Extra: all
|
|
37
|
+
Requires-Dist: nrhjsurrogate; extra == 'all'
|
|
38
|
+
Requires-Dist: threadpoolctl; extra == 'all'
|
|
39
|
+
Requires-Dist: vlconf; extra == 'all'
|
|
40
|
+
Provides-Extra: gpu-legacy
|
|
41
|
+
Requires-Dist: torch; extra == 'gpu-legacy'
|
|
42
|
+
Provides-Extra: nr
|
|
43
|
+
Requires-Dist: nrhjsurrogate; extra == 'nr'
|
|
44
|
+
Provides-Extra: pipeline
|
|
45
|
+
Requires-Dist: threadpoolctl; extra == 'pipeline'
|
|
46
|
+
Requires-Dist: vlconf; extra == 'pipeline'
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# tdanalysis
|
|
50
|
+
|
|
51
|
+
Time-domain parameter estimation for gravitational-wave data, and the
|
|
52
|
+
inspiral-ringdown consistency test built on it.
|
|
53
|
+
|
|
54
|
+
The likelihood is `-½ δᵀ C⁻¹ δ` on a chosen data segment. `C` is the full noise
|
|
55
|
+
covariance built from the detector autocorrelation function, with no
|
|
56
|
+
diagonal-in-frequency PSD approximation. This makes short segments, and
|
|
57
|
+
segments with cut-out data or gaps, tractable. Ringdown analyses work with
|
|
58
|
+
such segments.
|
|
59
|
+
|
|
60
|
+
This is release v1. It is pure Python and installs from PyPI with no compiler.
|
|
61
|
+
It contains the parameter estimation core and the consistency test. The
|
|
62
|
+
batched GPU sampling code (v2) and the ringdown spectroscopy likelihoods (v3)
|
|
63
|
+
are separate, later releases of the same package.
|
|
64
|
+
|
|
65
|
+
## Install
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install tdanalysis
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The wheel is `py3-none-any`. Python 3.11 or newer.
|
|
72
|
+
|
|
73
|
+
Optional extras:
|
|
74
|
+
|
|
75
|
+
| Extra | Pulls in | For |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| `tdanalysis[pipeline]` | `vlconf`, `threadpoolctl` | the `tdanalysis` config-driven CLI |
|
|
78
|
+
| `tdanalysis[nr]` | `nrhjsurrogate` | the NRAASur action-angle waveform backend |
|
|
79
|
+
| `tdanalysis[gpu-legacy]` | `torch` | non-numba backends of the legacy matrix multiplier |
|
|
80
|
+
| `tdanalysis[all]` | the first two | |
|
|
81
|
+
|
|
82
|
+
Each of these is imported inside the function that first needs it, so the
|
|
83
|
+
library imports and runs without any of them.
|
|
84
|
+
|
|
85
|
+
`nrhjsurrogate` declares `requires-python >= 3.12`, so the `[nr]` extra
|
|
86
|
+
resolves only on 3.12 or newer, although the package itself supports 3.11. On
|
|
87
|
+
an older interpreter pip fails and gives this as the reason. This is intended:
|
|
88
|
+
a marker that installs nothing would leave the backend missing without any
|
|
89
|
+
message.
|
|
90
|
+
|
|
91
|
+
## Contents
|
|
92
|
+
|
|
93
|
+
* Parameter estimation. `tdanalysis.likelihoods.single.pe.GWTransientTD` for
|
|
94
|
+
one detector, `...likelihoods.multi.pe.GWTransientTDMultiDetector` for a
|
|
95
|
+
coherent network. Both are bilby `Likelihood`s and work in a bilby sampler run.
|
|
96
|
+
* Inspiral-ringdown consistency test.
|
|
97
|
+
`tdanalysis.likelihoods.single.consistency_test.InspiralRingdownConsistencyTD`
|
|
98
|
+
and `...likelihoods.multi.consistency_test.IMRConsistencyMultiDetector`
|
|
99
|
+
compare an inspiral-derived and a ringdown-derived remnant. Also
|
|
100
|
+
`tdanalysis.likelihoods.comparison.discriminators.ChiSquaredRingdown`.
|
|
101
|
+
* Quadratic forms and whiteners. `tdanalysis.forms`, selected with
|
|
102
|
+
`qform_method`: Gohberg-Semencul (`gs`, O(N log N) via FFT), preconditioned CG
|
|
103
|
+
(`pcg`), `invLD`, `Llt` and `CD`. `gs_batched` is the numpy batched chi-square
|
|
104
|
+
used by `reduced_batch`.
|
|
105
|
+
* Covariance and PSD handling. `tdanalysis.covariance`, including the band
|
|
106
|
+
patching and taper conditioning covered by the tests.
|
|
107
|
+
* Waveform backends. LAL and pycbc approximants, and the NRAASur action-angle
|
|
108
|
+
surrogate (`tdanalysis.waveforms.nraasur`). All are wrapped at the generator
|
|
109
|
+
level, so peak finding, tapers, padding, the segment crop and the projection
|
|
110
|
+
use the same code for every approximant. Parameters estimated with
|
|
111
|
+
different models are therefore comparable.
|
|
112
|
+
* A CLI. `tdanalysis --help`, a config-driven run driver.
|
|
113
|
+
|
|
114
|
+
v1 does not include the ringdown spectroscopy likelihoods and Kerr QNM
|
|
115
|
+
templates (v3), or the Kokkos GPU kernels and batched sampling (v2).
|
|
116
|
+
|
|
117
|
+
## Worked example
|
|
118
|
+
|
|
119
|
+
`tests/test_pe_smoke.py` is the reference example and the release check. It
|
|
120
|
+
builds a `GWTransientTD` with LAL waveform generation, conditioning and
|
|
121
|
+
projection, and a Gohberg-Semencul form from a Cholesky factor. Nothing is
|
|
122
|
+
mocked. It needs no data files, so it runs wherever the package installs.
|
|
123
|
+
|
|
124
|
+
See it for the constructor arguments in context. It checks that:
|
|
125
|
+
|
|
126
|
+
* the zero-noise truth is the maximum, and moving off it costs chi-square
|
|
127
|
+
* scalar and batched evaluation give the same number, so a posterior does not
|
|
128
|
+
depend on the batch size
|
|
129
|
+
* batching does not depend on row order, and a one-row batch matches the
|
|
130
|
+
scalar call
|
|
131
|
+
* the likelihood survives a pickle round trip, so a bilby multiprocessing pool
|
|
132
|
+
can carry it
|
|
133
|
+
|
|
134
|
+
## Tests
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
pip install tdanalysis
|
|
138
|
+
python -m pytest tests/ -q
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The shipped tests cover the `GWTransientTD` checks above, PSD band patching,
|
|
142
|
+
taper conditioning, agreement between whitening backends, and the 1.1 fixes
|
|
143
|
+
(sky-dependent detector delay, sub-sample placement, mode-power placement,
|
|
144
|
+
shared generation, high-pass).
|
|
145
|
+
|
|
146
|
+
## Licence
|
|
147
|
+
|
|
148
|
+
PolyForm Noncommercial License 1.0.0, with two additional terms. See
|
|
149
|
+
`LICENSE` for the text, and `NOTICE.md` for what it means in practice and for
|
|
150
|
+
the contributors to this release.
|
|
151
|
+
|
|
152
|
+
This is not an open-source licence, because it restricts the field of use.
|
|
153
|
+
|
|
154
|
+
* Noncommercial use is free and needs no permission: research, teaching,
|
|
155
|
+
and publishing results obtained with it. The licence grants this outright,
|
|
156
|
+
also where the funding is industrial.
|
|
157
|
+
* Commercial use needs a written licence, which may carry a fee or a
|
|
158
|
+
royalty: vbp5193@psu.edu.
|
|
159
|
+
* Training a model on this software is not permitted, commercial or not.
|
|
160
|
+
Building a surrogate or emulator of the waveforms and posteriors it produces
|
|
161
|
+
is ordinary research use and is allowed. Ingesting the source and
|
|
162
|
+
documentation into a general-purpose code or language model is not.
|
|
163
|
+
* AI tools may be used on this software only with training and retention
|
|
164
|
+
off. AI assistance is allowed; a configuration that would feed this code
|
|
165
|
+
into a training corpus is not.
|
|
166
|
+
|
|
167
|
+
The additional terms modify PolyForm, so the metadata declares
|
|
168
|
+
`LicenseRef-PolyForm-Noncommercial-1.0.0-with-AI-terms` and not the bare
|
|
169
|
+
PolyForm identifier.
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
# Release notes
|
|
173
|
+
|
|
174
|
+
## tdanalysis 1.2
|
|
175
|
+
|
|
176
|
+
- No code changes from 1.1. Corrected credits and wording in the 1.1 notes below:
|
|
177
|
+
the consistency-test `log_likelihood(parameters)` fix is credited jointly to
|
|
178
|
+
Viviana Cáceres, the scalar shared generation and the Toeplitz API cite the work
|
|
179
|
+
of Sayan Neogi and Viviana Cáceres they build on, and the tdpipe high-pass is
|
|
180
|
+
described as a time-domain IIR filter. *(Vaishak Prasad)*
|
|
181
|
+
|
|
182
|
+
## tdanalysis 1.1
|
|
183
|
+
|
|
184
|
+
### Bug fixes
|
|
185
|
+
|
|
186
|
+
These change the likelihood of IMR and inspiral analyses (`segment` `'IMR'` or
|
|
187
|
+
`'I'`) with `conditioning='pol'`, including both parts of the consistency test.
|
|
188
|
+
Results produced with 1.0.0 should be rerun.
|
|
189
|
+
|
|
190
|
+
- **Detector delay at the sampled sky.** The arrival time at each detector was
|
|
191
|
+
computed from the injection (or trigger) sky position, while the antenna
|
|
192
|
+
pattern used the sampled one, so the timing between detectors never followed
|
|
193
|
+
the sky. On a zero-noise H1/L1/V1 injection at network SNR 30 the 90% sky area
|
|
194
|
+
goes from about 295 to about 6 deg². *(Vaishak Prasad)*
|
|
195
|
+
- **Sub-sample template placement.** The template peak and the target time were
|
|
196
|
+
both rounded to the sample grid, so the likelihood was a staircase in
|
|
197
|
+
`geocent_time`, the sky and every parameter that moves the peak. Placement is
|
|
198
|
+
now exact to a fraction of a sample (band-limited peak location plus a local
|
|
199
|
+
Lanczos shift). `subsample_alignment=False` restores the old placement.
|
|
200
|
+
*(Sayan Neogi)*
|
|
201
|
+
- **Merger located at the peak of |h₊ + i h×|.** The peak was the argmax of a
|
|
202
|
+
complex array, which is the peak of h₊ alone. For precessing systems this is
|
|
203
|
+
far from the merger, and it jumps between cycles. *(Sayan Neogi)*
|
|
204
|
+
- **`taper_start=True` no longer tapers the end of the template.** The end was
|
|
205
|
+
ramped to zero over the same `taper_duration` (0.0625 s) as the start whenever
|
|
206
|
+
the template ends inside the analysis window. NRSur7dq4 ends about 100 M after
|
|
207
|
+
the peak (about 35 ms at 70 M☉), so the ramp reached back before the merger and
|
|
208
|
+
scaled down the last cycles. On GW250114 this pulled the fit to a high-spin,
|
|
209
|
+
unequal-mass template with a stronger merger that made up for the attenuation. Runs
|
|
210
|
+
with `taper_start=True` (off by default) should be rerun. *(Vaishak Prasad)*
|
|
211
|
+
- **tdpipe downloads data at `[runner] sampling_rate`.** The download read a
|
|
212
|
+
separate `[runner] sample_rate` key, 4096 Hz by default, so a configuration that
|
|
213
|
+
set only `sampling_rate` to another value got data at 4096 Hz. A configuration
|
|
214
|
+
that still sets `sample_rate` now stops with an error. *(Vaishak Prasad)*
|
|
215
|
+
- **Consistency-test likelihoods accept `log_likelihood(parameters)`,** as the
|
|
216
|
+
spectroscopic consistency test already did. Every `analysis_type = CT` run
|
|
217
|
+
stopped with a `TypeError` when the sampler started.
|
|
218
|
+
*(Viviana Cáceres, Vaishak Prasad)*
|
|
219
|
+
|
|
220
|
+
### New features
|
|
221
|
+
|
|
222
|
+
Default behaviour is unchanged unless stated.
|
|
223
|
+
|
|
224
|
+
- **`peak_definition="mode_power"`** (`GWTransientTD`): place the template by
|
|
225
|
+
the peak of Σ_{l≤2} Σ_m |h_lm|², which does not depend on the frame, on phase or
|
|
226
|
+
polarization conventions, or on the viewing angle. The modes come from one lal
|
|
227
|
+
`ChooseTDModes` call and the polarizations are built from them as
|
|
228
|
+
Σ h_lm ₋₂Y_lm(inclination, π/2 − φ_ref), which reproduces `ChooseTDWaveform`
|
|
229
|
+
to about 1e-15 for IMRPhenomTPHM, SEOBNRv4PHM, NRSur7dq4 and IMRPhenomTHM. This
|
|
230
|
+
is checked once per likelihood. Approximants that do not follow that
|
|
231
|
+
convention (e.g. SEOBNRv4HM) are refused. The highest `l` in the sum is
|
|
232
|
+
`mode_power_lmax` (default 2). *(Sayan Neogi)*
|
|
233
|
+
- **High-pass of downloaded strain in tdpipe:**
|
|
234
|
+
`[runner] highpass = {"frequency": 10, "order": 8, "pad": 8}`. The filter is
|
|
235
|
+
an 8th-order Butterworth (IIR) high-pass applied in the time domain, forward
|
|
236
|
+
and backward (`scipy.signal.sosfiltfilt`), so it has zero phase and an
|
|
237
|
+
effective response 1/(1 + (f_c/f)^16). The strain is downloaded with `pad`
|
|
238
|
+
extra seconds on each side, filtered, and cropped back, so the filter's edge
|
|
239
|
+
transients fall outside the analysed data. This is needed when the covariance
|
|
240
|
+
comes from a band-limited ACF: on GW250114 the whitened power d^T C⁻¹ d / N
|
|
241
|
+
goes from 18–52 unfiltered to 0.83–0.86 off-source. *(Vaishak Prasad)*
|
|
242
|
+
- **`PSDToAutocorr(..., in_band_limit="cap")`:** clip narrow spectral lines from
|
|
243
|
+
above, instead of raising the floor of the band, when the in-band dynamic
|
|
244
|
+
range exceeds the target condition number. On real-event Welch PSDs at
|
|
245
|
+
κ = 1e8, raising the floor kept as little as 2% of the SNR². Clipping the
|
|
246
|
+
lines keeps all of it, with cond(C) ≤ 4.4e7. *(Vaishak Prasad)*
|
|
247
|
+
- **Dense-free Gohberg–Semencul:** with `qform_method='gs'`,
|
|
248
|
+
`whitening_backend='cpu-qform'`, an `autocorrelation` and no `invLij`, the GS
|
|
249
|
+
generators and the whitening come from a Levinson–Durbin recursion
|
|
250
|
+
(`tdanalysis.forms.levinson`) and no N × N matrix is formed. This holds for every
|
|
251
|
+
detector of a network and for each part of the consistency test. A supplied `invLij` is still used
|
|
252
|
+
as given. The fitting factor works from the autocorrelation the same way.
|
|
253
|
+
*(Viviana Cáceres)*
|
|
254
|
+
- **Logging:** progress and diagnostics go through Python's `logging` module,
|
|
255
|
+
one logger per module, instead of `waveformtools.message()`. Use
|
|
256
|
+
`logging.getLogger("tdanalysis").setLevel(...)` to control verbosity.
|
|
257
|
+
*(Viviana Cáceres)*
|
|
258
|
+
- **Faster network likelihoods:** `GWTransientTDMultiDetector`, and each part of
|
|
259
|
+
`IMRConsistencyMultiDetector`, convert the parameters and generate the
|
|
260
|
+
waveform once per call instead of once per detector
|
|
261
|
+
(`share_generation=True`, the default). H1/L1/V1: 24.2 → 9.4 ms per call, with
|
|
262
|
+
identical results. This extends the shared-generation design of Sayan Neogi's
|
|
263
|
+
batched likelihood (PR #3) to the scalar one. *(Vaishak Prasad)*
|
|
264
|
+
- **Batched generation shared across detectors** in the batched likelihood.
|
|
265
|
+
*(Sayan Neogi)*
|
|
266
|
+
- **Toeplitz solves and sliding quadratic forms**, a public API for other
|
|
267
|
+
time-domain likelihoods, exact to rounding (see the docs page *Toeplitz solves
|
|
268
|
+
and sliding quadratic forms*):
|
|
269
|
+
- `tdanalysis.forms.gs`: `gs_generators_from_acorr(acorr)` (the
|
|
270
|
+
Gohberg–Semencul generators by Levinson with iterative refinement),
|
|
271
|
+
`check_acorr_positive_definite`, `GSQuadraticForm.from_acorr(acorr)` (no
|
|
272
|
+
dense matrix, no parent object) and `apply_Cinv_batch(V)` for a block of
|
|
273
|
+
vectors. The GS form follows Kailath and
|
|
274
|
+
Sayed (eds.), *Fast Reliable Algorithms for Matrices with Structure*
|
|
275
|
+
(SIAM 1999).
|
|
276
|
+
- `tdanalysis.forms.toeplitz_solver.ToeplitzSolver(acorr)`: `C^{-1}` by
|
|
277
|
+
Cholesky for short windows and GS for long ones (`apply_Cinv`), plus
|
|
278
|
+
whitening (`whiten`, `color`, `logdet`) with the Cholesky factor of `C`.
|
|
279
|
+
- `tdanalysis.forms.sliding`: `sliding_data_term` and `sliding_self_terms`,
|
|
280
|
+
the data and self terms of complex multi-mode templates at every shift through
|
|
281
|
+
a window, with several exact methods and an automatic choice among them; a
|
|
282
|
+
`support=` argument for the template's extent, and `PrefixNotApplicable` when
|
|
283
|
+
the prefix method is requested where it does not apply.
|
|
284
|
+
- `tdanalysis.utils.filters`: the zero-phase high-pass, and exact FIR filters
|
|
285
|
+
from a sampled frequency response.
|
|
286
|
+
|
|
287
|
+
It uses the dense-free GS generators, kernels and Levinson–Durbin module of
|
|
288
|
+
Viviana Cáceres (above). *(Vaishak Prasad)*
|
|
289
|
+
|
|
290
|
+
### Renamed
|
|
291
|
+
|
|
292
|
+
Each concept has one name across the package. The old names are removed, with
|
|
293
|
+
no aliases. Code written against 1.0.0 needs these changes. *(Vaishak Prasad)*
|
|
294
|
+
|
|
295
|
+
- `PSDToAutocorrConfig`: field `sample_rate` → `sampling_rate`.
|
|
296
|
+
- `PSDToAutocorr.from_curve_file` and `PSDToAutocorr.curve_file_config` take the
|
|
297
|
+
config's field names: `ifo_name` → `ifo`, `fs` → `sampling_rate`,
|
|
298
|
+
`is_asd` → `psd_is_asd`, `taper_bins` → `patch_taper_bins`.
|
|
299
|
+
- `PSDToAutocorr` attributes: `times` → `tau`, `times_half` → `tau_half`,
|
|
300
|
+
`frequencies` → `frequencies_raw`, `psd_input` → `psd_raw`.
|
|
301
|
+
- `GWTransientTD`: `batched_response` → `get_detector_response_batch`,
|
|
302
|
+
attribute `prefer_batched_generation` → `prefer_batch_generation`, and the
|
|
303
|
+
argument `v_batch` of the batch methods (`log_likelihood_batch` included,
|
|
304
|
+
here and in the network likelihoods) → `parameters_batch`.
|
|
305
|
+
- `tdanalysis.forms.gs_batched`: `batched_apply_Cinv` → `apply_Cinv_batch`,
|
|
306
|
+
`batched_compute` → `compute_batch`, `batched_chisq` → `chisq_batch`; the
|
|
307
|
+
arguments `U`, `V` → `u`, `v`.
|
|
308
|
+
- `ReducedBatchEvaluationMixin` (`tdanalysis.likelihoods.reduced_batch`):
|
|
309
|
+
`unit_cube_to_sampling_batch` → `reduced_to_sampling_batch`,
|
|
310
|
+
`reduced_to_physical_batch` → `reduced_to_model_batch`.
|
|
311
|
+
- `tdanalysis.waveforms.nraasur`: `nraasur_available` →
|
|
312
|
+
`check_nraasur_available`, `NRAASurWaveformModel.native_reach` →
|
|
313
|
+
`get_native_start`, `hybridisation_report` → `get_hybridization_info`; the
|
|
314
|
+
argument `params_rows` of `get_td_waveform_batch` → `parameters_dict_list`.
|
|
315
|
+
- `tdanalysis.utils.io.create_gwpy_ts`: argument `fs` → `sampling_rate`.
|
|
316
|
+
|
|
317
|
+
Names introduced during 1.1 development, for readers of earlier drafts of these
|
|
318
|
+
notes:
|
|
319
|
+
|
|
320
|
+
- `tdanalysis.forms.gs`: `toeplitz_generators` → `gs_generators_from_acorr`,
|
|
321
|
+
`validate_covariance_acf` → `check_acorr_positive_definite`,
|
|
322
|
+
`GSQuadraticForm.from_acf(acf, validate=)` →
|
|
323
|
+
`GSQuadraticForm.from_acorr(acorr, check=)`, `apply_Cinv_many` →
|
|
324
|
+
`apply_Cinv_batch`, `gs_kernel_columns` → `gs_kernels_td`; the argument
|
|
325
|
+
`ycol` of `gs_kernels` → `y`.
|
|
326
|
+
- `ToeplitzSolver(acf)` → `ToeplitzSolver(acorr)`; `apply` → `apply_Cinv`,
|
|
327
|
+
attributes `n` → `n_samples`, `acf` → `acorr`.
|
|
328
|
+
- `tdanalysis.forms.sliding`: `METHODS` → `SLIDING_METHODS`,
|
|
329
|
+
`turn_on_inside_window` → `is_turn_on_inside_window`, argument `want_V` →
|
|
330
|
+
`compute_V`.
|
|
331
|
+
- `tdanalysis.utils.filters`: `fir_from_response_full(R_pos)` →
|
|
332
|
+
`fir_taps_from_response(response)`, `fir_reach(..., pieces)` →
|
|
333
|
+
`fir_max_lag(..., segments)`, `fir_truncate_exact(taps_full, reach)` →
|
|
334
|
+
`fir_truncate_at_max_lag(taps_full, max_lag)`, `fir_truncate(taps_full, L)` →
|
|
335
|
+
`fir_truncate(taps_full, half_length)`, and `L_neg`, `L_pos` → `n_neg`,
|
|
336
|
+
`n_pos`. Its `highpass_zero_phase` is the same function as the one in
|
|
337
|
+
`tdanalysis.utils.conditioning`, with arguments `(x, sampling_rate, f_corner,
|
|
338
|
+
order=8)` instead of `(x, fs, f_corner, order=8)`.
|
|
339
|
+
- Module `tdanalysis.utils.mode_power_anchor` → `tdanalysis.utils.mode_power_peak`:
|
|
340
|
+
`AnchoredArray` → `PeakTaggedArray` (attribute `anchor` → `peak_tag`),
|
|
341
|
+
`tag` → `tag_peak_index`, `anchor_index` → `get_peak_index`,
|
|
342
|
+
`polarizations_and_anchor` → `polarizations_and_peak_index`, `modes_dict` →
|
|
343
|
+
`get_modes_dict`.
|
|
344
|
+
- `GWTransientTD` keyword `anchor_lmax` → `mode_power_lmax` (also forwarded by
|
|
345
|
+
`GWTransientTDMultiDetector`).
|
|
346
|
+
- `GWTransientTD.compute_batch_polarizations` → `generate_polarizations_batch`;
|
|
347
|
+
the arguments `rows` → `parameters_dict_list` and `reject` → `reject_mask` of
|
|
348
|
+
it, `get_detector_response_batch` and `log_likelihood_batch`.
|
|
349
|
+
- `tdanalysis.utils.conditioning.highpass_zero_phase(x, sample_rate, frequency,
|
|
350
|
+
order=8)` → `highpass_zero_phase(x, sampling_rate, f_corner, order=8)`.
|
|
351
|
+
|
|
352
|
+
### Removed
|
|
353
|
+
|
|
354
|
+
- `tdanalysis.detectors` (next-generation detector definitions), with its noise
|
|
355
|
+
curves and autocorrelations under `tdanalysis/data/`, is no longer shipped.
|
|
356
|
+
Nothing else in the package uses it. *(Vaishak Prasad)*
|
|
357
|
+
|
|
358
|
+
### Known issues
|
|
359
|
+
|
|
360
|
+
- **Nested sampling can miss a likelihood mode at high SNR.** In zero-noise 15D
|
|
361
|
+
NRSur7dq4 injections run with dynesty acceptance-walk and 1000 live points this
|
|
362
|
+
happened twice. For a GW230814-like signal (L1 only, SNR 45) the posterior held
|
|
363
|
+
only one of the two sky positions that give the same signal in L1 (the
|
|
364
|
+
likelihood is equal at both, to 0.006). For a GW250114-like signal (H1/L1,
|
|
365
|
+
SNR 82) it settled in a nearby mode (inclination near π minus the injected
|
|
366
|
+
value, a shifted sky, a different φ_jl), and the injection's log likelihood is
|
|
367
|
+
above every posterior sample. The cause is the sampler settings; the likelihood
|
|
368
|
+
is correct. Check that the injected or best-fit point is not well above the
|
|
369
|
+
posterior samples in log likelihood, and compare runs with different seeds.
|