Skip to content

Commit e49f4eb

Browse files
authored
Merge pull request #951 from rzellem/develop
v1.10.0 - updates to priors
2 parents 809cd6c + d5e67a9 commit e49f4eb

7 files changed

+525
-58
lines changed

examples/global_fitter_unit_test.py

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
4+
from exotic.api.elca import transit, glc_fitter
5+
6+
if __name__ == "__main__":
7+
8+
# simulate input data
9+
epochs = np.random.choice(np.arange(100), 3, replace=False)
10+
input_data = []
11+
local_bounds = []
12+
13+
for i, epoch in enumerate(epochs):
14+
15+
nobs = np.random.randint(50) + 100
16+
phase = np.linspace(-0.02-0.01*np.random.random(), 0.02+0.01*np.random.random(), nobs)
17+
18+
prior = {
19+
'rprs':0.1, # Rp/Rs
20+
'ars':14.25, # a/Rs
21+
'per':3.5, # Period [day]
22+
'inc':87.5, # Inclination [deg]
23+
'u0': 1.349, 'u1': -0.709, # exotethys - limb darkening (nonlinear)
24+
'u2': 0.362, 'u3': -0.087,
25+
'ecc':0, # Eccentricity
26+
'omega':0, # Arg of periastron
27+
'tmid':1, # time of mid transit [day],
28+
29+
'a1':5000 + 2500*np.random.random(), # airmass coeffcients
30+
'a2':-0.25 + 0.1*np.random.random()
31+
}
32+
33+
time = prior['tmid'] + prior['per']*(phase+epoch)
34+
stime = time-time[0]
35+
alt = 90* np.cos(4*stime-np.pi/6)
36+
airmass = 1./np.cos( np.deg2rad(90-alt))
37+
model = transit(time, prior)*prior['a1']*np.exp(prior['a2']*airmass)
38+
flux = model*np.random.normal(1, np.mean(np.sqrt(model)/model)*0.25, model.shape)
39+
ferr = flux**0.5
40+
41+
input_data.append({
42+
'time':time,
43+
'flux':flux,
44+
'ferr':ferr,
45+
'airmass':airmass,
46+
'priors':prior
47+
})
48+
49+
# individual properties
50+
local_bounds.append({
51+
'rprs':[0,0.2],
52+
'a2':[-0.5,0]
53+
})
54+
55+
#plt.plot(time,flux,marker='o')
56+
#plt.plot(time, model,ls='-')
57+
#plt.show()
58+
59+
# shared properties between light curves
60+
global_bounds = {
61+
'per':[3.5-0.0001,3.5+0.0001],
62+
'tmid':[1-0.01,1+0.01],
63+
'ars':[14,14.5],
64+
}
65+
66+
print('epochs:',epochs)
67+
myfit = glc_fitter(input_data, global_bounds, local_bounds, individual_fit=False, verbose=True)
68+
69+
myfit.plot_bestfit()
70+
plt.show()
71+
72+
myfit.plot_triangle()
73+
plt.show()
74+
75+
myfit.plot_bestfits()
76+
plt.show()
77+
78+
79+

examples/lc_fitter_unit_test.py

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from exotic.exotic import LimbDarkening
2+
from exotic.api.elca import transit, lc_fitter
3+
from ldtk.filters import create_tess
4+
import matplotlib.pyplot as plt
5+
import numpy as np
6+
7+
if __name__ == "__main__":
8+
prior = {
9+
'rprs': 0.02, # Rp/Rs
10+
'ars': 14.25, # a/Rs
11+
'per': 3.33, # Period [day]
12+
'inc': 88.5, # Inclination [deg]
13+
'u0': 0, 'u1': 0, 'u2': 0, 'u3': 0, # limb darkening (nonlinear)
14+
'ecc': 0.5, # Eccentricity
15+
'omega': 120, # Arg of periastron
16+
'tmid': 0.75, # Time of mid transit [day],
17+
'a1': 50, # Airmass coefficients
18+
'a2': 0., # trend = a1 * np.exp(a2 * airmass)
19+
20+
'teff':5000,
21+
'tefferr':50,
22+
'met': 0,
23+
'meterr': 0,
24+
'logg': 3.89,
25+
'loggerr': 0.01
26+
}
27+
28+
# example generating LD coefficients
29+
tessfilter = create_tess()
30+
31+
ld_obj = LimbDarkening(
32+
teff=prior['teff'], teffpos=prior['tefferr'], teffneg=prior['tefferr'],
33+
met=prior['met'], metpos=prior['meterr'], metneg=prior['meterr'],
34+
logg=prior['logg'], loggpos=prior['loggerr'], loggneg=prior['loggerr'],
35+
wl_min=tessfilter.wl.min(), wl_max=tessfilter.wl.max(), filter_type="Clear")
36+
37+
ld0, ld1, ld2, ld3, filt, wlmin, wlmax = ld_obj.nonlinear_ld()
38+
39+
prior['u0'],prior['u1'],prior['u2'],prior['u3'] = [ld0[0], ld1[0], ld2[0], ld3[0]]
40+
41+
time = np.linspace(0.7, 0.8, 1000) # [day]
42+
43+
# simulate extinction from airmass
44+
stime = time-time[0]
45+
alt = 90 * np.cos(4*stime-np.pi/6)
46+
#airmass = 1./np.cos(np.deg2rad(90-alt))
47+
airmass = np.zeros(time.shape[0])
48+
49+
# GENERATE NOISY DATA
50+
data = transit(time, prior)*prior['a1']*np.exp(prior['a2']*airmass)
51+
data += np.random.normal(0, prior['a1']*250e-6, len(time))
52+
dataerr = np.random.normal(300e-6, 50e-6, len(time)) + np.random.normal(300e-6, 50e-6, len(time))
53+
54+
# add bounds for free parameters only
55+
mybounds = {
56+
'rprs': [0, 0.1],
57+
'tmid': [prior['tmid']-0.01, prior['tmid']+0.01],
58+
'ars': [13, 15],
59+
#'a2': [0, 0.3] # uncomment if you want to fit for airmass
60+
# never list 'a1' in bounds, it is perfectly correlated to exp(a2*airmass)
61+
# and is solved for during the fit
62+
}
63+
64+
myfit = lc_fitter(time, data, dataerr, airmass, prior, mybounds, mode='ns')
65+
66+
for k in myfit.bounds.keys():
67+
print(f"{myfit.parameters[k]:.6f} +- {myfit.errors[k]}")
68+
69+
fig, axs = myfit.plot_bestfit()
70+
plt.tight_layout()
71+
plt.show()
72+
73+
fig = myfit.plot_triangle()
74+
plt.tight_layout()
75+
plt.show()

0 commit comments

Comments
 (0)