-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenEnv
236 lines (200 loc) · 7.8 KB
/
genEnv
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#%%
import pymc as pm
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
import pandas as pd
import scipy.stats as stats
import seaborn as sns
import xarray as xr
#%%
rng=np.random.Generator(np.random.PCG64(1234))
#%%
size = 250
mean_tempC_Km = 6.5/1000
max_alt_Km = 13
lat = np.arange(0, size)
long = np.arange(0, size)
alt = np.arange(0, max_alt_Km)*1000
#%%
therm = stats.multivariate_normal.rvs(mean=[0,0], cov=[[1,0],[0,1]], size=1000)
therm = pd.DataFrame(therm, columns=['x','y'])
therm.plot(kind='scatter', x='x', y='y')
plt.show()
#%%
def sample_AR_signal(n_samples, corr, mu=0, sigma=1):
assert 0 < corr < 1, "Auto-correlation must be between 0 and 1"
# Find out the offset `c` and the std of the white noise `sigma_e`
# that produce a signal with the desired mean and variance.
# See https://en.wikipedia.org/wiki/Autoregressive_model
# under section "Example: An AR(1) process".
c = mu * (1 - corr)
sigma_e = np.sqrt((sigma ** 2) * (1 - corr ** 2))
# Sample the auto-regressive process.
signal = [c + np.random.normal(0, sigma_e)]
for _ in range(1, n_samples):
signal.append(c + corr * signal[-1] + np.random.normal(0, sigma_e))
return np.array(signal)
def compute_corr_lag_1(signal):
return np.corrcoef(signal[:-1], signal[1:])[0][1]
# Examples.
print(compute_corr_lag_1(sample_AR_signal(5000, 0.5)))
print(np.mean(sample_AR_signal(5000, 0.5, mu=2)))
print(np.std(sample_AR_signal(5000, 0.5, sigma=3)))
#%%
base_sigma = .05
samp_lat= pd.DataFrame(sample_AR_signal(size, 0.5, mu=2, sigma=base_sigma))
# %%
samp = sample_AR_signal(size, 0.5, mu=samp_lat, sigma=base_sigma)
samp = pd.DataFrame(samp[:, :, 0])
# %%
samp.values
# %%
def plot_temperature_env(samp):
x2, y2 = np.meshgrid(samp.index.values, samp.columns.values)
plt.figure(figsize=(6,5))
axes = plt.axes(projection='3d')
axes.plot_surface(x2, y2,samp.values,cmap=cm.coolwarm,
linewidth=0, antialiased=False)
axes.set_ylabel('Longitude')
axes.set_xlabel('Latitude')
axes.set_zlabel('Temperature')
# keeps padding between figure elements
plt.tight_layout()
plt.show()
plot_temperature_env(samp)
# %%
lat_inc_max = 10
long_inc_mu, long_inc_std = .01, .1
def add_inc_MA(size, sample_AR_signal, samp_lat, lat_inc_max, long_inc_mu, long_inc_std):
lat_inc = np.linspace(0,lat_inc_max, len(samp_lat))
sample_lat_inc = samp_lat[0] + lat_inc
sample_lat_inc = pd.DataFrame(sample_lat_inc)
#sample_lat_inc.plot()
samp_inc = sample_AR_signal(size, corr=0.5, mu=sample_lat_inc)
long_inc = stats.norm.rvs(loc=long_inc_mu, scale=long_inc_std, size=(size,size), random_state=None)
long_inc = np.cumsum(long_inc, axis=0)
samp_inc = pd.DataFrame(samp_inc[:, :, 0]+long_inc)
return samp_inc
samp_inc = add_inc_MA(size, sample_AR_signal, samp_lat, lat_inc_max, long_inc_mu, long_inc_std)
plot_temperature_env(samp_inc)
# %%
#allow for inversion by having random lapse rate at diff altitudes
def add_altitude_effects(rng, samp_inc, mean_tempC_Km, max_alt_Km):
tempC_Km = rng.normal(loc=mean_tempC_Km, scale=mean_tempC_Km/10, size=max_alt_Km)
# Temp at altitude = base temp - tempC_km * altitude
temperature = ( [np.array(samp_inc)
for _ in np.arange(max_alt_Km)]
-np.broadcast_to(
tempC_Km * np.arange(max_alt_Km)*1000, (250,250,13)
).T
)
temperature = temperature.T
return temperature
temp_3D = add_altitude_effects(rng, samp_inc, mean_tempC_Km, max_alt_Km)
# %%
xr_temp_3D = xr.DataArray(temp_3D, dims=['lat', 'long', 'alt'], coords={'lat': lat, 'long': long, 'alt': alt})
fig = xr_temp_3D.plot.contourf(x='lat',y='long',col='alt', col_wrap=4,
robust=True, vmin=-90, vmax=32, levels=20)
plt.suptitle('Temperature at different altitudes', fontsize = 'xx-large',
weight = 'extra bold')
plt.subplots_adjust(top=.92, right=.8, left=.05, bottom=.05)
xr_tempC_Km= xr.DataArray(mean_tempC_Km, dims=['alt'], coords={'alt': alt})
# %%
#barometric formula
def add_barometric_effects(T0 = 288.15-273.15, L = 0.0065, H = 0, P0 = 101_325.00, g0 = 9.80665, M = 0.0289644, R = 8.3144598):
#barometric formula
#P = P0 * (1 - L * H / T0) ^ (g0 * M / (R * L))
#P = pressure
#P0 = pressure at sea level = 101_325.00 Pa
#L = temperature lapse rate = temperature lapse rate (K/m) in
#H = altitude (m)
#T0 = temperature at sea level = reference temperature (K)
#g0 = gravitational acceleration = gravitational acceleration: 9.80665 m/s2
#M = molar mass of air = molar mass of Earth's air: 0.0289644 kg/mol
#R = gas constant = universal gas constant: 8.3144598 J/(mol·K)
#L = temperature lapse rate
#T = temperature
if type(T0) == 'DataArray':
T0 = T0.sel(alt=0)
return P0 * (1 - L * H / (T0+273.15)) ** (g0 * M / (R * L))
pressure = add_barometric_effects(T0 = xr_temp_3D,
L = xr_tempC_Km,
H = xr_temp_3D.alt, P0 = 101_325.00, g0 = 9.80665, M = 0.0289644, R = 8.3144598)
# %%
xr_temp_pres = xr.merge(
[xr_temp_3D.rename("Temperature"),
pressure.rename("pressure")]
)
# %%
xr_temp_pres.pressure.plot.contourf(x='lat',y='long', col='alt', col_wrap=4,
robust=True, levels=20)
plt.suptitle('pressure at different altitudes', fontsize = 'xx-large',
weight = 'extra bold')
plt.subplots_adjust(top=.92, right=.8, left=.05, bottom=.05)
# %%
# make Z = a function of time and X = sin of time and y = cos of time
# %%
time = np.arange(0, 100, 0.1)
release_alt = 12_000
step_alt = 1
x = (np.sin(time) +1) * 250/2
y = (np.cos(time) +1 ) * 250/2
#create samples from normal distribution and sort them
samples= stats.weibull_max.rvs(c=1, scale = 100, size=len(time))
samples.sort()
steps = samples/(samples.max()-samples.min()) #normalize
steps = steps - steps.min() #shift to 0
z = release_alt * (1- steps)
plt.plot(time, z)
plt.xlabel('Time')
plt.ylabel('Altitude')
plt.title('Altitude vs Time')
ax.set_ylim(0, 12000)
plt.show()
#plot 3d trajectory of z by x and y
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x, y, z)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_zlim(0, 12000)
plt.title('3D Trajectory')
plt.show()
# %%
#select from xarray the temperature at the pressure of the trajectory
xr_x = xr.DataArray(x, dims=['time'], coords={'time': time})
xr_y = xr.DataArray(y, dims=['time'], coords={'time': time})
xr_z = xr.DataArray(z, dims=['time'], coords={'time': time})
xr_traj_env = xr_temp_pres.sel(lat=xr_x,long=xr_y,alt=xr_z, method='nearest')
#.Temperature.plot.contourf(x='lat',y='long', col='time', col_wrap=4)
# %%
#xarray 3d plot of temperature over time
xr_traj_env.Temperature.plot()
plt.suptitle('Temperature over time', fontsize = 'xx-large')
plt.show()
xr_traj_env.pressure.plot()
plt.suptitle('pressure over time', fontsize = 'xx-large')
plt.show()
# %%
#add wind direction and speed then its velocity relvant to the trajectory
# %%
#add wind direction and speed then its velocity relvant to the trajectory
wind_direction = 180 #degrees from north is 0, from east is 90, from south is 180, from west is 270
wind_speed = 10 #m/s #TODO: add wind speed as a function of altitude and lat long
wind_speed_long = wind_speed * np.cos(np.deg2rad(wind_direction))
wind_speed_lat = wind_speed * np.sin(np.deg2rad(wind_direction))
wind_speed_z = 0
display('wind_speed_long',wind_speed_long,
'wind_speed_lat',wind_speed_lat,
'wind_speed_z',wind_speed_z)
# %%
#add wind velocity relvant to the trajectory
xr_traj_env['wind_speed_long'] = wind_speed_long
xr_traj_env['wind_speed_lat'] = wind_speed_lat
xr_traj_env['wind_speed_z'] = wind_speed_z
xr_traj_env['wind_speed'] = np.sqrt(wind_speed_long**2 + wind_speed_lat**2 + wind_speed_z**2)
xr_traj_env['wind_direction'] = wind_direction
xr_traj_env
# %%