sounding_analysis/layers/
convective.rs

1use super::Layer;
2use crate::{parcel, parcel_profile, sounding::Sounding};
3use metfor::JpKg;
4
5/// Get the effective inflow layer.
6pub fn effective_inflow_layer(snd: &Sounding) -> Option<Layer> {
7    let mut vals_iter = snd
8        .bottom_up()
9        // Convert rows to parcels
10        .filter_map(|row| parcel::Parcel::from_datarow(row).map(|pcl| (row, pcl)))
11        // Lift the parcel, skip if there is an error
12        .filter_map(|(row, pcl)| {
13            parcel_profile::lift_parcel(pcl, snd)
14                .ok()
15                .map(|pcl_anal| (row, pcl_anal))
16        })
17        // Get the CAPE and CIN
18        .filter_map(|(row, pcl_anal)| {
19            pcl_anal
20                .cape()
21                .into_option()
22                .and_then(|cape| pcl_anal.cin().map(|cin| (row, cape, cin)))
23        })
24        // Skip levels until we get one that meets criteria
25        .skip_while(|(_, cape, cin)| *cape < JpKg(100.0) || *cin < JpKg(-250.0))
26        // Take levels as long as they meet criteria
27        .take_while(|(_, cape, cin)| *cape >= JpKg(100.0) && *cin >= JpKg(-250.0))
28        // Discard the cape and cin values, we only need the rows
29        .map(|(row, _, _)| row);
30
31    let bottom = vals_iter.next();
32    let top = vals_iter.last();
33
34    if let (Some(bottom), Some(top)) = (bottom, top) {
35        Some(Layer { bottom, top })
36    } else {
37        None
38    }
39}