PyAETNA 4.0.0__py3-none-any.whl

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.
Files changed (96) hide show
  1. PyAETNA/__init__.py +9 -0
  2. PyAETNA/__main__.py +5 -0
  3. PyAETNA/_device_config.py +57 -0
  4. PyAETNA/_xla_flags.py +50 -0
  5. PyAETNA/body_models.py +2336 -0
  6. PyAETNA/cli.py +52 -0
  7. PyAETNA/gp.py +791 -0
  8. PyAETNA/gp_parallel.py +172 -0
  9. PyAETNA/kernels/factory.py +823 -0
  10. PyAETNA/kernels/multichannel.py +417 -0
  11. PyAETNA/logger.py +73 -0
  12. PyAETNA/model_utils.py +282 -0
  13. PyAETNA/outputs.py +260 -0
  14. PyAETNA/physics/__init__.py +6 -0
  15. PyAETNA/physics/orbital.py +479 -0
  16. PyAETNA/physics/plotting.py +767 -0
  17. PyAETNA/physics/priors.py +89 -0
  18. PyAETNA/physics/spectra.py +483 -0
  19. PyAETNA/physics/stellar.py +369 -0
  20. PyAETNA/planet_phys.py +1414 -0
  21. PyAETNA/provenance.py +163 -0
  22. PyAETNA/py.typed +0 -0
  23. PyAETNA/reporting/__init__.py +64 -0
  24. PyAETNA/reporting/confidence_bands.py +1238 -0
  25. PyAETNA/reporting/corner_plot.py +1204 -0
  26. PyAETNA/reporting/data_validation.py +116 -0
  27. PyAETNA/reporting/diagnostics.py +580 -0
  28. PyAETNA/reporting/gp_plotting.py +942 -0
  29. PyAETNA/reporting/grid_builder.py +1257 -0
  30. PyAETNA/reporting/model_components.py +894 -0
  31. PyAETNA/reporting/model_math.py +1096 -0
  32. PyAETNA/reporting/multigp_plots.py +1681 -0
  33. PyAETNA/reporting/noise_plots.py +406 -0
  34. PyAETNA/reporting/panel_detrended.py +188 -0
  35. PyAETNA/reporting/panel_nontime_residuals.py +467 -0
  36. PyAETNA/reporting/panel_overlay.py +745 -0
  37. PyAETNA/reporting/panel_residuals.py +109 -0
  38. PyAETNA/reporting/param_sorting.py +155 -0
  39. PyAETNA/reporting/pdf_report.py +2119 -0
  40. PyAETNA/reporting/periodogram_plots.py +1467 -0
  41. PyAETNA/reporting/phase_plots.py +1529 -0
  42. PyAETNA/reporting/plot_data_prep.py +1123 -0
  43. PyAETNA/reporting/plot_models.py +177 -0
  44. PyAETNA/reporting/plot_styling.py +468 -0
  45. PyAETNA/reporting/residual_plotting.py +419 -0
  46. PyAETNA/reporting/trend_detection.py +128 -0
  47. PyAETNA/reporting/ttv_plots.py +1226 -0
  48. PyAETNA/run.py +813 -0
  49. PyAETNA/sampling/__init__.py +19 -0
  50. PyAETNA/sampling/centering.py +331 -0
  51. PyAETNA/sampling/config/parser/__init__.py +602 -0
  52. PyAETNA/sampling/config/parser/_constants.py +14 -0
  53. PyAETNA/sampling/config/parser/detrending.py +825 -0
  54. PyAETNA/sampling/config/parser/gp.py +386 -0
  55. PyAETNA/sampling/config/parser/multigp.py +697 -0
  56. PyAETNA/sampling/config/parser/ordering.py +154 -0
  57. PyAETNA/sampling/config/parser/planets.py +699 -0
  58. PyAETNA/sampling/config/parser/prior_refs.py +157 -0
  59. PyAETNA/sampling/config/parser/scoping.py +465 -0
  60. PyAETNA/sampling/config/parser/star.py +647 -0
  61. PyAETNA/sampling/config/priors.py +266 -0
  62. PyAETNA/sampling/config/section.py +51 -0
  63. PyAETNA/sampling/config/validation.py +231 -0
  64. PyAETNA/sampling/data.py +243 -0
  65. PyAETNA/sampling/eccentricity.py +65 -0
  66. PyAETNA/sampling/energy.py +431 -0
  67. PyAETNA/sampling/engine/checkpoint.py +461 -0
  68. PyAETNA/sampling/engine/context.py +24 -0
  69. PyAETNA/sampling/engine/convergence.py +126 -0
  70. PyAETNA/sampling/engine/data_loader.py +335 -0
  71. PyAETNA/sampling/engine/eiv.py +458 -0
  72. PyAETNA/sampling/engine/ensemble_kernels.py +238 -0
  73. PyAETNA/sampling/engine/exceptions.py +47 -0
  74. PyAETNA/sampling/engine/execution.py +500 -0
  75. PyAETNA/sampling/engine/numpyro_model.py +1031 -0
  76. PyAETNA/sampling/engine/runner.py +150 -0
  77. PyAETNA/sampling/engine/sampler_settings.py +192 -0
  78. PyAETNA/sampling/engine/sampler_utils.py +404 -0
  79. PyAETNA/sampling/engine/sampling_logging.py +292 -0
  80. PyAETNA/sampling/engine/sampling_utils.py +707 -0
  81. PyAETNA/sampling/model/core.py +774 -0
  82. PyAETNA/sampling/model/detrending.py +315 -0
  83. PyAETNA/sampling/nested_sampling.py +1457 -0
  84. PyAETNA/sampling/peaks.py +1225 -0
  85. PyAETNA/sampling/precision.py +393 -0
  86. PyAETNA/sampling/protocols.py +140 -0
  87. PyAETNA/sampling/utils.py +299 -0
  88. PyAETNA/utils/__init__.py +4 -0
  89. PyAETNA/utils/constants.py +26 -0
  90. PyAETNA/version.py +21 -0
  91. pyaetna-4.0.0.dist-info/METADATA +269 -0
  92. pyaetna-4.0.0.dist-info/RECORD +96 -0
  93. pyaetna-4.0.0.dist-info/WHEEL +5 -0
  94. pyaetna-4.0.0.dist-info/entry_points.txt +2 -0
  95. pyaetna-4.0.0.dist-info/licenses/LICENSE +21 -0
  96. pyaetna-4.0.0.dist-info/top_level.txt +1 -0
PyAETNA/__init__.py ADDED
@@ -0,0 +1,9 @@
1
+ """PyAETNA: JAX-accelerated modelling of exoplanet light curves and radial velocities."""
2
+
3
+ from ._xla_flags import apply_default_xla_flags
4
+ from .version import __version__
5
+
6
+ # Before JAX initialises its GPU backend (see PyAETNA._xla_flags).
7
+ apply_default_xla_flags()
8
+
9
+ __all__ = ["__version__"]
PyAETNA/__main__.py ADDED
@@ -0,0 +1,5 @@
1
+ """``python -m PyAETNA config.yaml``: same as the ``pyaetna`` command."""
2
+
3
+ from .cli import main
4
+
5
+ main()
@@ -0,0 +1,57 @@
1
+ """Configure JAX device count and BLAS threads for CPU parallelism.
2
+
3
+ This module MUST be imported before any JAX operations to enable multi-core
4
+ CPU parallelism. It sets XLA_FLAGS to create virtual devices for parallel
5
+ MCMC chains.
6
+
7
+ IMPORTANT: This configuration ONLY affects the CPU backend. GPU devices are
8
+ still detected and preferred if available. The --xla_force_host_platform_device_count
9
+ flag does not prevent JAX from using GPUs when present on the system.
10
+ """
11
+
12
+ import os
13
+
14
+ # Configure host CPU device count for JAX before importing it.
15
+ # Use the machine's CPU count, and at least _MIN_HOST_DEVICES, by default, but
16
+ # allow explicit override via env var PYAETNA_XLA_FORCE_HOST_PLATFORM_DEVICE_COUNT.
17
+ # Nested sampling on a CPU gives each of its slice chains (50 by default) its own
18
+ # device, which is fastest even when there are fewer cores than devices
19
+ # (sampling/nested_sampling.py, cpu_chain_mesh).
20
+ # NOTE: This setting does NOT affect GPU detection or usage.
21
+ _MIN_HOST_DEVICES = 64
22
+ _cpu_count = os.cpu_count() or 1
23
+ _default = max(_cpu_count, _MIN_HOST_DEVICES)
24
+ _override = os.environ.get("PYAETNA_XLA_FORCE_HOST_PLATFORM_DEVICE_COUNT")
25
+ try:
26
+ _n_devices = max(1, int(_override)) if _override is not None else _default
27
+ except ValueError:
28
+ _n_devices = _default
29
+
30
+ # One thread per BLAS/LAPACK call, unless the user set it. On a CPU, JAX runs dense linear algebra (Cholesky
31
+ # factorisations and triangular solves of dense GPs) as LAPACK calls into OpenBLAS; with many host devices
32
+ # calling it at once, a multithreaded OpenBLAS oversubscribes the CPU and its threads contend. On the K2-100
33
+ # multi-GP benchmark (8 logical CPUs, 50 chains on host devices) one thread made nested sampling 65 times
34
+ # faster (98 -> 6.4e3 likelihood evaluations per second). Must be set before NumPy is first imported.
35
+ for _var in ("OPENBLAS_NUM_THREADS", "MKL_NUM_THREADS", "OMP_NUM_THREADS"):
36
+ os.environ.setdefault(_var, "1")
37
+
38
+ _flag = f"--xla_force_host_platform_device_count={_n_devices}"
39
+ _existing = os.environ.get("XLA_FLAGS", "")
40
+ if "--xla_force_host_platform_device_count=" not in _existing:
41
+ os.environ["XLA_FLAGS"] = (_existing + " " + _flag).strip()
42
+
43
+ # Longer timeouts for collectives between host devices, unless the user set them. The slice chains of a
44
+ # nested-sampling iteration meet at an all-gather; XLA aborts the process (SIGABRT) when a device arrives more
45
+ # than ~60 s after the others (warning after 20 s). With 50 chains on few cores and an expensive likelihood a
46
+ # chain can legitimately be that late, so warn after 5 min and abort only after an hour (an interrupted
47
+ # nested-sampling run resumes from its checkpoint). Note (2026-09-30, under investigation): on the laptop, TOI-216
48
+ # (a GP on 196k points, 50 chains on 12 cores) twice stopped with two devices that never reached the all-gather
49
+ # while the CPU was idle, i.e. a deadlock, not a late chain; the same run on 12 cores of the server completed.
50
+ _COLLECTIVE_TIMEOUTS = {
51
+ "--xla_cpu_collective_call_warn_stuck_timeout_seconds": "300",
52
+ "--xla_cpu_collective_call_terminate_timeout_seconds": "3600",
53
+ }
54
+ for _name, _value in _COLLECTIVE_TIMEOUTS.items():
55
+ _existing = os.environ.get("XLA_FLAGS", "")
56
+ if f"{_name}=" not in _existing:
57
+ os.environ["XLA_FLAGS"] = f"{_existing} {_name}={_value}".strip()
PyAETNA/_xla_flags.py ADDED
@@ -0,0 +1,50 @@
1
+ """XLA compiler flags PyAETNA needs on GPU.
2
+
3
+ Applied when the package is imported, i.e. before JAX initialises its GPU
4
+ backend, which is when ``XLA_FLAGS`` is read. A flag the user already set in
5
+ ``XLA_FLAGS`` is never overridden.
6
+
7
+ ``--xla_gpu_experimental_enable_fusion_autotuner=false``
8
+ XLA's GPU *fusion* autotuner can explode on some fused kernels once the
9
+ batch is large enough: vectorising the Pi Men likelihood (four
10
+ instruments, 223 RVs) over 500 points drove compilation above 23 GB of
11
+ host RAM until the kernel killed the process. The threshold depends on
12
+ the model and the code version: with JAX 0.11.0 and the eccentric Pi Men
13
+ model, 302 points compile in 1.9 s with 1.7 GB, while 303 were killed at an
14
+ 8 GB cap after 64 s. Nested sampling evaluates its 500
15
+ initial live points in one batch, so it hit this directly. Disabling
16
+ only the fusion autotuner removes the problem and leaves GEMM autotuning
17
+ on: on K2-140 and on a dense GP the run time is unchanged (turning off
18
+ all autotuning with ``--xla_gpu_autotune_level=0`` would make a
19
+ small-batch dense GP ~30% slower). To re-enable it, set the flag to
20
+ ``true`` in ``XLA_FLAGS`` before importing PyAETNA. Reported upstream as
21
+ https://github.com/openxla/xla/issues/49549 (still present in JAX 0.11.2),
22
+ with a standalone reproducer; possibly related: tue-bmd/zea#599 (compile
23
+ time exploding above a grid size, same workaround). Fixed upstream on
24
+ 2026-09-29 by XLA commit c644af1 ("Prevent exponential op duplication in
25
+ TritonXLAFoldTransposePass"): transpose folding cloned the operations of
26
+ reconvergent elementwise graphs into a tree, so compile time and memory
27
+ grew exponentially. Keep the flag until the minimum supported JAX
28
+ includes that commit, then check the reproducer and remove it.
29
+ """
30
+
31
+ from __future__ import annotations
32
+
33
+ import os
34
+
35
+ _DEFAULT_FLAGS = {
36
+ "--xla_gpu_experimental_enable_fusion_autotuner": "false",
37
+ }
38
+
39
+
40
+ def apply_default_xla_flags(environ: dict[str, str] | None = None) -> None:
41
+ """Append PyAETNA's default XLA flags unless the user already set them."""
42
+ env = os.environ if environ is None else environ
43
+ existing = env.get("XLA_FLAGS", "")
44
+ extra = [
45
+ f"{flag}={value}"
46
+ for flag, value in _DEFAULT_FLAGS.items()
47
+ if f"{flag}=" not in existing
48
+ ]
49
+ if extra:
50
+ env["XLA_FLAGS"] = " ".join([existing, *extra]).strip()