ParamAlias

Struct ParamAlias 

Source
pub struct ParamAlias {
    pub file_prefixes: Vec<String>,
    pub tokens: Vec<String>,
    pub unit_tag: Option<&'static str>,
}
Expand description

Centralized parameter alias mapping for grib_preview_cli and other consumers.

Moved from atmosGUI to allow reuse across CLI/UI and the decoder helpers.

Fields§

§file_prefixes: Vec<String>§tokens: Vec<String>§unit_tag: Option<&'static str>

Implementations§

Source§

impl ParamAlias

Source

pub fn for_param(param: &str) -> Self

Examples found in repository?
examples/extract_param.rs (line 42)
13fn main() -> Result<(), Box<dyn Error>> {
14    let args: Vec<_> = env::args_os().skip(1).collect();
15    if args.len() < 4 {
16        eprintln!("usage: extract_param <file.grib2> <param> <lon> <lat>");
17        eprintln!("example: extract_param data.grib2 msl 113.363 22.962");
18        return Ok(());
19    }
20
21    let file_s = args[0].to_string_lossy().to_string();
22    let path = Path::new(&file_s);
23    let param = args[1].to_string_lossy().to_string();
24    let lon: f64 = args[2].to_string_lossy().parse()?;
25    let lat: f64 = args[3].to_string_lossy().parse()?;
26
27    println!("Summarizing file: {}", path.display());
28    let fs = summarize_file(path)?;
29    for m in fs.messages.iter().take(10) {
30        println!("msg {}: key='{}' repr={:?} payload_len={} decode_ok={}", m.message_index, m.key, m.repr_template, m.payload_len, m.decode_ok);
31    }
32
33    println!("\nFinding candidates for param '{}':", param);
34    let candidates = find_candidates_for_param(path, &param)?;
35
36    // Read grid early so fallback paths can use it
37    let grid = read_first_grib2_latlon_grid(path)?;
38
39    if candidates.is_empty() {
40        println!("No candidates found for '{}'. Trying filename prefix fallback...", param);
41        // Try filename prefix fallback using the ParamAlias file_prefixes
42        let alias = rust_grib_decoder::param_alias::ParamAlias::for_param(&param);
43        if let Some(fname) = path.file_name().and_then(|s| s.to_str()) {
44            for prefix in alias.file_prefixes.iter() {
45                if fname.starts_with(prefix) {
46                    println!("Filename '{}' starts with prefix '{}', attempting message 0 decode", fname, prefix);
47                    // Try to decode message 0 using template42 Section5 params if present
48                    let params_vec = read_grib2_section5_template42_params_by_message(path)?;
49                    if let Some(Some(params)) = params_vec.get(0) {
50                        if let Ok(values) = decode_template42_try_message_payload(path, 0, grid.ni, grid.nj, params) {
51                            let val = interp_value(&values, grid.ni, grid.nj, grid.lon1_deg, grid.lat1_deg, grid.di_deg, grid.dj_deg, lon, lat);
52                            println!("Decoded {} samples from message 0 — interpolated value at {}x{} = {}", values.len(), lon, lat, val);
53                            return Ok(());
54                        } else {
55                            eprintln!("template42 rust-aec decode failed for message 0");
56                        }
57                    }
58                    #[cfg(feature = "grib-support")]
59                    {
60                        use grib::{from_reader, Grib2SubmessageDecoder};
61                        use std::fs::File;
62                        use std::io::BufReader;
63                        let f = File::open(path)?;
64                        let r = BufReader::new(f);
65                        let grib2 = from_reader(r)?;
66                        for ((midx, _sidx), sub) in grib2.iter() {
67                            if midx == 0 {
68                                let (w, h) = sub.grid_shape()?;
69                                let decoder = Grib2SubmessageDecoder::from(sub)?;
70                                match decoder.dispatch() {
71                                    Ok(decoded) => {
72                                        let vals: Vec<f32> = decoded.collect();
73                                        let val = interp_value(&vals, w, h, grid.lon1_deg, grid.lat1_deg, grid.di_deg, grid.dj_deg, lon, lat);
74                                        println!("grib crate decoded {} samples (msg 0) — interpolated value = {}", vals.len(), val);
75                                        return Ok(());
76                                    }
77                                    Err(e) => eprintln!("grib crate decode error (msg 0): {}", e),
78                                }
79                            }
80                        }
81                    }
82                }
83            }
84        }
85
86        println!("No decode succeeded using filename prefix fallback.");
87        return Ok(());
88    }
89
90    for (idx, reason, key, ft) in candidates.iter().take(3) {
91        println!("candidate: msg={} reason={:?} key='{}' ft={:?}", idx, reason, key, ft);
92    }
93
94    // Choose the first candidate and attempt to decode it
95    let (msg_idx, _, key, _ft) = &candidates[0];
96    println!("\nAttempting to decode candidate msg {} ('{}')", msg_idx, key);
97
98    let grid = read_first_grib2_latlon_grid(path)?;
99    println!("Grid: {}x{} lon1={} lat1={} di={} dj={}", grid.ni, grid.nj, grid.lon1_deg, grid.lat1_deg, grid.di_deg, grid.dj_deg);
100
101    // Try template-42 rust-aec decode using Section5 params if available
102    let params_vec = read_grib2_section5_template42_params_by_message(path)?;
103    if let Some(Some(params)) = params_vec.get(*msg_idx) {
104        println!("Found template42 params for msg {} — trying rust-aec decode", msg_idx);
105        match decode_template42_try_message_payload(path, *msg_idx, grid.ni, grid.nj, params) {
106            Ok(values) => {
107                let val = interp_value(&values, grid.ni, grid.nj, grid.lon1_deg, grid.lat1_deg, grid.di_deg, grid.dj_deg, lon, lat);
108                println!("Decoded {} samples — interpolated value at {}x{} = {}", values.len(), lon, lat, val);
109                return Ok(());
110            }
111            Err(e) => eprintln!("rust-aec decode failed: {}", e),
112        }
113    }
114
115    #[cfg(feature = "grib-support")]
116    {
117        println!("Attempting to decode using `grib` crate for msg {}", msg_idx);
118        use std::fs::File;
119        use std::io::BufReader;
120        let f = File::open(path)?;
121        let r = BufReader::new(f);
122        let grib2 = from_reader(r)?;
123        for ((midx, _sidx), sub) in grib2.iter() {
124            if midx == *msg_idx {
125                let (w, h) = sub.grid_shape()?;
126                let decoder = Grib2SubmessageDecoder::from(sub)?;
127                match decoder.dispatch() {
128                    Ok(decoded) => {
129                        let vals: Vec<f32> = decoded.collect();
130                        let val = interp_value(&vals, w, h, grid.lon1_deg, grid.lat1_deg, grid.di_deg, grid.dj_deg, lon, lat);
131                        println!("grib crate decoded {} samples — interpolated value = {}", vals.len(), val);
132                        return Ok(());
133                    }
134                    Err(e) => eprintln!("grib crate decode error: {}", e),
135                }
136            }
137        }
138    }
139
140    println!("Could not decode the selected message (no template42 params and grib-support not enabled or decoding failed).");
141    Ok(())
142}
Source

pub fn matches_key(&self, key: &str, param: &str) -> bool

Heuristic match: check tokens then a normalized fallback

Trait Implementations§

Source§

impl Clone for ParamAlias

Source§

fn clone(&self) -> ParamAlias

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ParamAlias

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.