-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path13_TABLE2_fit_model_to_simulation_data.py
141 lines (96 loc) · 3.95 KB
/
13_TABLE2_fit_model_to_simulation_data.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""
Python 3.8 -- UTF-8
Ekaterina Ilin
MIT License (2022)
This script fits polynomials to the mean/std vs. latitude data
and computes uncertainties for all fits.
PRODUCES THE CSV FILE FOR TABLE 2 IN THE PAPER.
PRODUCES COVARIANCE MATRICES.
"""
import numpy as np
import pandas as pd
from scipy.odr import Model, RealData, ODR
import matplotlib.pyplot as plt
plt.style.use('plots/paper.mplstyle')
def latfit(b0,x):
mu, sig = x
a, b, c, d, e = b0
return a * mu**2 + b * mu + c * sig**2 + d * sig + e
if __name__ == "__main__":
# ----------------------------------------------------------------------------
# FIT POLYNOMIALS
print("Print unbinned data with polynomials:\n")
nstamp = "2022_06_30_10_00"
# read in all runs
res = pd.read_csv("results/2022_05_all_runs.csv")
# read in the mean std results
ms = pd.read_csv(f"results/{nstamp}_all_mean_stds.csv")
# init results
fitres = {}
# loop through group frames of same hemisphere, number of spots and color
for l, mono in res.groupby(["hem","nspots","color"]):
# get label
hem, nspots, color = l
# make label
tt = f"{nspots} spots, {hem}"
dicspots = {"1-3":2, "1":1, "3-5":4}
dicthem = {"bi-hem.":2., "mono-hem.":1.}
print(hem)
# setup result row
fitres[tt]={}
# init model
f = Model(latfit)
x1, x2, y = [], [], []
# read in simulated data
for _, d in mono.iterrows():
df = pd.read_csv(f"results/{nstamp}_{d.tstamp[17:]}_flares_train_merged.csv")
# select only data with mid latitude above 1 and below 89 deg, that also
# have std measured
_ = df[(df.midlat2 > 0.) &
(df.midlat2 < 90.) &
(~df["diff_tstart_std_stepsize1"].isnull())]
# sort by mid latitude
_ = _.sort_values(by="midlat2",ascending=True)
y_ = _.midlat2.values
# normalize to rotation period as unit
x1_ = _["diff_tstart_mean_stepsize1"] / 2 / np.pi
x2_ = _["diff_tstart_std_stepsize1"] / 2. / np.pi
x1 = np.concatenate((x1, x1_.values))
x2 = np.concatenate((x2, x2_.values))
y = np.concatenate((y, y_))
# 2D x-data
x = np.array([x1, x2])
# x-errors guessed
# error on mean and std is numerically small
sx = np.array([1e-7, 1e-7])
# y-error same as in binning in script 12_
sy = np.full_like(y, 2.5)
# setup data for ODR fit
mydata = RealData(x, y, sx=sx, sy=sy)
# setup ODR fit
myodr = ODR(mydata, f,
beta0=[-5988., 5000.,
-4000., -4000.,
30.],
maxit=15000)
# run ODR fit
myoutput = myodr.run()
# print output
print("----------------------------------------")
print(tt)
print(myoutput.pprint())
# some diagnosticts for each fit
mono["minflares"]=mono.nflares.apply(lambda x: float(x.split("-")[0]))
mono["maxflares"]=mono.nflares.apply(lambda x: float(x.split("-")[-1]))
mono = mono.sort_values("minflares",ascending=True)
# add results line
fitres[tt]=dict(zip(["color",
"a","b","c","d","e",
"ar","br","cr","dr","er"],
np.concatenate(([mono.color.iloc[0]],
myoutput.beta,
myoutput.sd_beta))))
# save fitting data
fitresd = pd.DataFrame(fitres)
print(fitresd.columns, fitresd.index)
fitresd.to_csv(f"results/fit_parameters.csv")