@@ -394,6 +394,30 @@ function compute_spectrum(var::ClimaAnalysis.OutputVar; mass_weight = nothing)
394394 )
395395end
396396
397+ import ClimaCoreSpectra. FFTW
398+ function compute_average_cartesian_spectrum_1d(x:: ClimaAnalysis.OutputVar )
399+ @assert length(x. dims) == 2 " Can only compute 1D or averaged 2D spectra"
400+ @assert x. dim2index[" time" ] == 1 " Time must be first dimension"
401+ space_name = x. index2dim[2 ]
402+ nt, nspace = size(x. data)
403+ Δ = only(unique(round.(Int, diff(x. dims[space_name])))) # Assume uniform grid, rounded to Int (m-scale)
404+
405+ x̂ = FFTW. rfft(x. data, 2 ) # FFT along non-time dim
406+ power = mean(abs2.(x̂) ./ nspace, dims = 1 ) |> vec
407+
408+ # ω = FFTW.rfftfreq(nspace, 1/Δ)
409+ ω = FFTW. rfftfreq(nspace, nspace) .+ 1 # wavenumber
410+
411+ attr = Dict(
412+ " short_name" => " spectrum_" * short_name(x),
413+ " long_name" => " Spectrum of " * long_name(x),
414+ " units" => " " ,
415+ )
416+ dims = Dict(" Log10 Wavenumber" => log10.(ω))
417+ dim_attr = Dict(" Log10 Wavenumber" => Dict(" units" => " log(1/m)" ))
418+
419+ return ClimaAnalysis. OutputVar(attr, dims, dim_attr, log10.(power))
420+ end
397421
398422"""
399423 map_comparison(func, simdirs, args)
@@ -1312,6 +1336,9 @@ function make_plots(
13121336 ]
13131337 short_names_xyzt = short_names_xyzt ∩ collect(keys(simdirs[1 ]. vars))
13141338
1339+ short_names_spectra = [" wa" ]
1340+ short_names_spectra = short_names_spectra ∩ collect(keys(simdirs[1 ]. vars))
1341+
13151342 # Window average from instantaneous snapshots?
13161343 function average_t_last2hrs(var)
13171344 window_end = last(var. dims[" time" ])
@@ -1337,11 +1364,38 @@ function make_plots(
13371364 )
13381365
13391366 summary_file = make_plots_generic(output_paths, vcat(var_groups_tz_avg_xy... );
1367+ output_name = isempty(short_names_spectra) ? " summary" : " tmp2" ,
13401368 plot_fn = plot_parsed_attribute_title!,
13411369 summary_files = [tmp_file],
13421370 MAX_NUM_COLS = 2 , MAX_NUM_ROWS = 4 ,
13431371 )
13441372
1373+ isempty(short_names_spectra) && return summary_file
1374+ # If spectra are available, make additional plots
1375+
1376+ var_groups_y_spectra =
1377+ map_comparison(simdirs, short_names_spectra) do simdir, short_name
1378+ var = get(simdir; short_name, reduction)
1379+ last_t = var. dims[" time" ][end ]
1380+ var_ty = slice(var; x= 50_000 , z= 10_000 )
1381+ data_yt = window(var_ty, " time" ; left = last_t - 10 * 3600 )
1382+ compute_average_cartesian_spectrum_1d(data_yt)
1383+ end
1384+
1385+ var_groups_x_spectra =
1386+ map_comparison(simdirs, short_names_spectra) do simdir, short_name
1387+ var = get(simdir; short_name, reduction)
1388+ last_t = var. dims[" time" ][end ]
1389+ var_tx = slice(var; y= 50_000 , z= 10_000 )
1390+ data_xt = window(var_tx, " time" ; left = last_t - 10 * 3600 )
1391+ compute_average_cartesian_spectrum_1d(data_xt)
1392+ end
1393+
1394+ make_plots_generic(
1395+ output_paths,
1396+ [var_groups_y_spectra; var_groups_x_spectra];
1397+ summary_files = [summary_file],
1398+ plot_fn = plot_spectrum_with_line!,
13451399 MAX_NUM_COLS = 2 ,
13461400 MAX_NUM_ROWS = 4 ,
13471401 )
0 commit comments