use crate::healpix::is_seen;
use std::fmt;
#[derive(Clone, Debug)]
pub enum DataArray {
Float32(Vec<f32>),
Float64(Vec<f64>),
}
impl DataArray {
#[inline]
pub fn from_f32(data: Vec<f32>) -> Self {
DataArray::Float32(data)
}
#[inline]
pub fn from_f64(data: Vec<f64>) -> Self {
DataArray::Float64(data)
}
#[inline]
pub fn len(&self) -> usize {
match self {
DataArray::Float32(v) => v.len(),
DataArray::Float64(v) => v.len(),
}
}
#[inline]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
#[inline]
pub fn get(&self, idx: usize) -> Option<f64> {
match self {
DataArray::Float32(v) => v.get(idx).map(|&x| x as f64),
DataArray::Float64(v) => v.get(idx).copied(),
}
}
pub fn iter(&self) -> impl Iterator<Item = f64> + '_ {
match self {
DataArray::Float32(v) => {
Box::new(v.iter().map(|&x| x as f64)) as Box<dyn Iterator<Item = f64>>
}
DataArray::Float64(v) => Box::new(v.iter().copied()),
}
}
pub fn min_value(&self) -> f64 {
match self {
DataArray::Float32(v) => v
.iter()
.filter(|&&x| is_seen(x as f64))
.map(|&x| x as f64)
.fold(f64::INFINITY, f64::min),
DataArray::Float64(v) => v
.iter()
.filter(|&&x| is_seen(x))
.copied()
.fold(f64::INFINITY, f64::min),
}
}
pub fn max_value(&self) -> f64 {
match self {
DataArray::Float32(v) => v
.iter()
.filter(|&&x| is_seen(x as f64))
.map(|&x| x as f64)
.fold(f64::NEG_INFINITY, f64::max),
DataArray::Float64(v) => v
.iter()
.filter(|&&x| is_seen(x))
.copied()
.fold(f64::NEG_INFINITY, f64::max),
}
}
pub fn valid_f64_values(&self) -> Vec<f64> {
match self {
DataArray::Float32(v) => v
.iter()
.filter(|&&x| is_seen(x as f64))
.map(|&x| x as f64)
.collect(),
DataArray::Float64(v) => v.iter().filter(|&&x| is_seen(x)).copied().collect(),
}
}
pub fn as_f64_vec(&self) -> std::borrow::Cow<'_, Vec<f64>> {
match self {
DataArray::Float32(v) => std::borrow::Cow::Owned(v.iter().map(|&x| x as f64).collect()),
DataArray::Float64(v) => std::borrow::Cow::Borrowed(v),
}
}
pub fn as_f64_slice(&self) -> Option<&[f64]> {
match self {
DataArray::Float32(_) => None,
DataArray::Float64(v) => Some(v),
}
}
pub fn memory_size_bytes(&self) -> usize {
match self {
DataArray::Float32(v) => v.len() * 4,
DataArray::Float64(v) => v.len() * 8,
}
}
pub fn dtype(&self) -> &'static str {
match self {
DataArray::Float32(_) => "float32",
DataArray::Float64(_) => "float64",
}
}
}
impl fmt::Display for DataArray {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mb = self.memory_size_bytes() as f64 / (1024.0 * 1024.0);
write!(
f,
"{} data ({} pixels, {:.1} MB)",
self.dtype(),
self.len(),
mb
)
}
}
#[inline]
pub fn to_f64_vec(data: &DataArray) -> Vec<f64> {
data.as_f64_vec().into_owned()
}