Skip to content

Commit 542fa8f

Browse files
committed
Plot error from AIDA calibs
1 parent 62af04e commit 542fa8f

File tree

3 files changed

+150
-35
lines changed

3 files changed

+150
-35
lines changed

papers/ice_nucleation_2024/AIDA_calibrations.jl

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,29 @@ for (batch_index, batch_name) in enumerate(batch_names)
129129
EKI_output = calibrate_J_parameters_EKI(FT, nuc_mode, params_list, IC_list, y_truth, end_sim, Γ)
130130
UKI_output = calibrate_J_parameters_UKI(FT, nuc_mode, params_list, IC_list, y_truth, end_sim, Γ)
131131

132+
EKI_calibrated_parameters = EKI_output[1] # MEAN of parameters from ensembles in FINAL iteration
133+
UKI_calibrated_parameters = UKI_output[1] # MEAN of parameters from ensembles in FINAL iteration
134+
EKI_all_params = EKI_output[2] # parameters from EACH ensemble in EACH iteration
135+
UKI_all_params = UKI_output[2] # parameters from EACH ensemble in EACH iteration
136+
EKI_mean_each_iter = EKI_output[3] # MEAN of parameters from ensembles in EACH iteration
137+
UKI_mean_each_iter = UKI_output[3] # MEAN of parameters from ensembles in EACH iteration
138+
# EKI_final_iter_spread = EKI_output[4] # parameters for EACH ensemble in FINAL iteration
139+
UKI_final_iter_spread = UKI_output[4] # parameters for EACH ensemble in FINAL iteration
140+
132141
EKI_n_iterations = size(EKI_output[2])[1]
133142
EKI_n_ensembles = size(EKI_output[2][1])[2]
143+
UKI_n_iterations = size(UKI_output[2])[1]
144+
UKI_n_ensembles = size(UKI_output[2][1])[2]
145+
146+
EKI_calibrated_ensemble_means = ensemble_means(EKI_all_params, EKI_n_iterations, EKI_n_ensembles)
147+
UKI_calibrated_ensemble_means = ensemble_means(UKI_all_params, UKI_n_iterations, UKI_n_ensembles)
134148

135-
EKI_calibrated_parameters = EKI_output[1]
136-
UKI_calibrated_parameters = UKI_output[1]
137-
calibrated_ensemble_means = ensemble_means(EKI_output[2], EKI_n_iterations, EKI_n_ensembles)
138149
merge!(EKI_calibrated_coeff_dict, Dict(batch_name => EKI_calibrated_parameters))
139150
merge!(UKI_calibrated_coeff_dict, Dict(batch_name => UKI_calibrated_parameters))
140151

152+
EKI_loss_batch = []
153+
UKI_loss_batch = []
154+
141155
### Plot for individual experiments.
142156
for (exp_index, data_file) in enumerate(data_file_name_list)
143157
if batch_name == "HOM"
@@ -160,20 +174,40 @@ for (batch_index, batch_name) in enumerate(batch_names)
160174
push!(overview_data.UKI_calibrated_parcel, UKI_parcel)
161175
end
162176

177+
# Parcel runs using ensemble means of parameters at each iteration for each exp in batch
178+
EKI_loss_exp = []
179+
UKI_loss_exp = []
180+
for j in 1:EKI_n_iterations
181+
EKI_parcel_iteration = run_model([params_list[exp_index]], nuc_mode, EKI_mean_each_iter[j], FT, [IC_list[exp_index]], end_sim)
182+
EKI_loss_iteration = (EKI_parcel_iteration[9, end] / Nₜ[exp_index]) - frozen_frac_moving_mean[exp_index][end]
183+
append!(EKI_loss_exp, abs.(EKI_loss_iteration))
184+
end
185+
push!(EKI_loss_batch, EKI_loss_exp)
186+
for k in 1:UKI_n_iterations
187+
UKI_parcel_iteration = run_model([params_list[exp_index]], nuc_mode, UKI_mean_each_iter[k], FT, [IC_list[exp_index]], end_sim)
188+
UKI_loss_iteration = (UKI_parcel_iteration[9, end] / Nₜ[exp_index]) - frozen_frac_moving_mean[exp_index][end]
189+
append!(UKI_loss_exp, abs.(UKI_loss_iteration))
190+
end
191+
push!(UKI_loss_batch, UKI_loss_exp)
192+
163193
## Plots.
164194
## Plotting AIDA data.
165195
AIDA_data = data_file in edf_data_names ? unpack_data(data_file) : unpack_data(data_file, total_t = t_max[exp_index])
166196
(; AIDA_t_profile, AIDA_T_profile, AIDA_P_profile, AIDA_ICNC_profile, AIDA_e_profile) = AIDA_data
167197

168198
AIDA_ICNC_data_fig = plot_AIDA_ICNC_data(
169-
exp_names[exp_index],
199+
exp_names[exp_index], start_time[exp_index],
170200
AIDA_t_profile, AIDA_ICNC_profile,
171201
t_profile[exp_index], ICNC_moving_avg[exp_index], frozen_frac_moving_mean[exp_index],
172202
)
173203

174204
## Calibrated coefficients.
175205
# Did they converge?
176-
calibrated_coeffs_fig = plot_calibrated_coeffs(batch_name, EKI_n_iterations, calibrated_ensemble_means)
206+
calibrated_coeffs_fig = plot_calibrated_coeffs(
207+
batch_name,
208+
EKI_n_iterations, EKI_calibrated_ensemble_means,
209+
UKI_n_iterations, UKI_calibrated_ensemble_means,
210+
)
177211

178212
## Calibrated parcel simulations.
179213
# Does the calibrated parcel give reasonable outputs?
@@ -192,21 +226,28 @@ for (batch_index, batch_name) in enumerate(batch_names)
192226
)
193227

194228
## Looking at spread in UKI calibrated parameters
195-
ϕ_UKI = UKI_output[2]
196-
UKI_parcel_1 = run_model([params_list[exp_index]], nuc_mode, [ϕ_UKI[1,1], ϕ_UKI[2,1]], FT, [IC_list[exp_index]], end_sim)
197-
UKI_parcel_2 = run_model([params_list[exp_index]], nuc_mode, [ϕ_UKI[1,1], ϕ_UKI[2,1]], FT, [IC_list[exp_index]], end_sim)
198-
UKI_parcel_3 = run_model([params_list[exp_index]], nuc_mode, [ϕ_UKI[1,1], ϕ_UKI[2,1]], FT, [IC_list[exp_index]], end_sim)
199-
UKI_parcel_4 = run_model([params_list[exp_index]], nuc_mode, [ϕ_UKI[1,1], ϕ_UKI[2,1]], FT, [IC_list[exp_index]], end_sim)
200-
UKI_parcel_5 = run_model([params_list[exp_index]], nuc_mode, [ϕ_UKI[1,1], ϕ_UKI[2,1]], FT, [IC_list[exp_index]], end_sim)
229+
UKI_parcel_1 = run_model([params_list[exp_index]], nuc_mode, [UKI_final_iter_spread[1,1], UKI_final_iter_spread[2,1]], FT, [IC_list[exp_index]], end_sim)
230+
UKI_parcel_2 = run_model([params_list[exp_index]], nuc_mode, [UKI_final_iter_spread[1,2], UKI_final_iter_spread[2,2]], FT, [IC_list[exp_index]], end_sim)
231+
UKI_parcel_3 = run_model([params_list[exp_index]], nuc_mode, [UKI_final_iter_spread[1,3], UKI_final_iter_spread[2,3]], FT, [IC_list[exp_index]], end_sim)
232+
UKI_parcel_4 = run_model([params_list[exp_index]], nuc_mode, [UKI_final_iter_spread[1,4], UKI_final_iter_spread[2,4]], FT, [IC_list[exp_index]], end_sim)
233+
UKI_parcel_5 = run_model([params_list[exp_index]], nuc_mode, [UKI_final_iter_spread[1,5], UKI_final_iter_spread[2,5]], FT, [IC_list[exp_index]], end_sim)
201234

202235
UKI_spread_fig = plot_UKI_spread(
203236
exp_names[exp_index],
204237
t_profile[exp_index], frozen_frac_moving_mean[exp_index], Nₜ[exp_index],
205238
UKI_parcel_1, UKI_parcel_2, UKI_parcel_3, UKI_parcel_4, UKI_parcel_5, UKI_parcel,
206239
)
207240

208-
end # plotting individual experiments
209-
end
241+
end # iterating over experiments in batch
242+
243+
## Plotting loss function over calibration iterations
244+
loss_fig = plot_loss_func(
245+
batch_name,
246+
EKI_n_iterations, UKI_n_iterations,
247+
EKI_loss_batch, UKI_loss_batch,
248+
)
249+
250+
end # iterating over batches
210251

211252
# Plotting overview
212253
plot_ICNC_overview(overview_data)

papers/ice_nucleation_2024/calibration.jl

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,14 @@ function calibrate_J_parameters_EKI(FT, IN_mode, params, IC, y_truth, end_sim,
350350
digits = 6,
351351
)
352352

353+
mean_each_iter = []
354+
for i in 1:final_iter[1]
355+
push!(mean_each_iter, EKP.get_u_mean(EKI_obj, i))
356+
end
357+
353358
calibrated_coeffs = [m_coeff_ekp, c_coeff_ekp]
354359

355-
return [calibrated_coeffs, ϕ_n_values]
360+
return [calibrated_coeffs, ϕ_n_values, mean_each_iter]
356361
end
357362

358363
function calibrate_J_parameters_UKI(FT, IN_mode, params, IC, y_truth, end_sim, Γ,; perfect_model = false)
@@ -394,14 +399,7 @@ function calibrate_J_parameters_UKI(FT, IN_mode, params, IC, y_truth, end_sim,
394399
# Update ensemble
395400
terminate = EKP.EnsembleKalmanProcesses.update_ensemble!(UKI_obj, G_ens)
396401
push!(err, EKP.get_error(UKI_obj)[end])
397-
# println(
398-
# "Iteration: " *
399-
# string(n) *
400-
# ", Error: " *
401-
# string(err[n]) *
402-
# " norm(Cov):" *
403-
# string(Distributions.norm(EKP.get_process(UKI_obj).uu_cov[n]))
404-
# )
402+
405403
if !isnothing(terminate)
406404
final_iter[1] = n - 1
407405
break
@@ -411,9 +409,17 @@ function calibrate_J_parameters_UKI(FT, IN_mode, params, IC, y_truth, end_sim,
411409
UKI_mean_u_space = EKP.get_u_mean_final(UKI_obj)
412410
UKI_mean = EKP.transform_unconstrained_to_constrained(prior, UKI_mean_u_space)
413411

414-
ϕ_n = EKP.get_ϕ_final(prior, UKI_obj)
412+
ϕ_n = EKP.get_ϕ_final(prior, UKI_obj) # final iteraiton for each ensemble
413+
all_ϕ_n = EKP.get_ϕ(prior, UKI_obj; return_array=true) # set of params for each ensembles AND each iteration
414+
415+
mean_each_iter = []
416+
for i in 1:(final_iter[1] + 1)
417+
mean_u_space = EKP.get_u_mean(UKI_obj, i)
418+
mean_u_space_transformed = EKP.transform_unconstrained_to_constrained(prior, mean_u_space)
419+
push!(mean_each_iter, mean_u_space_transformed)
420+
end
415421

416-
return [UKI_mean, ϕ_n, final_iter]
422+
return [UKI_mean, all_ϕ_n, mean_each_iter, ϕ_n]
417423
end
418424

419425
function ensemble_means(ϕ_n_values, N_iterations, N_ensemble)

papers/ice_nucleation_2024/plots.jl

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import CairoMakie as MK
22

33
include(joinpath(pkgdir(CM), "parcel", "ParcelCommon.jl"))
44

5+
#! format: off
6+
57
"""
68
plot_AIDA_ICNC_data(
79
exp_name,
@@ -12,7 +14,7 @@ include(joinpath(pkgdir(CM), "parcel", "ParcelCommon.jl"))
1214
Plots raw AIDA ICNC data. Plot is saved and returned.
1315
"""
1416
function plot_AIDA_ICNC_data(
15-
exp_name,
17+
exp_name, start_time,
1618
AIDA_t_profile, AIDA_ICNC_profile,
1719
t_profile, ICNC_moving_avg, frozen_frac_moving_mean,
1820
)
@@ -34,8 +36,8 @@ function plot_AIDA_ICNC_data(
3436
linestyle = :dash,
3537
linewidth = 2,
3638
)
37-
MK.lines!(data_ax1, t_profile, ICNC_moving_avg, label = "AIDA ICNC moving mean", linewidth = 2.5, color = :blue)
38-
MK.lines!(data_ax2, t_profile, frozen_frac_moving_mean, linewidth = 2.5, color = :blue)
39+
MK.lines!(data_ax1, t_profile .+ start_time, ICNC_moving_avg, label = "AIDA ICNC moving mean", linewidth = 2.5, color = :blue)
40+
MK.lines!(data_ax2, t_profile .+ start_time, frozen_frac_moving_mean, linewidth = 2.5, color = :blue)
3941
MK.axislegend(data_ax1, framevisible = true, labelsize = 12, position = :rc)
4042
MK.save("$exp_name" * "_ICNC.svg", AIDA_data_fig)
4143

@@ -48,29 +50,49 @@ end
4850
4951
Plots evolution of calibrated coefficients over the EKI iterations. Plot is saved and returned.
5052
"""
51-
function plot_calibrated_coeffs(batch_name, EKI_n_iterations, calibrated_ensemble_means)
53+
function plot_calibrated_coeffs(
54+
batch_name,
55+
EKI_n_iterations, EKI_calibrated_ensemble_means,
56+
UKI_n_iterations, UKI_calibrated_ensemble_means,
57+
)
5258

53-
calibrated_coeffs_fig = MK.Figure(size = (1100, 900), fontsize = 24)
59+
calibrated_coeffs_fig = MK.Figure(size = (900, 600), fontsize = 24)
5460
m_coeff_ax = MK.Axis(calibrated_coeffs_fig[1, 1], ylabel = "m coefficient [-]", title = "$batch_name")
5561
c_coeff_ax =
56-
MK.Axis(calibrated_coeffs_fig[1, 2], ylabel = "c coefficient [-]", xlabel = "iteration #", title = "EKI")
62+
MK.Axis(calibrated_coeffs_fig[1, 2], ylabel = "c coefficient [-]", xlabel = "iteration #", title = "Ensemble Mean")
5763

5864
MK.lines!(
5965
m_coeff_ax,
6066
collect(1:EKI_n_iterations),
61-
calibrated_ensemble_means[1],
62-
label = "ensemble mean",
67+
EKI_calibrated_ensemble_means[1],
68+
label = "EKI",
6369
color = :orange,
6470
linewidth = 2.5,
6571
)
6672
MK.lines!(
6773
c_coeff_ax,
6874
collect(1:EKI_n_iterations),
69-
calibrated_ensemble_means[2],
70-
label = "ensemble mean",
75+
EKI_calibrated_ensemble_means[2],
76+
label = "EKI",
7177
color = :orange,
7278
linewidth = 2.5,
7379
)
80+
MK.lines!(
81+
m_coeff_ax,
82+
collect(1:UKI_n_iterations),
83+
UKI_calibrated_ensemble_means[1],
84+
label = "UKI",
85+
color = :fuchsia,
86+
linewidth = 2.5,
87+
)
88+
MK.lines!(
89+
c_coeff_ax,
90+
collect(1:UKI_n_iterations),
91+
UKI_calibrated_ensemble_means[2],
92+
label = "UKI",
93+
color = :fuchsia,
94+
linewidth = 2.5,
95+
)
7496

7597
MK.save("$batch_name" * "_calibrated_coeffs_fig.svg", calibrated_coeffs_fig)
7698

@@ -293,7 +315,7 @@ function plot_UKI_spread(
293315
MK.errorbars!(ax_spread, t_profile, frozen_frac_moving_mean, error, color = (:blue, 0.3))
294316
MK.save("$exp_name" * "_UKI_spread_fig.svg", UKI_spread_fig)
295317

296-
return plot_UKI_spread
318+
return UKI_spread_fig
297319

298320
end
299321

@@ -390,3 +412,49 @@ function plot_ICNC_overview(overview_data)
390412

391413
return overview_fig
392414
end
415+
416+
"""
417+
plot_loss_func(
418+
batch_name,
419+
EKI_n_iterations, UKI_n_iterations,
420+
EKI_loss_batch, UKI_loss_batch,
421+
)
422+
423+
Plots the difference in loss functions over each iteration of
424+
calibration for a batch. The absolute value of the difference in
425+
loss functions for all experiments are summed at each iteration.
426+
Plot is saved and returned.
427+
"""
428+
function plot_loss_func(
429+
batch_name,
430+
EKI_n_iterations, UKI_n_iterations,
431+
EKI_loss_batch, UKI_loss_batch,
432+
)
433+
EKI_loss = vec(sum(reduce(hcat, EKI_loss_batch), dims=2))
434+
UKI_loss = vec(sum(reduce(hcat, UKI_loss_batch), dims=2))
435+
436+
loss_fig = MK.Figure(size = (700, 600), fontsize = 24)
437+
ax_loss = MK.Axis(loss_fig[1, 1], ylabel = "|Δ(Frozen Fraction)| [-]", xlabel = "Iteration [-]", title = "$batch_name: |Simulated Final FF - AIDA Final FF|")
438+
MK.lines!(
439+
ax_loss,
440+
collect(1:EKI_n_iterations),
441+
EKI_loss,
442+
label = "EKI",
443+
linewidth = 2.5,
444+
color = :orange,
445+
)
446+
MK.lines!(
447+
ax_loss,
448+
collect(1:UKI_n_iterations),
449+
UKI_loss,
450+
label = "UKI",
451+
linewidth = 2.5,
452+
color = :fuchsia,
453+
)
454+
MK.axislegend(ax_loss, framevisible = false, labelsize = 18, position = :rc)
455+
MK.save("$batch_name" * "_loss_fig.svg", loss_fig)
456+
457+
return loss_fig
458+
459+
end
460+
#! format: on

0 commit comments

Comments
 (0)