Skip to main content

sounding_analysis/
indexes.rs

1//! Indexes that are specific to a sounding, but not a particular parcel analysis of that sounding.
2
3use crate::{
4    error::Result,
5    sounding::Sounding,
6};
7use itertools::{izip, Itertools};
8use metfor::{mixing_ratio, Mm, Quantity};
9
10/// Precipitable water (mm)
11#[inline]
12pub fn precipitable_water(snd: &Sounding) -> Result<Mm> {
13    let p_profile = snd.pressure_profile();
14    let dp_profile = snd.dew_point_profile();
15
16    let integrated_mw = izip!(p_profile, dp_profile)
17        // Remove levels with missing data
18        .filter(|(p, dp)| p.is_some() && dp.is_some())
19        // Unpack from the Optioned type
20        .map(|(p, dp)| (p.unpack(), dp.unpack()))
21        // Converte dew point to mixing ratio, removing failed levels.
22        .filter_map(|(p, dp)| mixing_ratio(dp, p).map(|mw| (p, mw)))
23        // View them as pairs for integration with the trapezoid method
24        .tuple_windows::<(_, _)>()
25        // Do the sum for integrating
26        .fold(0.0, |mut acc_mw, ((p0, mw0), (p1, mw1))| {
27            let dp = p0 - p1;
28            acc_mw += (mw0 + mw1) * dp.unpack();
29
30            acc_mw
31        });
32
33    Ok(Mm(integrated_mw / 9.81 / 997.0 * 100_000.0 / 2.0))
34}
35