use std::collections::HashMap;
use super::*;
use metfor::{HectoPascal, Meters, Quantity};
use sounding_analysis::Layers;
use sounding_analysis::{Result, Sounding};
fn test_layers<F: FnOnce(&Sounding) -> Result<Layers>>(
snd: &Sounding,
tgt_int_vals: &HashMap<String, i64>,
tgt_float_vals: &HashMap<String, Vec<f64>>,
anal_func: F,
num_key: &str,
levels_key: &str,
) {
if let Some(num_layers) = tgt_int_vals.get(num_key) {
let num_layers = *num_layers as usize;
let analysis = anal_func(&snd).unwrap();
println!("\nanalysis = [");
for lyr in &analysis {
println!("{:#?}", lyr);
}
println!("]");
let analyzed_num = analysis.len();
assert_eq!(num_layers, analyzed_num);
if num_layers > 0 {
if let Some(layer_pressures) = tgt_float_vals.get(levels_key) {
assert!(layer_pressures.len() >= 2);
let layer_pressures = layer_pressures.chunks(2);
let mut count_layers_compared = 0;
for (lyr, it) in analysis.iter().zip(layer_pressures) {
println!(
"\nbottom {:#?} --- {:#?}",
lyr.bottom.pressure.unwrap(),
HectoPascal(it[0])
);
assert!(lyr
.bottom
.pressure
.unwrap()
.approx_eq(HectoPascal(it[0]), HectoPascal(1.0)));
println!("top {:#?} --- {:#?}", lyr.top.pressure.unwrap(), it[1]);
assert!(lyr
.top
.pressure
.unwrap()
.approx_eq(HectoPascal(it[1]), HectoPascal(1.0)));
count_layers_compared += 1;
}
assert_eq!(count_layers_compared, num_layers);
} else {
panic!("No pressure levels given for analysis target.");
}
}
} else {
panic!("No num value given..")
}
}
#[allow(dead_code)] pub fn test_dendritic_layers(
snd: &Sounding,
tgt_int_vals: &HashMap<String, i64>,
tgt_float_vals: &HashMap<String, Vec<f64>>,
) {
use sounding_analysis::dendritic_snow_zone;
test_layers(
snd,
tgt_int_vals,
tgt_float_vals,
dendritic_snow_zone,
"num dendritic zones",
"dendritic zone pressures",
);
}
#[allow(dead_code)] pub fn test_warm_dry_bulb_aloft_and_cold_sfc_layers(
snd: &Sounding,
tgt_int_vals: &HashMap<String, i64>,
tgt_float_vals: &HashMap<String, Vec<f64>>,
) {
use sounding_analysis::{cold_surface_temperature_layer, warm_temperature_layer_aloft};
test_layers(
snd,
tgt_int_vals,
tgt_float_vals,
warm_temperature_layer_aloft,
"num warm dry bulb aloft",
"warm dry bulb layer pressures",
);
if let Some(num_warm_layers) = tgt_int_vals.get("num warm dry bulb aloft") {
let num_warm_layers = *num_warm_layers as usize;
let analysis = warm_temperature_layer_aloft(&snd).unwrap();
println!("num_warm_layers = {}", num_warm_layers);
if num_warm_layers > 0 {
if let Some(cold_surface_layer_pressures) =
tgt_float_vals.get("cold surface layer pressures")
{
let num_cold_surface_layer_pressures = cold_surface_layer_pressures.len();
assert_eq!(num_cold_surface_layer_pressures, 2);
let cold_sfc_analysis = cold_surface_temperature_layer(&snd, &analysis)
.unwrap() .unwrap();
println!("cold_sfc_analysis: {:#?}", cold_sfc_analysis);
let cold_surface_layer_pressures = cold_surface_layer_pressures.chunks(2);
for (lyr, it) in [cold_sfc_analysis].iter().zip(cold_surface_layer_pressures) {
println!(
"\nbottom {:#?} --- {:#?}",
lyr.bottom.pressure.unwrap(),
it[0]
);
assert!(lyr
.bottom
.pressure
.unwrap()
.approx_eq(HectoPascal(it[0]), HectoPascal(1.0)));
println!("top {:#?} --- {:#?}", lyr.top.pressure.unwrap(), it[1]);
assert!(lyr
.top
.pressure
.unwrap()
.approx_eq(HectoPascal(it[1]), HectoPascal(1.0)));
}
} else {
panic!("No pressure levels given for cold surface layer.");
}
}
}
}
#[allow(dead_code)] pub fn test_warm_wet_bulb_aloft(
snd: &Sounding,
tgt_int_vals: &HashMap<String, i64>,
tgt_float_vals: &HashMap<String, Vec<f64>>,
) {
use sounding_analysis::warm_wet_bulb_layer_aloft;
test_layers(
snd,
tgt_int_vals,
tgt_float_vals,
warm_wet_bulb_layer_aloft,
"num warm wet bulb aloft",
"warm wet bulb layer pressures",
);
}
#[allow(dead_code)] pub fn test_layer_agl(snd: &Sounding, tgt_float_vals: &HashMap<String, Vec<f64>>) {
use sounding_analysis::layer_agl;
let analysis = layer_agl(snd, Meters(6000.0)).expect("error creating layer");
println!("\n6km AGL layer: {:#?}", analysis);
if let Some(agl_layer_pressures) = tgt_float_vals.get("6km agl layer pressures") {
assert_eq!(agl_layer_pressures.len(), 2);
let agl_layer_pressures = agl_layer_pressures.chunks(2);
for (lyr, it) in [analysis].iter().zip(agl_layer_pressures) {
println!(
"bottom {:#?} --- {:#?}",
lyr.bottom.pressure.unwrap(),
it[0]
);
assert!(lyr
.bottom
.pressure
.unwrap()
.approx_eq(HectoPascal(it[0]), HectoPascal(1.0)));
println!("top {:#?} --- {:#?}", lyr.top.pressure.unwrap(), it[1]);
assert!(lyr
.top
.pressure
.unwrap()
.approx_eq(HectoPascal(it[1]), HectoPascal(1.0)));
}
} else {
panic!("No pressure levels given for agl layers.");
}
}
#[allow(dead_code)] pub fn test_pressure_layer(snd: &Sounding, tgt_float_vals: &HashMap<String, Vec<f64>>) {
use sounding_analysis::pressure_layer;
let analysis = pressure_layer(snd, HectoPascal(700.0), HectoPascal(500.0)).unwrap();
println!("\n700-500 hPa layer: {:#?}", analysis);
if let Some(pressure_layer_heights) = tgt_float_vals.get("700-500 hPa layer heights") {
assert_eq!(pressure_layer_heights.len(), 2);
let pressure_layer_heights = pressure_layer_heights.chunks(2);
for (lyr, it) in [analysis].iter().zip(pressure_layer_heights) {
println!(
"bottom {:#?} --- {:#?}",
lyr.bottom.height.unwrap(),
it[0]
);
assert!(lyr
.bottom
.height
.unwrap()
.approx_eq(Meters(it[0]), Meters(1.0)));
println!("top {:#?} --- {:#?}", lyr.top.height.unwrap(), it[1]);
assert!(lyr
.top
.height
.unwrap()
.approx_eq(Meters(it[1]), Meters(1.0)));
}
} else {
panic!("No heights given for pressure layer.");
}
}
#[allow(dead_code)] pub fn test_inversion_layers(
snd: &Sounding,
tgt_int_vals: &HashMap<String, i64>,
tgt_float_vals: &HashMap<String, Vec<f64>>,
) {
use sounding_analysis::inversions;
let test_inversions = |snd: &Sounding| inversions(snd, HectoPascal(300.0));
test_layers(
snd,
tgt_int_vals,
tgt_float_vals,
test_inversions,
"num inversions",
"inversion layer pressures",
);
}