boreholeio 0.1.0

A library for interacting with borehole.io, a subsurface data management, delivery and visualisation platform
Documentation
use crate::{
    schema::axes::{Base, ChannelAxis, LabelledAxis},
    strided_array_file::{ArrayProxy, Statistics},
};
use ndarray::SliceInfoElem;

pub type Error = String;

/// Slices the coordinate system to match the given extents. All arguments must
/// have the same length and follow a consistent order.
pub fn slice_coordinate_system<AxisType: Base>(
    axes: &[AxisType],
    slice_info: &[SliceInfoElem],
) -> Result<Vec<ChannelAxis>, Error> {
    if axes.len() != slice_info.len() {
        return Err("Inconsistent amount of axes and slicing dimensions".into());
    }

    let mut sliced = Vec::<ChannelAxis>::with_capacity(axes.len());
    for (axis, slice_info) in axes.iter().zip(slice_info) {
        sliced.push(axis.slice(slice_info)?);
    }

    Ok(sliced)
}

/// Auxiliary method for calculating the data bounds.
pub(crate) fn calculate_bounds(data: &ArrayProxy<'_>) -> Result<[f64; 2], Error> {
    Ok([
        data.calc_stats(Statistics::Min)?,
        data.calc_stats(Statistics::Max)?,
    ])
}

/// Updates every `label.bounds` to match the `data`.
pub(crate) fn update_labelled_axis(
    axis: &mut LabelledAxis,
    axis_index: usize,
    data: &ArrayProxy<'_>,
) -> Result<(), Error> {
    // Verify indexing.
    if axis_index >= data.dimensions() {
        return Err("Axis index is out of bounds".into());
    }

    // Initialize a slice which covers the entire data.
    let mut slice_info = vec![
        SliceInfoElem::Slice {
            start: 0,
            end: None,
            step: 1,
        };
        data.dimensions()
    ];

    // Modify every label one by one.
    for (label_index, label) in axis.labels.iter_mut().enumerate() {
        // Initialize the slice to cover current `label`.
        slice_info[axis_index] = SliceInfoElem::Index(label_index as isize);
        // Update the data bounds.
        label.bounds = calculate_bounds(&data.slice(slice_info.clone())?)?;
    }

    Ok(())
}