import math
import numpy as np
import pandas as pd
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
In [1]:
In [2]:
= pd.read_excel(
df "https://gml.noaa.gov/grad/solcalc/NOAA_Solar_Calculations_year.xls",
=["Date"],
parse_dates=[366],
skiprows )
In [3]:
def unix2date(unix):
= unix / 86400 + 719468
dote = (
cykl if dote >= 0
dote else dote - 146096
// 146097
) = dote - cykl * 146097
dotc = (dotc
yotc - dotc // 1460
+ dotc // 36524
- dotc // 146096
// 365
) return [
int(yotc + cykl * 400),
int(dotc - (yotc * 365
+ yotc // 4
- yotc // 100))
]
In [4]:
= pd.concat([
df
df,
pd.DataFrame(for d in df["Date"]],
[unix2date(d.timestamp()) =["year", "doy"],
columns
),=1).sort_values("doy").reset_index() ], axis
In [5]:
"original"] = df["Eq of Time (minutes)"] / 144 df[
In [6]:
"radians"] = math.tau * df.index / 365 df[
In [7]:
def model(gamma, p0, p1, p2, p3, p4):
return (
+
p0 * np.cos(gamma) +
p1 * np.sin(gamma) +
p2 * np.cos(2 * gamma) +
p3 * np.sin(2 * gamma)
p4 )
In [8]:
= curve_fit(model, df["radians"], df["original"])
popt, pcov dict(enumerate(popt.tolist()))
{0: 1.4950424467725955e-05,
1: -0.04189873301524992,
2: -0.02923703633324393,
3: -0.0456943801628261,
4: 0.05175601752530743}
In [9]:
"fitted"] = [model(r, *popt) for r in df["radians"]] df[
In [10]:
= {"linewidth": 3, "legend": True} plotopts
In [11]:
In [12]:
"original"] = df["Sun Declin (deg)"] * np.pi / 180 df[
In [13]:
= curve_fit(model, df["radians"], df["original"])
popt, pcov dict(enumerate(popt.tolist()))
{0: 0.006878449305004424,
1: -0.14278002226634132,
2: 0.3799303998359597,
3: 0.0039588461763330925,
4: 0.005561843926537278}
In [14]:
"fitted"] = [model(r, *popt) for r in df["radians"]] df[
In [15]:
In [16]:
= 90.833 * np.pi / 180 sza
In [17]:
sza
1.5853349194640092