squishyplanet 0.2.0__tar.gz → 0.2.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.
- {squishyplanet-0.2.0/squishyplanet.egg-info → squishyplanet-0.2.2}/PKG-INFO +15 -17
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/README.md +14 -16
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/pyproject.toml +1 -1
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/__init__.py +1 -1
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/kepler.py +69 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/parametric_ellipse.py +103 -67
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/polynomial_limb_darkened_transit.py +4 -1
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/oblate_system.py +21 -4
- {squishyplanet-0.2.0 → squishyplanet-0.2.2/squishyplanet.egg-info}/PKG-INFO +15 -17
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/tests/test_projected_parameterization.py +9 -4
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/LICENSE +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/setup.cfg +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/setup.py +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/__init__.py +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/greens_basis_transform.py +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/phase_curve_utils.py +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/planet_2d.py +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/planet_3d.py +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet.egg-info/SOURCES.txt +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet.egg-info/dependency_links.txt +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet.egg-info/requires.txt +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet.egg-info/top_level.txt +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/tests/test_against_jaxoplanet_transit.py +0 -0
- {squishyplanet-0.2.0 → squishyplanet-0.2.2}/tests/test_oblate_system.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: squishyplanet
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A package for dealing with non-spherical exoplanets
|
|
5
5
|
Author-email: Ben Cassese <b.c.cassese@columbia.edu>
|
|
6
6
|
License: MIT
|
|
@@ -26,11 +26,12 @@ Requires-Dist: ipykernel
|
|
|
26
26
|
|
|
27
27
|
# squishyplanet
|
|
28
28
|
|
|
29
|
-
[](https://doi.org/10.21105/joss.06972)
|
|
30
30
|
[](https://squishyplanet.readthedocs.io/en/latest/?badge=latest)
|
|
31
31
|

|
|
32
32
|
[](https://coveralls.io/github/ben-cassese/squishyplanet?branch=main)
|
|
33
33
|

|
|
34
|
+
[](https://opensource.org/licenses/MIT)
|
|
34
35
|
|
|
35
36
|
A package for modeling non-spherical exoplanets.
|
|
36
37
|
|
|
@@ -52,23 +53,20 @@ See the [installation instructions](https://squishyplanet.readthedocs.io/en/late
|
|
|
52
53
|
|
|
53
54
|
## Attribution and License
|
|
54
55
|
|
|
55
|
-
[](https://opensource.org/licenses/MIT)
|
|
56
|
-
[hopefully joss badge]
|
|
57
56
|
|
|
58
|
-
``squishyplanet`` is made freely available under the MIT License. If you use this code in your research, please cite the accompanying JOSS paper
|
|
57
|
+
``squishyplanet`` is made freely available under the MIT License. If you use this code in your research, please cite the accompanying JOSS paper:
|
|
59
58
|
|
|
60
59
|
```
|
|
61
|
-
@article{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
journal = {}
|
|
60
|
+
@article{squishyplanet,
|
|
61
|
+
author = {{Cassese}, Ben and {Vega}, Justin and {Lu}, Tiger and {Rice}, Malena and {Poddar}, Avishi and {Kipping}, David},
|
|
62
|
+
doi = {10.21105/joss.06972},
|
|
63
|
+
journal = {Journal of Open Source Software},
|
|
64
|
+
month = aug,
|
|
65
|
+
number = {100},
|
|
66
|
+
pages = {6972},
|
|
67
|
+
title = {{squishyplanet: modeling transits of non-spherical exoplanets in JAX}},
|
|
68
|
+
url = {https://joss.theoj.org/papers/10.21105/joss.06972},
|
|
69
|
+
volume = {9},
|
|
70
|
+
year = {2024}
|
|
73
71
|
}
|
|
74
72
|
```
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# squishyplanet
|
|
2
2
|
|
|
3
|
-
[](https://doi.org/10.21105/joss.06972)
|
|
4
4
|
[](https://squishyplanet.readthedocs.io/en/latest/?badge=latest)
|
|
5
5
|

|
|
6
6
|
[](https://coveralls.io/github/ben-cassese/squishyplanet?branch=main)
|
|
7
7
|

|
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
|
8
9
|
|
|
9
10
|
A package for modeling non-spherical exoplanets.
|
|
10
11
|
|
|
@@ -26,23 +27,20 @@ See the [installation instructions](https://squishyplanet.readthedocs.io/en/late
|
|
|
26
27
|
|
|
27
28
|
## Attribution and License
|
|
28
29
|
|
|
29
|
-
[](https://opensource.org/licenses/MIT)
|
|
30
|
-
[hopefully joss badge]
|
|
31
30
|
|
|
32
|
-
``squishyplanet`` is made freely available under the MIT License. If you use this code in your research, please cite the accompanying JOSS paper
|
|
31
|
+
``squishyplanet`` is made freely available under the MIT License. If you use this code in your research, please cite the accompanying JOSS paper:
|
|
33
32
|
|
|
34
33
|
```
|
|
35
|
-
@article{
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
journal = {}
|
|
34
|
+
@article{squishyplanet,
|
|
35
|
+
author = {{Cassese}, Ben and {Vega}, Justin and {Lu}, Tiger and {Rice}, Malena and {Poddar}, Avishi and {Kipping}, David},
|
|
36
|
+
doi = {10.21105/joss.06972},
|
|
37
|
+
journal = {Journal of Open Source Software},
|
|
38
|
+
month = aug,
|
|
39
|
+
number = {100},
|
|
40
|
+
pages = {6972},
|
|
41
|
+
title = {{squishyplanet: modeling transits of non-spherical exoplanets in JAX}},
|
|
42
|
+
url = {https://joss.theoj.org/papers/10.21105/joss.06972},
|
|
43
|
+
volume = {9},
|
|
44
|
+
year = {2024}
|
|
47
45
|
}
|
|
48
46
|
```
|
|
@@ -177,3 +177,72 @@ def skypos(a, e, f, Omega, i, omega, **kwargs):
|
|
|
177
177
|
_z(a, e, f, Omega, i, omega),
|
|
178
178
|
]
|
|
179
179
|
)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def true_anomaly_at_transit_center(e, i, omega):
|
|
183
|
+
"""
|
|
184
|
+
Computes the true anomaly at the instant of minimum star/planet separation.
|
|
185
|
+
|
|
186
|
+
Uses equations 4.12-4.18 of
|
|
187
|
+
`Kipping 2011 <https://ui.adsabs.harvard.edu/abs/2011PhDT.......294K/abstract>`_
|
|
188
|
+
to compute the true anomaly at the instant of minimum star/planet separation.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
e (Array [Dimensionless]): Eccentricity of the orbit
|
|
192
|
+
i (Array [Radian]): Orbital inclination
|
|
193
|
+
omega (Array [Radian]): Argument of periapsis
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
Array: True anomaly at the instant of minimum star/planet separation in radians.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
hp = e * jnp.sin(omega)
|
|
200
|
+
kp = e * jnp.cos(omega)
|
|
201
|
+
|
|
202
|
+
eta_1 = (kp / (1 + hp)) * (jnp.cos(i) ** 2)
|
|
203
|
+
eta_2 = (kp / (1 + hp)) * (1 / (1 + hp)) * (jnp.cos(i) ** 2) ** 2
|
|
204
|
+
eta_3 = (
|
|
205
|
+
-(kp / (1 + hp))
|
|
206
|
+
* ((-6 * (1 + hp) + kp**2 * (-1 + 2 * hp)) / (6 * (1 + hp) ** 3))
|
|
207
|
+
* (jnp.cos(i) ** 2) ** 3
|
|
208
|
+
)
|
|
209
|
+
eta_4 = (
|
|
210
|
+
-(kp / (1 + hp))
|
|
211
|
+
* ((-2 * (1 + hp) + kp**2 * (-1 + 3 * hp)) / (2 * (1 + hp) ** 4))
|
|
212
|
+
* (jnp.cos(i) ** 2) ** 4
|
|
213
|
+
)
|
|
214
|
+
eta_5 = (
|
|
215
|
+
(kp / (1 + hp))
|
|
216
|
+
* (
|
|
217
|
+
(
|
|
218
|
+
40 * (1 + hp) ** 2
|
|
219
|
+
- 40 * kp**2 * (-1 + 3 * hp + 4 * hp**2)
|
|
220
|
+
+ kp**4 * (3 - 19 * hp + 8 * hp**2)
|
|
221
|
+
)
|
|
222
|
+
/ (40 * (1 + hp) ** 6)
|
|
223
|
+
)
|
|
224
|
+
* (jnp.cos(i) ** 2) ** 5
|
|
225
|
+
)
|
|
226
|
+
eta_6 = (
|
|
227
|
+
(kp / (1 + hp))
|
|
228
|
+
* (
|
|
229
|
+
(
|
|
230
|
+
24 * (1 + hp) ** 2
|
|
231
|
+
- 40 * kp**2 * (-1 + 4 * hp + 5 * hp**2)
|
|
232
|
+
+ 9 * kp**4 * (1 - 8 * hp + 5 * hp**2)
|
|
233
|
+
)
|
|
234
|
+
/ (24 * (1 + hp) ** 7)
|
|
235
|
+
)
|
|
236
|
+
* (jnp.cos(i) ** 2) ** 6
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
return jnp.pi / 2 - omega - eta_1 - eta_2 - eta_3 - eta_4 - eta_5 - eta_6
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def t0_to_t_peri(e, i, omega, period, t0, **kwargs):
|
|
243
|
+
f = true_anomaly_at_transit_center(e, i, omega)
|
|
244
|
+
|
|
245
|
+
eccentric_anomaly = jnp.arctan2(jnp.sqrt(1 - e**2) * jnp.sin(f), e + jnp.cos(f))
|
|
246
|
+
mean_anomaly = eccentric_anomaly - e * jnp.sin(eccentric_anomaly)
|
|
247
|
+
|
|
248
|
+
return t0 - period / (2 * jnp.pi) * mean_anomaly
|
|
@@ -4,12 +4,8 @@ jax.config.update("jax_enable_x64", True)
|
|
|
4
4
|
import jax.numpy as jnp
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
# running into some numerical issues for very narrow ellipses-
|
|
8
|
-
# e.g., the terminator for a spherical planet at f=1e-6. the rhos are ~1e14 there,
|
|
9
|
-
# and the final value for c_y1 is off. everything is fine at f=1e-5 though, so leaving
|
|
10
|
-
# for now
|
|
11
7
|
@jax.jit
|
|
12
|
-
def poly_to_parametric_helper(rho_xx, rho_xy, rho_x0, rho_yy, rho_y0, rho_00
|
|
8
|
+
def poly_to_parametric_helper(rho_xx, rho_xy, rho_x0, rho_yy, rho_y0, rho_00):
|
|
13
9
|
"""
|
|
14
10
|
A helper function for :func:`poly_to_parametric`.
|
|
15
11
|
|
|
@@ -30,37 +26,101 @@ def poly_to_parametric_helper(rho_xx, rho_xy, rho_x0, rho_yy, rho_y0, rho_00, **
|
|
|
30
26
|
- cosa (Array [Dimensionless]): Cosine of the rotation angle
|
|
31
27
|
- sina (Array [Dimensionless]): Sine of the rotation angle
|
|
32
28
|
"""
|
|
33
|
-
|
|
29
|
+
# (* base eq *)
|
|
30
|
+
# pxx x^2 + pxy x y + px0 x + pyy y^2 + py0 y + p00 == 1
|
|
31
|
+
# (* normalize to get rid of p0 *)
|
|
32
|
+
# pxx/(1 - p00) x^2 + pxy /(1 - p00) x y + px0/(1 - p00) x +
|
|
33
|
+
# pyy/(1 - p00) y^2 + py0 /(1 - p00) y == 1
|
|
34
|
+
# (* solve for the ellipse center *)
|
|
35
|
+
# CoefficientRules[
|
|
36
|
+
# pxx/(1 - p00) x^2 + pxy /(1 - p00) x y + px0/(1 - p00) x +
|
|
37
|
+
# pyy/(1 - p00) y^2 + py0 /(1 - p00) y /. {x -> x - xc,
|
|
38
|
+
# y -> y - yc}, {x, y}]
|
|
39
|
+
# Solve[{px0/(1 - p00) - (2 pxx xc)/(1 - p00) - (pxy yc)/(1 - p00) == 0,
|
|
40
|
+
# py0/(1 - p00) - (pxy xc)/(1 - p00) - (2 pyy yc)/(1 - p00) ==
|
|
41
|
+
# 0 }, {xc, yc}]
|
|
42
|
+
# (* plug back in *)
|
|
43
|
+
# Simplify[
|
|
44
|
+
# CoefficientRules[
|
|
45
|
+
# pxx/(1 - p00) x^2 + pxy /(1 - p00) x y + px0/(1 - p00) x +
|
|
46
|
+
# pyy/(1 - p00) y^2 + py0 /(1 - p00) y /. {x -> x - xc,
|
|
47
|
+
# y -> y - yc} /. {xc -> -((-pxy py0 + 2 px0 pyy)/(
|
|
48
|
+
# pxy^2 - 4 pxx pyy)),
|
|
49
|
+
# yc -> -((-px0 pxy + 2 pxx py0)/(pxy^2 - 4 pxx pyy))}, {x, y}]]
|
|
50
|
+
# (* normalize again to get the final coeffs *)
|
|
51
|
+
# pxxShift =
|
|
52
|
+
# Simplify[(pxx/(
|
|
53
|
+
# 1 - p00)) /(1 - (
|
|
54
|
+
# px0 pxy py0 - pxx py0^2 -
|
|
55
|
+
# px0^2 pyy)/((-1 + p00) (pxy^2 - 4 pxx pyy)))]
|
|
56
|
+
# pxyShift =
|
|
57
|
+
# Simplify[(pxy/(
|
|
58
|
+
# 1 - p00))/(1 - (
|
|
59
|
+
# px0 pxy py0 - pxx py0^2 -
|
|
60
|
+
# px0^2 pyy)/((-1 + p00) (pxy^2 - 4 pxx pyy)))]
|
|
61
|
+
# pyyShift =
|
|
62
|
+
# Simplify[(pyy/(
|
|
63
|
+
# 1 - p00)) /(1 - (
|
|
64
|
+
# px0 pxy py0 - pxx py0^2 -
|
|
65
|
+
# px0^2 pyy)/((-1 + p00) (pxy^2 - 4 pxx pyy)))]
|
|
34
66
|
|
|
35
67
|
# the center of the ellipse
|
|
36
68
|
xc = (rho_xy * rho_y0 - 2 * rho_yy * rho_x0) / (4 * rho_xx * rho_yy - rho_xy**2)
|
|
37
69
|
yc = (rho_xy * rho_x0 - 2 * rho_xx * rho_y0) / (4 * rho_xx * rho_yy - rho_xy**2)
|
|
38
70
|
|
|
39
|
-
# the
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
# get new coefficients for the centered ellipse: all others are zero now,
|
|
72
|
+
# explicitly got rid of rho_00 so there's a lot more divison
|
|
73
|
+
rho_xx_shift = -(
|
|
74
|
+
(rho_xx * (rho_xy**2 - 4 * rho_xx * rho_yy))
|
|
75
|
+
/ (
|
|
76
|
+
(-1 + rho_00) * rho_xy**2
|
|
77
|
+
- rho_x0 * rho_xy * rho_y0
|
|
78
|
+
+ rho_x0**2 * rho_yy
|
|
79
|
+
+ rho_xx * (rho_y0**2 + 4 * rho_yy - 4 * rho_00 * rho_yy)
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
rho_xy_shift = (-(rho_xy**3) + 4 * rho_xx * rho_xy * rho_yy) / (
|
|
83
|
+
(-1 + rho_00) * rho_xy**2
|
|
84
|
+
- rho_x0 * rho_xy * rho_y0
|
|
85
|
+
+ rho_x0**2 * rho_yy
|
|
86
|
+
+ rho_xx * (rho_y0**2 + 4 * rho_yy - 4 * rho_00 * rho_yy)
|
|
87
|
+
)
|
|
88
|
+
rho_yy_shift = -(
|
|
89
|
+
(rho_yy * (rho_xy**2 - 4 * rho_xx * rho_yy))
|
|
90
|
+
/ (
|
|
91
|
+
(-1 + rho_00) * rho_xy**2
|
|
92
|
+
- rho_x0 * rho_xy * rho_y0
|
|
93
|
+
+ rho_x0**2 * rho_yy
|
|
94
|
+
+ rho_xx * (rho_y0**2 + 4 * rho_yy - 4 * rho_00 * rho_yy)
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
# get the rotation angle (edge case gives you nans if there's no rotation)
|
|
99
|
+
theta = jnp.where(
|
|
100
|
+
rho_xx_shift - rho_yy_shift != 0.0,
|
|
101
|
+
0.5 * jnp.arctan2(rho_xy_shift, (rho_xx_shift - rho_yy_shift)) + jnp.pi / 2,
|
|
102
|
+
0.0,
|
|
103
|
+
)
|
|
104
|
+
theta = jnp.where(theta < 0.0, theta + jnp.pi, theta)
|
|
105
|
+
# jax.debug.print("{x}", x=theta)
|
|
106
|
+
cosa = jnp.cos(theta)
|
|
107
|
+
sina = jnp.sin(theta)
|
|
108
|
+
|
|
109
|
+
# get the semi-major and semi-minor axes
|
|
110
|
+
a = (
|
|
111
|
+
rho_xx_shift * jnp.cos(theta) ** 2
|
|
112
|
+
+ rho_xy_shift * jnp.cos(theta) * jnp.sin(theta)
|
|
113
|
+
+ rho_yy_shift * jnp.sin(theta) ** 2
|
|
114
|
+
)
|
|
115
|
+
b = (
|
|
116
|
+
rho_xx_shift * jnp.sin(theta) ** 2
|
|
117
|
+
- rho_xy_shift * jnp.cos(theta) * jnp.sin(theta)
|
|
118
|
+
+ rho_yy_shift * jnp.cos(theta) ** 2
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
r1 = 1 / jnp.sqrt(a)
|
|
122
|
+
r2 = 1 / jnp.sqrt(b)
|
|
123
|
+
|
|
64
124
|
return r1, r2, xc, yc, cosa, sina
|
|
65
125
|
|
|
66
126
|
|
|
@@ -141,41 +201,17 @@ def cartesian_intersection_to_parametric_angle(
|
|
|
141
201
|
|
|
142
202
|
"""
|
|
143
203
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
y_alpha = c_y1 * jnp.cos(alpha) + c_y2 * jnp.sin(alpha) + c_y3
|
|
148
|
-
|
|
149
|
-
return (x - x_alpha) ** 2 + (y - y_alpha) ** 2
|
|
150
|
-
|
|
151
|
-
# could have just used autograd, but it's simple enough to do by hand
|
|
152
|
-
def grad_loss(alpha):
|
|
153
|
-
return 2 * (c_x2 * jnp.cos(alpha) - c_x1 * jnp.sin(alpha)) * (
|
|
154
|
-
c_x3 - x + c_x1 * jnp.cos(alpha) + c_x2 * jnp.sin(alpha)
|
|
155
|
-
) + 2 * (c_y2 * jnp.cos(alpha) - c_y1 * jnp.sin(alpha)) * (
|
|
156
|
-
c_y3 - y + c_y1 * jnp.cos(alpha) + c_y2 * jnp.sin(alpha)
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
def scan_func(alpha, _):
|
|
160
|
-
# rarely, but sometimes, it actually reaches loss=0 and grad=0
|
|
161
|
-
# in that case, it throws nans when it tries to divide and everything
|
|
162
|
-
# following that is wrong
|
|
163
|
-
l = loss(alpha)
|
|
164
|
-
g = grad_loss(alpha)
|
|
165
|
-
|
|
166
|
-
def not_converged(alpha):
|
|
167
|
-
return alpha - l / g, None
|
|
168
|
-
|
|
169
|
-
def converged(alpha):
|
|
170
|
-
return alpha, None
|
|
171
|
-
|
|
172
|
-
return jax.lax.cond(jnp.abs(g) > 1e-16, not_converged, converged, alpha)
|
|
204
|
+
# center the ellipse
|
|
205
|
+
xs -= c_x3
|
|
206
|
+
ys -= c_y3
|
|
173
207
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
208
|
+
# the x, y positions are now linear combinations of just cosa, sina
|
|
209
|
+
# linear solve for those
|
|
210
|
+
inv = jnp.linalg.inv(jnp.array([[c_x1, c_x2], [c_y1, c_y2]]))
|
|
211
|
+
matrix = jax.vmap(lambda x, y: jnp.matmul(inv, jnp.array([x, y])))(xs, ys)
|
|
212
|
+
cosa = matrix[:, 0]
|
|
213
|
+
sina = matrix[:, 1]
|
|
177
214
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return alphas
|
|
215
|
+
# convert to alpha
|
|
216
|
+
alpha = jnp.arctan2(sina, cosa)
|
|
217
|
+
return alpha
|
{squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/polynomial_limb_darkened_transit.py
RENAMED
|
@@ -12,7 +12,7 @@ from squishyplanet.engine.parametric_ellipse import (
|
|
|
12
12
|
poly_to_parametric,
|
|
13
13
|
cartesian_intersection_to_parametric_angle,
|
|
14
14
|
)
|
|
15
|
-
from squishyplanet.engine.kepler import kepler, skypos
|
|
15
|
+
from squishyplanet.engine.kepler import kepler, skypos, t0_to_t_peri
|
|
16
16
|
|
|
17
17
|
epsabs = epsrel = 1e-12
|
|
18
18
|
|
|
@@ -438,6 +438,9 @@ def lightcurve(state, parameterize_with_projected_ellipse):
|
|
|
438
438
|
# array we'll modify if the planet is in transit
|
|
439
439
|
fluxes = jnp.ones_like(state["times"])
|
|
440
440
|
|
|
441
|
+
if state["t0"] is not None:
|
|
442
|
+
state["t_peri"] = t0_to_t_peri(**state)
|
|
443
|
+
|
|
441
444
|
time_deltas = state["times"] - state["t_peri"]
|
|
442
445
|
mean_anomalies = 2 * jnp.pi * time_deltas / state["period"]
|
|
443
446
|
true_anomalies = kepler(mean_anomalies, state["e"])
|
|
@@ -19,7 +19,7 @@ from squishyplanet.engine.parametric_ellipse import (
|
|
|
19
19
|
poly_to_parametric,
|
|
20
20
|
)
|
|
21
21
|
from squishyplanet.engine.greens_basis_transform import generate_change_of_basis_matrix
|
|
22
|
-
from squishyplanet.engine.kepler import kepler, skypos
|
|
22
|
+
from squishyplanet.engine.kepler import kepler, skypos, t0_to_t_peri
|
|
23
23
|
from squishyplanet.engine.polynomial_limb_darkened_transit import (
|
|
24
24
|
lightcurve,
|
|
25
25
|
parameterize_2d_helper,
|
|
@@ -70,8 +70,10 @@ class OblateSystem:
|
|
|
70
70
|
(e.g. BJD) will work. A required parameter, will raise an error if not
|
|
71
71
|
provided.
|
|
72
72
|
t_peri (float, [Days], default=None):
|
|
73
|
-
The time of periastron passage.
|
|
74
|
-
|
|
73
|
+
The time of periastron passage. One of ``t_peri`` or ``t0`` must be
|
|
74
|
+
provided.
|
|
75
|
+
t0 (float, [Days], default=None):
|
|
76
|
+
The time of transit center. One of ``t_peri`` or ``t0`` must be provided.
|
|
75
77
|
period (float, [Days], default=None):
|
|
76
78
|
The period of the orbit. A required parameter, will raise an error if not
|
|
77
79
|
provided.
|
|
@@ -241,6 +243,7 @@ class OblateSystem:
|
|
|
241
243
|
self,
|
|
242
244
|
times=None,
|
|
243
245
|
t_peri=None,
|
|
246
|
+
t0=None,
|
|
244
247
|
period=None,
|
|
245
248
|
a=None,
|
|
246
249
|
tidally_locked=None,
|
|
@@ -363,7 +366,11 @@ class OblateSystem:
|
|
|
363
366
|
|
|
364
367
|
# everything below here is just an instantaneous snapshot mostly for plotting,
|
|
365
368
|
# these will all vary with different parameter inputs
|
|
366
|
-
|
|
369
|
+
if self._state["t_peri"] is None:
|
|
370
|
+
tp = t0_to_t_peri(**self._state)
|
|
371
|
+
else:
|
|
372
|
+
tp = self._state["t_peri"]
|
|
373
|
+
time_deltas = self._state["times"] - tp
|
|
367
374
|
mean_anomalies = 2 * jnp.pi * time_deltas / state["period"]
|
|
368
375
|
true_anomalies = kepler(mean_anomalies, state["e"])
|
|
369
376
|
self._state["f"] = true_anomalies
|
|
@@ -449,8 +456,16 @@ class OblateSystem:
|
|
|
449
456
|
if self._state["parameterize_with_projected_ellipse"]:
|
|
450
457
|
self._state["r"] = 0.0
|
|
451
458
|
continue
|
|
459
|
+
if key == "t_peri":
|
|
460
|
+
continue
|
|
461
|
+
if key == "t0":
|
|
462
|
+
continue
|
|
452
463
|
raise ValueError(f"'{key}' is a required parameter")
|
|
453
464
|
|
|
465
|
+
assert (self._state["t_peri"] is None) != (
|
|
466
|
+
self._state["t0"] is None
|
|
467
|
+
), "Exactly one of 't_peri' or 't0' must be specified"
|
|
468
|
+
|
|
454
469
|
self._state["ld_u_coeffs"] = jnp.array(self._state["ld_u_coeffs"])
|
|
455
470
|
assert (
|
|
456
471
|
self._state["ld_u_coeffs"].shape[0] >= 2
|
|
@@ -486,6 +501,8 @@ class OblateSystem:
|
|
|
486
501
|
self._state[key] = jnp.array([self._state[key]])
|
|
487
502
|
shapes.append(1)
|
|
488
503
|
else:
|
|
504
|
+
if self._state[key] is None:
|
|
505
|
+
continue # still one None hanging around, either t0 or t_peri
|
|
489
506
|
if len(self._state[key].shape) > 1:
|
|
490
507
|
raise ValueError(
|
|
491
508
|
"All parameters must be scalars or 1D arrays of the same shape."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: squishyplanet
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A package for dealing with non-spherical exoplanets
|
|
5
5
|
Author-email: Ben Cassese <b.c.cassese@columbia.edu>
|
|
6
6
|
License: MIT
|
|
@@ -26,11 +26,12 @@ Requires-Dist: ipykernel
|
|
|
26
26
|
|
|
27
27
|
# squishyplanet
|
|
28
28
|
|
|
29
|
-
[](https://doi.org/10.21105/joss.06972)
|
|
30
30
|
[](https://squishyplanet.readthedocs.io/en/latest/?badge=latest)
|
|
31
31
|

|
|
32
32
|
[](https://coveralls.io/github/ben-cassese/squishyplanet?branch=main)
|
|
33
33
|

|
|
34
|
+
[](https://opensource.org/licenses/MIT)
|
|
34
35
|
|
|
35
36
|
A package for modeling non-spherical exoplanets.
|
|
36
37
|
|
|
@@ -52,23 +53,20 @@ See the [installation instructions](https://squishyplanet.readthedocs.io/en/late
|
|
|
52
53
|
|
|
53
54
|
## Attribution and License
|
|
54
55
|
|
|
55
|
-
[](https://opensource.org/licenses/MIT)
|
|
56
|
-
[hopefully joss badge]
|
|
57
56
|
|
|
58
|
-
``squishyplanet`` is made freely available under the MIT License. If you use this code in your research, please cite the accompanying JOSS paper
|
|
57
|
+
``squishyplanet`` is made freely available under the MIT License. If you use this code in your research, please cite the accompanying JOSS paper:
|
|
59
58
|
|
|
60
59
|
```
|
|
61
|
-
@article{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
journal = {}
|
|
60
|
+
@article{squishyplanet,
|
|
61
|
+
author = {{Cassese}, Ben and {Vega}, Justin and {Lu}, Tiger and {Rice}, Malena and {Poddar}, Avishi and {Kipping}, David},
|
|
62
|
+
doi = {10.21105/joss.06972},
|
|
63
|
+
journal = {Journal of Open Source Software},
|
|
64
|
+
month = aug,
|
|
65
|
+
number = {100},
|
|
66
|
+
pages = {6972},
|
|
67
|
+
title = {{squishyplanet: modeling transits of non-spherical exoplanets in JAX}},
|
|
68
|
+
url = {https://joss.theoj.org/papers/10.21105/joss.06972},
|
|
69
|
+
volume = {9},
|
|
70
|
+
year = {2024}
|
|
73
71
|
}
|
|
74
72
|
```
|
|
@@ -13,9 +13,8 @@ def test_projected_parameterization():
|
|
|
13
13
|
t_exp = 5 * u.min
|
|
14
14
|
times = jnp.arange(-30, 30, t_exp.to(u.hour).value) * u.hour.to(u.day)
|
|
15
15
|
|
|
16
|
-
for i in range(
|
|
16
|
+
for i in range(2_000):
|
|
17
17
|
key, *subkeys = jax.random.split(key, (5,))
|
|
18
|
-
# if i < 529: continue
|
|
19
18
|
|
|
20
19
|
# the 3d planet
|
|
21
20
|
injected_state = {
|
|
@@ -29,8 +28,8 @@ def test_projected_parameterization():
|
|
|
29
28
|
"r": 0.1,
|
|
30
29
|
"i": 89.9720 * jnp.pi / 180,
|
|
31
30
|
"ld_u_coeffs": jnp.array([0.4, 0.26]),
|
|
32
|
-
"f1": jax.random.uniform(subkeys[0], (1,), minval=0.0, maxval=0.
|
|
33
|
-
"f2": jax.random.uniform(subkeys[1], (1,), minval=0.0, maxval=0.
|
|
31
|
+
"f1": jax.random.uniform(subkeys[0], (1,), minval=0.0, maxval=0.99),
|
|
32
|
+
"f2": jax.random.uniform(subkeys[1], (1,), minval=0.0, maxval=0.99),
|
|
34
33
|
"obliq": jax.random.uniform(subkeys[2], (1,), minval=0.0, maxval=jnp.pi),
|
|
35
34
|
"prec": jax.random.uniform(subkeys[3], (1,), minval=0.0, maxval=jnp.pi),
|
|
36
35
|
"tidally_locked": False,
|
|
@@ -68,4 +67,10 @@ def test_projected_parameterization():
|
|
|
68
67
|
assert jnp.min(lc1 >= r**2)
|
|
69
68
|
assert jnp.min(lc2 >= r**2)
|
|
70
69
|
|
|
70
|
+
# single point outliers
|
|
71
|
+
diff = jnp.diff(lc1)
|
|
72
|
+
assert jnp.abs(jnp.argmax(diff) - jnp.argmin(diff)) != 1
|
|
73
|
+
diff = jnp.diff(lc2)
|
|
74
|
+
assert jnp.abs(jnp.argmax(diff) - jnp.argmin(diff)) != 1
|
|
75
|
+
|
|
71
76
|
assert jnp.allclose(lc1, lc2)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|