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.
Files changed (24) hide show
  1. {squishyplanet-0.2.0/squishyplanet.egg-info → squishyplanet-0.2.2}/PKG-INFO +15 -17
  2. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/README.md +14 -16
  3. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/pyproject.toml +1 -1
  4. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/__init__.py +1 -1
  5. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/kepler.py +69 -0
  6. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/parametric_ellipse.py +103 -67
  7. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/polynomial_limb_darkened_transit.py +4 -1
  8. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/oblate_system.py +21 -4
  9. {squishyplanet-0.2.0 → squishyplanet-0.2.2/squishyplanet.egg-info}/PKG-INFO +15 -17
  10. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/tests/test_projected_parameterization.py +9 -4
  11. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/LICENSE +0 -0
  12. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/setup.cfg +0 -0
  13. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/setup.py +0 -0
  14. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/__init__.py +0 -0
  15. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/greens_basis_transform.py +0 -0
  16. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/phase_curve_utils.py +0 -0
  17. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/planet_2d.py +0 -0
  18. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet/engine/planet_3d.py +0 -0
  19. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet.egg-info/SOURCES.txt +0 -0
  20. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet.egg-info/dependency_links.txt +0 -0
  21. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet.egg-info/requires.txt +0 -0
  22. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/squishyplanet.egg-info/top_level.txt +0 -0
  23. {squishyplanet-0.2.0 → squishyplanet-0.2.2}/tests/test_against_jaxoplanet_transit.py +0 -0
  24. {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.0
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
- [![status](https://joss.theoj.org/papers/2b62acea4e4d6c0de73309184861d1e9/status.svg)](https://joss.theoj.org/papers/2b62acea4e4d6c0de73309184861d1e9)
29
+ [![DOI](https://joss.theoj.org/papers/10.21105/joss.06972/status.svg)](https://doi.org/10.21105/joss.06972)
30
30
  [![Documentation Status](https://readthedocs.org/projects/squishyplanet/badge/?version=latest)](https://squishyplanet.readthedocs.io/en/latest/?badge=latest)
31
31
  ![Build Status](https://github.com/ben-cassese/squishyplanet/actions/workflows/tests.yml/badge.svg)
32
32
  [![Coverage Status](https://coveralls.io/repos/github/ben-cassese/squishyplanet/badge.svg?branch=main&service=github)](https://coveralls.io/github/ben-cassese/squishyplanet?branch=main)
33
33
  ![PyPI - Version](https://img.shields.io/pypi/v/squishyplanet)
34
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](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
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](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. The citation information will be updated once the paper is submitted/accepted.
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
- squishyplanet,
63
- doi = {},
64
- url = {},
65
- year = 2024,
66
- month = {},
67
- publisher = {},
68
- volume = {},
69
- number = {},
70
- author = {},
71
- title = {squishyplanet: modeling transits of non-spherical exoplanets in JAX},
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
- [![status](https://joss.theoj.org/papers/2b62acea4e4d6c0de73309184861d1e9/status.svg)](https://joss.theoj.org/papers/2b62acea4e4d6c0de73309184861d1e9)
3
+ [![DOI](https://joss.theoj.org/papers/10.21105/joss.06972/status.svg)](https://doi.org/10.21105/joss.06972)
4
4
  [![Documentation Status](https://readthedocs.org/projects/squishyplanet/badge/?version=latest)](https://squishyplanet.readthedocs.io/en/latest/?badge=latest)
5
5
  ![Build Status](https://github.com/ben-cassese/squishyplanet/actions/workflows/tests.yml/badge.svg)
6
6
  [![Coverage Status](https://coveralls.io/repos/github/ben-cassese/squishyplanet/badge.svg?branch=main&service=github)](https://coveralls.io/github/ben-cassese/squishyplanet?branch=main)
7
7
  ![PyPI - Version](https://img.shields.io/pypi/v/squishyplanet)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](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
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](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. The citation information will be updated once the paper is submitted/accepted.
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
- squishyplanet,
37
- doi = {},
38
- url = {},
39
- year = 2024,
40
- month = {},
41
- publisher = {},
42
- volume = {},
43
- number = {},
44
- author = {},
45
- title = {squishyplanet: modeling transits of non-spherical exoplanets in JAX},
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
  ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "squishyplanet"
7
- version = "0.2.0"
7
+ version = "0.2.2"
8
8
  requires-python = ">=3.9"
9
9
  dependencies = [
10
10
  "requests",
@@ -4,4 +4,4 @@ __all__ = ["OblateSystem"]
4
4
  __url__ = "https://github.com/ben-cassese/squishyplanet"
5
5
  __license__ = "MIT"
6
6
  __description__ = "Modeling transits of non-spherical exoplanets"
7
- __version__ = "0.2.0"
7
+ __version__ = "0.2.2"
@@ -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, **kwargs):
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
- rho_00 -= 1
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 rotation angle
40
- if rho_xx.shape == ():
41
- a = jnp.ones((1, 2, 2))
42
- else:
43
- a = jnp.ones((rho_xx.shape[0], 2, 2))
44
- a = a.at[:, 0, 0].set(rho_xx)
45
- a = a.at[:, 0, 1].set(rho_xy / 2)
46
- a = a.at[:, 1, 0].set(rho_xy / 2)
47
- a = a.at[:, 1, 1].set(rho_yy)
48
- l, b = jax.vmap(jnp.linalg.eigh, in_axes=(0))(a)
49
- lambda_1 = l[:, 0]
50
- lambda_2 = l[:, 1]
51
- cosa = b[:, 0, 0]
52
- sina = b[:, 0, 1]
53
-
54
- # the radii
55
- k = -(
56
- rho_yy * rho_x0**2
57
- - rho_xy * rho_x0 * rho_y0
58
- + rho_xx * rho_y0**2
59
- + rho_xy**2 * rho_00
60
- - 4 * rho_xx * rho_yy * rho_00
61
- ) / (rho_xy**2 - 4 * rho_xx * rho_yy)
62
- r1 = 1 / jnp.sqrt(lambda_1 / k)
63
- r2 = 1 / jnp.sqrt(lambda_2 / k)
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
- def inner(x, y):
145
- def loss(alpha):
146
- x_alpha = c_x1 * jnp.cos(alpha) + c_x2 * jnp.sin(alpha) + c_x3
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
- # if it starts on the actual value, will get nans
175
- # previously had it start at 0, but in idealized cases used for testing it really is 0
176
- return jax.lax.scan(scan_func, 0.123, None, length=50)[0]
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
- alphas = jax.vmap(inner)(xs, ys)
179
- alphas = jnp.mod(alphas, 2 * jnp.pi)
180
- alphas = jnp.where(alphas < 0, alphas + 2 * jnp.pi, alphas)
181
- return alphas
215
+ # convert to alpha
216
+ alpha = jnp.arctan2(sina, cosa)
217
+ return alpha
@@ -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. A required parameter, will raise an error
74
- if not provided.
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
- time_deltas = self._state["times"] - self._state["t_peri"]
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.0
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
- [![status](https://joss.theoj.org/papers/2b62acea4e4d6c0de73309184861d1e9/status.svg)](https://joss.theoj.org/papers/2b62acea4e4d6c0de73309184861d1e9)
29
+ [![DOI](https://joss.theoj.org/papers/10.21105/joss.06972/status.svg)](https://doi.org/10.21105/joss.06972)
30
30
  [![Documentation Status](https://readthedocs.org/projects/squishyplanet/badge/?version=latest)](https://squishyplanet.readthedocs.io/en/latest/?badge=latest)
31
31
  ![Build Status](https://github.com/ben-cassese/squishyplanet/actions/workflows/tests.yml/badge.svg)
32
32
  [![Coverage Status](https://coveralls.io/repos/github/ben-cassese/squishyplanet/badge.svg?branch=main&service=github)](https://coveralls.io/github/ben-cassese/squishyplanet?branch=main)
33
33
  ![PyPI - Version](https://img.shields.io/pypi/v/squishyplanet)
34
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](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
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](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. The citation information will be updated once the paper is submitted/accepted.
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
- squishyplanet,
63
- doi = {},
64
- url = {},
65
- year = 2024,
66
- month = {},
67
- publisher = {},
68
- volume = {},
69
- number = {},
70
- author = {},
71
- title = {squishyplanet: modeling transits of non-spherical exoplanets in JAX},
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(1_000):
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.5),
33
- "f2": jax.random.uniform(subkeys[1], (1,), minval=0.0, maxval=0.5),
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