Skip to content

Commit

Permalink
swtich ndarray to static read and rename
Browse files Browse the repository at this point in the history
  • Loading branch information
Quba1 committed Jul 24, 2024
1 parent e6e38bc commit a661367
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 70 deletions.
6 changes: 3 additions & 3 deletions src/keyed_message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ pub struct Key<T: Clone> {
}

pub trait KeyOps<T: Clone> {
fn read(&self, key_name: &str) -> Result<T, CodesError>;
fn read_unchecked(&self, key_name: &str) -> Result<T, CodesError>;
fn read_key(&self, key_name: &str) -> Result<T, CodesError>;
fn read_key_unchecked(&self, key_name: &str) -> Result<T, CodesError>;

fn write(&mut self, key: Key<T>) -> Result<(), CodesError>;
fn write_key(&mut self, key: Key<T>) -> Result<(), CodesError>;
}

/// Structure representing a single key in the `KeyedMessage`
Expand Down
60 changes: 30 additions & 30 deletions src/keyed_message/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl KeyedMessage {
}

impl KeyOps<i64> for KeyedMessage {
fn read(&self, key_name: &str) -> Result<i64, CodesError> {
fn read_key(&self, key_name: &str) -> Result<i64, CodesError> {
match self.get_key_native_type(key_name)? {
NativeKeyType::Long => (),
_ => return Err(CodesError::WrongRequestedKeyType),
Expand All @@ -33,20 +33,20 @@ impl KeyOps<i64> for KeyedMessage {
return Err(CodesError::WrongRequestedKeySize);
}

self.read_unchecked(key_name)
self.read_key_unchecked(key_name)
}

fn read_unchecked(&self, key_name: &str) -> Result<i64, CodesError> {
fn read_key_unchecked(&self, key_name: &str) -> Result<i64, CodesError> {
unsafe { codes_get_long(self.message_handle, key_name) }
}

fn write(&mut self, key: Key<i64>) -> Result<(), CodesError> {
fn write_key(&mut self, key: Key<i64>) -> Result<(), CodesError> {
unsafe { codes_set_long(self.message_handle, &key.name, key.value) }
}
}

impl KeyOps<f64> for KeyedMessage {
fn read(&self, key_name: &str) -> Result<f64, CodesError> {
fn read_key(&self, key_name: &str) -> Result<f64, CodesError> {
match self.get_key_native_type(key_name)? {
NativeKeyType::Double => (),
_ => return Err(CodesError::WrongRequestedKeyType),
Expand All @@ -60,20 +60,20 @@ impl KeyOps<f64> for KeyedMessage {
return Err(CodesError::WrongRequestedKeySize);
}

self.read_unchecked(key_name)
self.read_key_unchecked(key_name)
}

fn read_unchecked(&self, key_name: &str) -> Result<f64, CodesError> {
fn read_key_unchecked(&self, key_name: &str) -> Result<f64, CodesError> {
unsafe { codes_get_double(self.message_handle, key_name) }
}

fn write(&mut self, key: Key<f64>) -> Result<(), CodesError> {
fn write_key(&mut self, key: Key<f64>) -> Result<(), CodesError> {
unsafe { codes_set_double(self.message_handle, &key.name, key.value) }
}
}

impl KeyOps<String> for KeyedMessage {
fn read(&self, key_name: &str) -> Result<String, CodesError> {
fn read_key(&self, key_name: &str) -> Result<String, CodesError> {
match self.get_key_native_type(key_name)? {
NativeKeyType::Str => (),
_ => return Err(CodesError::WrongRequestedKeyType),
Expand All @@ -85,20 +85,20 @@ impl KeyOps<String> for KeyedMessage {
return Err(CodesError::IncorrectKeySize);
}

self.read_unchecked(key_name)
self.read_key_unchecked(key_name)
}

fn read_unchecked(&self, key_name: &str) -> Result<String, CodesError> {
fn read_key_unchecked(&self, key_name: &str) -> Result<String, CodesError> {
unsafe { codes_get_string(self.message_handle, key_name) }
}

fn write(&mut self, key: Key<String>) -> Result<(), CodesError> {
fn write_key(&mut self, key: Key<String>) -> Result<(), CodesError> {
unsafe { codes_set_string(self.message_handle, &key.name, &key.value) }
}
}

impl KeyOps<Vec<i64>> for KeyedMessage {
fn read(&self, key_name: &str) -> Result<Vec<i64>, CodesError> {
fn read_key(&self, key_name: &str) -> Result<Vec<i64>, CodesError> {
match self.get_key_native_type(key_name)? {
NativeKeyType::Long => (),
_ => return Err(CodesError::WrongRequestedKeyType),
Expand All @@ -110,20 +110,20 @@ impl KeyOps<Vec<i64>> for KeyedMessage {
return Err(CodesError::IncorrectKeySize);
}

self.read_unchecked(key_name)
self.read_key_unchecked(key_name)
}

fn read_unchecked(&self, key_name: &str) -> Result<Vec<i64>, CodesError> {
fn read_key_unchecked(&self, key_name: &str) -> Result<Vec<i64>, CodesError> {
unsafe { codes_get_long_array(self.message_handle, key_name) }
}

fn write(&mut self, key: Key<Vec<i64>>) -> Result<(), CodesError> {
fn write_key(&mut self, key: Key<Vec<i64>>) -> Result<(), CodesError> {
unsafe { codes_set_long_array(self.message_handle, &key.name, &key.value) }
}
}

impl KeyOps<Vec<f64>> for KeyedMessage {
fn read(&self, key_name: &str) -> Result<Vec<f64>, CodesError> {
fn read_key(&self, key_name: &str) -> Result<Vec<f64>, CodesError> {
match self.get_key_native_type(key_name)? {
NativeKeyType::Double => (),
_ => return Err(CodesError::WrongRequestedKeyType),
Expand All @@ -135,20 +135,20 @@ impl KeyOps<Vec<f64>> for KeyedMessage {
return Err(CodesError::IncorrectKeySize);
}

self.read_unchecked(key_name)
self.read_key_unchecked(key_name)
}

fn read_unchecked(&self, key_name: &str) -> Result<Vec<f64>, CodesError> {
fn read_key_unchecked(&self, key_name: &str) -> Result<Vec<f64>, CodesError> {
unsafe { codes_get_double_array(self.message_handle, key_name) }
}

fn write(&mut self, key: Key<Vec<f64>>) -> Result<(), CodesError> {
fn write_key(&mut self, key: Key<Vec<f64>>) -> Result<(), CodesError> {
unsafe { codes_set_double_array(self.message_handle, &key.name, &key.value) }
}
}

impl KeyOps<Vec<u8>> for KeyedMessage {
fn read(&self, key_name: &str) -> Result<Vec<u8>, CodesError> {
fn read_key(&self, key_name: &str) -> Result<Vec<u8>, CodesError> {
match self.get_key_native_type(key_name)? {
NativeKeyType::Bytes => (),
_ => return Err(CodesError::WrongRequestedKeyType),
Expand All @@ -160,14 +160,14 @@ impl KeyOps<Vec<u8>> for KeyedMessage {
return Err(CodesError::IncorrectKeySize);
}

self.read_unchecked(key_name)
self.read_key_unchecked(key_name)
}

fn read_unchecked(&self, key_name: &str) -> Result<Vec<u8>, CodesError> {
fn read_key_unchecked(&self, key_name: &str) -> Result<Vec<u8>, CodesError> {
unsafe { codes_get_bytes(self.message_handle, key_name) }
}

fn write(&mut self, key: Key<Vec<u8>>) -> Result<(), CodesError> {
fn write_key(&mut self, key: Key<Vec<u8>>) -> Result<(), CodesError> {
unsafe { codes_set_bytes(self.message_handle, &key.name, &key.value) }
}
}
Expand Down Expand Up @@ -207,22 +207,22 @@ mod tests {
continue;
}

let kv: Result<i64, CodesError> = current_message.read(&key_name);
let kv: Result<i64, CodesError> = current_message.read_key(&key_name);
validate_read_error(kv, &key_name)?;

let kv: Result<f64, CodesError> = current_message.read(&key_name);
let kv: Result<f64, CodesError> = current_message.read_key(&key_name);
validate_read_error(kv, &key_name)?;

let kv: Result<String, CodesError> = current_message.read(&key_name);
let kv: Result<String, CodesError> = current_message.read_key(&key_name);
validate_read_error(kv, &key_name)?;

let kv: Result<Vec<i64>, CodesError> = current_message.read(&key_name);
let kv: Result<Vec<i64>, CodesError> = current_message.read_key(&key_name);
validate_read_error(kv, &key_name)?;

let kv: Result<Vec<f64>, CodesError> = current_message.read(&key_name);
let kv: Result<Vec<f64>, CodesError> = current_message.read_key(&key_name);
validate_read_error(kv, &key_name)?;

let kv: Result<Vec<u8>, CodesError> = current_message.read(&key_name);
let kv: Result<Vec<u8>, CodesError> = current_message.read_key(&key_name);
validate_read_error(kv, &key_name)?;
}

Expand Down
53 changes: 16 additions & 37 deletions src/message_ndarray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use ndarray::{s, Array2, Array3};

use crate::{errors::MessageNdarrayError, CodesError, DynamicKeyType, KeyedMessage};
use crate::{errors::MessageNdarrayError, CodesError, DynamicKeyType, KeyOps, KeyedMessage};

/// Struct returned by [`KeyedMessage::to_lons_lats_values()`] method.
/// The arrays are collocated, meaning that `longitudes[i, j]` and `latitudes[i, j]` are the coordinates of `values[i, j]`.
Expand All @@ -22,14 +22,14 @@ impl KeyedMessage {
/// Converts the message to a 2D ndarray.
///
/// Returns ndarray where first dimension represents y coordinates and second dimension represents x coordinates,
/// ie. `[lat, lon]`.
///
/// Common convention for grib files on regular lon-lat grid assumes that:
/// ie. `[lat, lon]`.
///
/// Common convention for grib files on regular lon-lat grid assumes that:
/// index `[0, 0]` is the top-left corner of the grid:
/// x coordinates are increasing with the i index,
/// y coordinates are decreasing with the j index.
///
/// This convention can be checked with `iScansNegatively` and `jScansPositively` keys -
///
/// This convention can be checked with `iScansNegatively` and `jScansPositively` keys -
/// if both are false, the above convention is used.
///
/// Requires the keys `Ni`, `Nj` and `values` to be present in the message.
Expand All @@ -42,29 +42,18 @@ impl KeyedMessage {
/// - When the number of values mismatch with the `Ni` and `Nj` keys
#[cfg_attr(docsrs, doc(cfg(feature = "message_ndarray")))]
pub fn to_ndarray(&self) -> Result<Array2<f64>, CodesError> {
let DynamicKeyType::Int(ni) = self.read_key_dynamic("Ni")?.value else {
return Err(MessageNdarrayError::UnexpectedKeyType("Ni".to_owned()).into());
};
let ni: i64 = self.read_key("Ni")?;
let ni = usize::try_from(ni).map_err(MessageNdarrayError::from)?;

let DynamicKeyType::Int(nj) = self.read_key_dynamic("Nj")?.value else {
return Err(MessageNdarrayError::UnexpectedKeyType("Nj".to_owned()).into());
};
let nj: i64 = self.read_key("Nj")?;
let nj = usize::try_from(nj).map_err(MessageNdarrayError::from)?;

let DynamicKeyType::FloatArray(vals) = self.read_key_dynamic("values")?.value else {
return Err(MessageNdarrayError::UnexpectedKeyType("values".to_owned()).into());
};

let vals: Vec<f64> = self.read_key("values")?;
if vals.len() != (ni * nj) {
return Err(MessageNdarrayError::UnexpectedValuesLength(vals.len(), ni * nj).into());
}

let DynamicKeyType::Int(j_scanning) = self.read_key_dynamic("jPointsAreConsecutive")?.value else {
return Err(
MessageNdarrayError::UnexpectedKeyType("jPointsAreConsecutive".to_owned()).into(),
);
};
let j_scanning: i64 = self.read_key("jPointsAreConsecutive")?;

if ![0, 1].contains(&j_scanning) {
return Err(MessageNdarrayError::UnexpectedKeyValue(
Expand Down Expand Up @@ -98,32 +87,22 @@ impl KeyedMessage {
/// - When the number of values mismatch with the `Ni` and `Nj` keys
#[cfg_attr(docsrs, doc(cfg(feature = "message_ndarray")))]
pub fn to_lons_lats_values(&self) -> Result<RustyCodesMessage, CodesError> {
let DynamicKeyType::Int(ni) = self.read_key_dynamic("Ni")?.value else {
return Err(MessageNdarrayError::UnexpectedKeyType("Ni".to_owned()).into());
};
let ni: i64 = self.read_key("Ni")?;
let ni = usize::try_from(ni).map_err(MessageNdarrayError::from)?;

let DynamicKeyType::Int(nj) = self.read_key_dynamic("Nj")?.value else {
return Err(MessageNdarrayError::UnexpectedKeyType("Nj".to_owned()).into());
};
let nj: i64 = self.read_key("Nj")?;
let nj = usize::try_from(nj).map_err(MessageNdarrayError::from)?;

let DynamicKeyType::FloatArray(latlonvals) = self.read_key_dynamic("latLonValues")?.value else {
return Err(MessageNdarrayError::UnexpectedKeyType("latLonValues".to_owned()).into());
};
let latlonvals: Vec<f64> = self.read_key("latLonValues")?;

if latlonvals.len() != (ni * nj * 3) {
return Err(
MessageNdarrayError::UnexpectedValuesLength(latlonvals.len(), ni * nj * 3).into(),
);
}

let DynamicKeyType::Int(j_scanning) = self.read_key_dynamic("jPointsAreConsecutive")?.value else {
return Err(
MessageNdarrayError::UnexpectedKeyType("jPointsAreConsecutive".to_owned()).into(),
);
};

let j_scanning: i64 = self.read_key("jPointsAreConsecutive")?;

if ![0, 1].contains(&j_scanning) {
return Err(MessageNdarrayError::UnexpectedKeyValue(
"jPointsAreConsecutive".to_owned(),
Expand Down Expand Up @@ -165,8 +144,8 @@ mod tests {

use super::*;
use crate::codes_handle::CodesHandle;
use crate::FallibleStreamingIterator;
use crate::DynamicKeyType;
use crate::FallibleStreamingIterator;
use crate::ProductKind;
use std::path::Path;

Expand Down

0 comments on commit a661367

Please sign in to comment.