Skip to content

Commit 7a8069a

Browse files
committed
Updated example
1 parent 2c6af90 commit 7a8069a

6 files changed

Lines changed: 67431 additions & 40175 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
SOAP/__pycache__
1+
SOAP/__pycache__
2+
docs/notebooks/*.npz

SOAP/utils.py

Lines changed: 156 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,166 @@
11
import os
2-
32
import numpy as np
4-
53
from .units import ms
4+
from matplotlib.colors import LinearSegmentedColormap
5+
from astropy.constants import M_earth, M_sun
6+
#colormaps
7+
transgrad = LinearSegmentedColormap.from_list('transmission_gradient', (
8+
# Edit this gradient at https://eltos.github.io/gradient/#Random%20gradient%209491=008080-FFF2F2-440154
9+
(0.000, (1.000, 0.000, 0.000)), # Bright red (#FF0000) at the low end
10+
(0.500, (1.000, 1.000, 1.000)), # Bright gray (white) at the middle
11+
(1.000, (0.000, 0.000, 0.545))))
12+
13+
# Define color gradients
14+
star_gradient = LinearSegmentedColormap.from_list(
15+
"star_gradient",
16+
[
17+
(0.000, (0.000, 0.169, 0.867)),
18+
(0.050, (0.000, 0.169, 0.867)),
19+
(0.500, (1.000, 1.000, 1.000)),
20+
(0.950, (0.867, 0.000, 0.031)),
21+
(1.000, (0.867, 0.000, 0.031)),
22+
],
23+
)
24+
25+
star_gradient_flux = LinearSegmentedColormap.from_list(
26+
"star_gradient",
27+
(
28+
# Edit this gradient at https://eltos.github.io/gradient/#Random%20gradient%209491=0:FFFFFF-20:786500-25:806B00-30:887200-35:907900-40:988000-45:A08700-50:A88E00-55:B09500-60:B99C00-65:C1A300-70:CAAA00-75:D2B100-80:DBB900-85:E4C000-90:EDC700-95:F6CE00-100:FFD600
29+
(0.000, (0.184, 0.157, 0.000)),
30+
(0.063, (0.227, 0.192, 0.000)),
31+
(0.125, (0.271, 0.231, 0.000)),
32+
(0.188, (0.318, 0.271, 0.000)),
33+
(0.250, (0.365, 0.310, 0.000)),
34+
(0.313, (0.412, 0.349, 0.000)),
35+
(0.375, (0.463, 0.392, 0.000)),
36+
(0.438, (0.510, 0.435, 0.000)),
37+
(0.500, (0.561, 0.478, 0.000)),
38+
(0.563, (0.612, 0.522, 0.000)),
39+
(0.625, (0.667, 0.565, 0.000)),
40+
(0.688, (0.718, 0.608, 0.000)),
41+
(0.750, (0.773, 0.655, 0.000)),
42+
(0.813, (0.827, 0.698, 0.000)),
43+
(0.875, (0.886, 0.745, 0.000)),
44+
(0.938, (0.941, 0.792, 0.000)),
45+
(1.000, (1.000, 0.839, 0.000)),
46+
),
47+
)
48+
49+
planet_gradient_2 = LinearSegmentedColormap.from_list(
50+
"planet_gradient_2",
51+
[
52+
(0.000, (1.000, 0.365, 0.051)),
53+
(0.119, (0.961, 0.510, 0.000)),
54+
(0.238, (0.918, 0.620, 0.000)),
55+
(0.357, (0.867, 0.714, 0.000)),
56+
(0.476, (0.804, 0.800, 0.243)),
57+
(0.607, (0.686, 0.816, 0.310)),
58+
(0.738, (0.553, 0.824, 0.408)),
59+
(0.869, (0.404, 0.827, 0.506)),
60+
(1.000, (0.224, 0.824, 0.600)),
61+
],
62+
)
663

764
c = 299792458.0 * ms
865
sqrt2pi = np.sqrt(2.0 * np.pi)
966

67+
def compute_planet_doppler_shift(sim, psi, absorption_spec):
68+
from.fast_starspot import doppler_shift
69+
"""
70+
Compute Doppler-shifted absorption spectra due to planet's orbital motion.
71+
72+
Parameters:
73+
- sim: simulation object containing planet and star parameters.
74+
- psi_planet: orbital phase array of the planet.
75+
- absorption_spec: array (or list) of absorption spectra to shift.
76+
- M_sun: solar mass constant (in appropriate mass units).
77+
- M_earth: Earth mass constant (in appropriate mass units).
78+
79+
Returns:
80+
- absorpt_prest: array of Doppler-shifted absorption spectra.
81+
"""
82+
psi_planet=(psi*sim.star.prot/sim.planet.P).value
83+
Kp = (sim.planet.K) * (M_sun * sim.star.mass) / (sim.planet.Mp * M_earth)
84+
pshift = (Kp * np.sin(2 * np.pi * psi_planet)).value
85+
absorpt_prest = np.array([
86+
doppler_shift(sim.pixel.wave, absorption_spec[x], -1000 * pshift[x])
87+
for x in range(len(pshift))
88+
])
89+
return absorpt_prest
90+
91+
def transit_durations(sim):
92+
"""
93+
Calculate transit duration and ingress/egress duration for a planet transiting a star.
94+
Supports both circular and eccentric orbits.
95+
96+
Parameters:
97+
P : float
98+
Orbital period (same time units as desired output)
99+
a : float
100+
Semi-major axis in units of stellar radii (a/R_star)
101+
Rp : float
102+
Planet radius in units of stellar radii (R_p/R_star)
103+
ip : float
104+
Orbital inclination in degrees (90° is edge-on)
105+
e : float, optional
106+
Orbital eccentricity (default 0 for circular orbits)
107+
w : float, optional
108+
Argument of periastron in degrees (default 90° means periastron at transit)
109+
110+
Returns:
111+
T14 : float
112+
Total transit duration (first to last contact), in same units as P
113+
tau : float
114+
Ingress or egress duration
115+
116+
Notes:
117+
- The formulas follow the analytic approximations described by Seager & Mallén-Ornelas (2003)
118+
for circular orbits, extended for eccentricity following Kipping (2010):
119+
https://arxiv.org/abs/1004.3819
120+
- The eccentricity correction is applied through the planet's distance at transit
121+
and the velocity factor.
122+
123+
References:
124+
Seager & Mallén-Ornelas (2003), The Astrophysical Journal 585, 1038
125+
Kipping (2010), MNRAS, 407, 301, https://arxiv.org/abs/1004.3819
126+
"""
127+
128+
a=sim.planet.a.value
129+
P=1
130+
ip=sim.planet.ip.value
131+
Rp=sim.planet.Rp.value
132+
e=sim.planet.e
133+
w=sim.planet.w.value
134+
135+
# Convert degrees to radians for angle calculations
136+
i = np.radians(ip)
137+
w_rad = np.radians(w)
138+
139+
# Computes the star-planet distance ratio at mid-transit (normalized by a)
140+
r_tp = (1 - e**2) / (1 + e * np.sin(w_rad))
141+
142+
# Impact parameter b (normalized by stellar radius)
143+
b = a * r_tp * np.cos(i)
144+
145+
# Velocity correction factor accounting for orbital speed at transit
146+
velocity_factor = np.sqrt(1 - e**2) / (1 + e * np.sin(w_rad))
147+
148+
# Calculate total transit duration T14 using modified formula:
149+
# arcsin argument: chord length over the projected orbital distance factor including eccentricity
150+
arg_total = np.sqrt((1 + Rp)**2 - b**2) / (a * r_tp * np.sin(i))
151+
# Clip argument to valid range [-1,1] to avoid NaNs
152+
arg_total = np.clip(arg_total, -1, 1)
153+
T14 = (P / np.pi) * velocity_factor * np.arcsin(arg_total)
154+
155+
# Calculate full transit duration T23 (between second and third contacts)
156+
arg_full = np.sqrt((1 - Rp)**2 - b**2) / (a * r_tp * np.sin(i))
157+
arg_full = np.clip(arg_full, -1, 1)
158+
T23 = (P / np.pi) * velocity_factor * np.arcsin(arg_full)
159+
160+
# Ingress or egress duration is half the difference
161+
#tau = 0.5 * (T14 - T23)
162+
163+
return T14, T23
10164

11165
def read_rdb(fname):
12166
d = np.loadtxt(fname, skiprows=2)

0 commit comments

Comments
 (0)