Compare commits
2
Commits
564e59cd9f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
645c75535c | ||
|
|
4a5a538bf3 |
No files matched your search
+1
-1
Submodule image-registration updated: e5136f00bb...2b01f65cc9.
@@ -117,6 +117,9 @@ pub enum Error {
|
||||
/// the view is empty
|
||||
#[error("empty view")]
|
||||
EmptyView,
|
||||
/// the view cannot be parsed as a scalar
|
||||
#[error("not a scalar")]
|
||||
NotScalar,
|
||||
/// the color string could not be parsed
|
||||
#[error("invalid color: {0}")]
|
||||
InvalidColor(String),
|
||||
|
||||
+645
-5
@@ -4,9 +4,10 @@ use crate::metadata::Metadata;
|
||||
use crate::movie::MovieOptions;
|
||||
|
||||
use crate::readers::{DynReader, PixelType, Reader};
|
||||
use crate::view::{Item, View};
|
||||
use crate::view::View;
|
||||
use itertools::Itertools;
|
||||
use ndarray::{ArrayD, Ix0, Ix1, IxDyn, SliceInfo, SliceInfoElem};
|
||||
use num::Zero;
|
||||
use numpy::{
|
||||
AllowTypeChange, IntoPyArray, PyArray, PyArrayDescr, PyArrayLike0, PyArrayLike1,
|
||||
PyArrayMethods, dtype,
|
||||
@@ -26,6 +27,8 @@ use pyo3_stub_gen::derive::*;
|
||||
use pyo3_stub_gen::inventory::submit;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// class to read image files, while taking good care of important metadata,
|
||||
@@ -70,7 +73,7 @@ unsafe impl Send for PyView {}
|
||||
unsafe impl Sync for PyView {}
|
||||
|
||||
impl PyView {
|
||||
fn item(py: Python, view: View<IxDyn>, dtype: PixelType) -> PyResult<Bound<PyAny>> {
|
||||
fn scalar(py: Python, view: View<IxDyn>, dtype: PixelType) -> PyResult<Bound<PyAny>> {
|
||||
macro_rules! item {
|
||||
($t:tt) => {
|
||||
Ok(view
|
||||
@@ -486,7 +489,7 @@ impl PyView {
|
||||
.collect::<Vec<_>>();
|
||||
let view = view.permute_axes(&axes)?;
|
||||
if view.ndim() == 0 {
|
||||
Self::item(py, view, self.dtype)
|
||||
Self::scalar(py, view, self.dtype)
|
||||
} else {
|
||||
PyView {
|
||||
view,
|
||||
@@ -544,7 +547,7 @@ impl PyView {
|
||||
}
|
||||
let view = self.view.slice(new_slice.as_slice())?;
|
||||
if view.ndim() == 0 {
|
||||
Self::item(py, view, self.dtype)
|
||||
Self::scalar(py, view, self.dtype)
|
||||
} else {
|
||||
PyView {
|
||||
view,
|
||||
@@ -1157,7 +1160,7 @@ impl PyView {
|
||||
}
|
||||
let view = self.view.slice(new_slice.as_slice())?;
|
||||
Some(if view.ndim() == 0 {
|
||||
Self::item(py, view, self.dtype)
|
||||
Self::scalar(py, view, self.dtype)
|
||||
} else {
|
||||
PyView {
|
||||
view,
|
||||
@@ -2006,6 +2009,643 @@ impl PyView {
|
||||
/// backwards compatibility
|
||||
#[expect(unused_variables)]
|
||||
fn set_cache_size(&self, size: usize) {}
|
||||
|
||||
/// set a value at an index - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __setitem__(&self, key: Bound<PyAny>, value: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// delete an index - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __delitem__(&self, key: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place addition - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __iadd__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place subtraction - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __isub__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place multiplication - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __imul__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place true division - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __itruediv__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place floor division - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __ifloordiv__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place modulo - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __imod__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place power - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __ipow__(&self, other: Bound<PyAny>, r#mod: Option<Bound<PyAny>>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place bitwise AND - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __iand__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place bitwise OR - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __ior__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place bitwise XOR - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __ixor__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place left shift - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __ilshift__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place right shift - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __irshift__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// in-place matrix multiplication - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[expect(unused_variables)]
|
||||
fn __imatmul__(&self, other: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// set a scalar at an index - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (index, value))]
|
||||
#[expect(unused_variables)]
|
||||
fn itemset(&self, index: Bound<PyAny>, value: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// fill the view with a value - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (value))]
|
||||
#[expect(unused_variables)]
|
||||
fn fill(&self, value: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// put values at indices - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (indices, values, mode="raise"))]
|
||||
#[expect(unused_variables)]
|
||||
fn put(&self, indices: Bound<PyAny>, values: Bound<PyAny>, mode: &str) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// put values at masked indices - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (mask, values))]
|
||||
#[expect(unused_variables)]
|
||||
fn putmask(&self, mask: Bound<PyAny>, values: Bound<PyAny>) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// resize the view in place - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (new_shape, order="C", refcheck=true))]
|
||||
#[expect(unused_variables)]
|
||||
fn resize(&self, new_shape: Bound<PyAny>, order: &str, refcheck: bool) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// byteswap pixels in place - not supported (read-only)
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (inplace=false))]
|
||||
#[expect(unused_variables)]
|
||||
fn byteswap(&self, inplace: bool) -> PyResult<()> {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"Imread is a read-only, lazy view and cannot be mutated in place",
|
||||
))
|
||||
}
|
||||
|
||||
/// index of the maximum - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (axis=None, out=None, keepdims=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn argmax(
|
||||
&self,
|
||||
axis: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
keepdims: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// index of the minimum - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (axis=None, out=None, keepdims=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn argmin(
|
||||
&self,
|
||||
axis: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
keepdims: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// standard deviation - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (axis=None, dtype=None, out=None, ddof=None, keepdims=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn std(
|
||||
&self,
|
||||
axis: Option<Bound<PyAny>>,
|
||||
dtype: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
ddof: Option<Bound<PyAny>>,
|
||||
keepdims: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// variance - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (axis=None, dtype=None, out=None, ddof=None, keepdims=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn var(
|
||||
&self,
|
||||
axis: Option<Bound<PyAny>>,
|
||||
dtype: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
ddof: Option<Bound<PyAny>>,
|
||||
keepdims: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// product - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (axis=None, dtype=None, out=None, keepdims=None, initial=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn prod(
|
||||
&self,
|
||||
axis: Option<Bound<PyAny>>,
|
||||
dtype: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
keepdims: Option<Bound<PyAny>>,
|
||||
initial: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// cumulative sum - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (axis=None, dtype=None, out=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn cumsum(
|
||||
&self,
|
||||
axis: Option<Bound<PyAny>>,
|
||||
dtype: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// cumulative product - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (axis=None, dtype=None, out=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn cumprod(
|
||||
&self,
|
||||
axis: Option<Bound<PyAny>>,
|
||||
dtype: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// get a single Python scalar - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (index))]
|
||||
#[expect(unused_variables)]
|
||||
fn item(&self, index: Bound<PyAny>) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// indices of non-zero elements - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
fn nonzero(&self) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// gather along an axis - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (indices, axis=None, mode=None, out=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn take(
|
||||
&self,
|
||||
indices: Bound<PyAny>,
|
||||
axis: Option<Bound<PyAny>>,
|
||||
mode: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// gather along an axis after broadcasting - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (arr, indices, axis))]
|
||||
#[expect(unused_variables)]
|
||||
fn take_along_axis(
|
||||
&self,
|
||||
arr: Bound<PyAny>,
|
||||
indices: Bound<PyAny>,
|
||||
axis: Bound<PyAny>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// find insertion points - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (a, side=None, sorter=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn searchsorted(
|
||||
&self,
|
||||
a: Bound<PyAny>,
|
||||
side: Option<Bound<PyAny>>,
|
||||
sorter: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// return the n-th diagonal - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (offset=None, axis1=None, axis2=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn diagonal(
|
||||
&self,
|
||||
offset: Option<Bound<PyAny>>,
|
||||
axis1: Option<Bound<PyAny>>,
|
||||
axis2: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// repeat elements - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (repeats, axis=None, out=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn repeat(
|
||||
&self,
|
||||
repeats: Bound<PyAny>,
|
||||
axis: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// truncate to a range - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (a_min=None, a_max=None, out=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn clip(
|
||||
&self,
|
||||
a_min: Option<Bound<PyAny>>,
|
||||
a_max: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// round to decimals - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (decimals=None, out=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn round(&self, decimals: Option<Bound<PyAny>>, out: Option<Bound<PyAny>>) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// select elements where a condition is true - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (condition, axis=None, out=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn compress(
|
||||
&self,
|
||||
condition: Bound<PyAny>,
|
||||
axis: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// dot product - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (b))]
|
||||
#[expect(unused_variables)]
|
||||
fn dot(&self, b: Bound<PyAny>) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// trace along two axes - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (offset=None, axis1=None, axis2=None, dtype=None, out=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn trace(
|
||||
&self,
|
||||
offset: Option<Bound<PyAny>>,
|
||||
axis1: Option<Bound<PyAny>>,
|
||||
axis2: Option<Bound<PyAny>>,
|
||||
dtype: Option<Bound<PyAny>>,
|
||||
out: Option<Bound<PyAny>>,
|
||||
) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// real part
|
||||
#[getter]
|
||||
fn real(&self) -> PyView {
|
||||
self.clone()
|
||||
}
|
||||
|
||||
/// imaginary part
|
||||
#[getter]
|
||||
fn imag<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyAny>> {
|
||||
macro_rules! imag {
|
||||
($t:tt) => {
|
||||
Ok(
|
||||
ArrayD::<$t>::zeros(self.view.shape().into_iter().collect::<Vec<_>>())
|
||||
.into_pyarray(py)
|
||||
.into_any(),
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
match self.dtype {
|
||||
PixelType::Bool => todo!(),
|
||||
PixelType::I8 => imag!(i8),
|
||||
PixelType::U8 => imag!(u8),
|
||||
PixelType::I16 => imag!(i16),
|
||||
PixelType::U16 => imag!(u16),
|
||||
PixelType::I32 => imag!(i32),
|
||||
PixelType::U32 => imag!(u32),
|
||||
PixelType::F32 => imag!(f32),
|
||||
PixelType::F64 => imag!(f64),
|
||||
PixelType::I64 => imag!(i64),
|
||||
PixelType::U64 => imag!(u64),
|
||||
PixelType::I128 => Err(PyTypeError::new_err("i128 type is not supported")),
|
||||
PixelType::U128 => Err(PyTypeError::new_err("u128 type is not supported")),
|
||||
PixelType::F128 => Err(PyTypeError::new_err("f128 type is not supported")),
|
||||
}
|
||||
}
|
||||
|
||||
/// complex conjugate
|
||||
fn conj(&self) -> Self {
|
||||
self.clone()
|
||||
}
|
||||
|
||||
/// complex conjugate
|
||||
fn conjugate(&self) -> Self {
|
||||
self.clone()
|
||||
}
|
||||
|
||||
/// ctypes view - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[getter]
|
||||
fn ctypes(&self) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// total bytes - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[getter]
|
||||
fn nbytes(&self) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// bytes per element - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[getter]
|
||||
fn itemsize(&self) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// strides - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[getter]
|
||||
fn strides(&self) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// raw data buffer - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[getter]
|
||||
fn data(&self) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// convert to a nested Python list - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
fn tolist(&self) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// pickle to a file
|
||||
fn dump(&self, file: PathBuf) -> PyResult<()> {
|
||||
OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.open(file)?
|
||||
.write_all(&to_stdvec(self).map_err(Error::from)?)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// pickle to a string
|
||||
fn dumps(&self) -> PyResult<Vec<u8>> {
|
||||
Ok(to_stdvec(self).map_err(Error::from)?)
|
||||
}
|
||||
|
||||
/// a view of the same data
|
||||
#[pyo3(signature = (dtype=None, r#type=None))]
|
||||
fn view(&self, py: Python, dtype: Option<Bound<PyAny>>, r#type: Option<Bound<PyAny>>) -> PyResult<Self> {
|
||||
if r#type.is_some() {
|
||||
Err(PyNotImplementedError::new_err(
|
||||
"type not None is not supported",
|
||||
))
|
||||
} else if let Some(dtype) = dtype {
|
||||
self.as_type(py, dtype)
|
||||
} else {
|
||||
Ok(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
/// a structured view of the data - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (dtype=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn tview(&self, dtype: Option<Bound<PyAny>>) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// a view sharing memory with a buffer - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (mem=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn share_memory_with(&self, mem: Option<Bound<PyAny>>) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// split horizontally - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (n))]
|
||||
#[expect(unused_variables)]
|
||||
fn hsplit(&self, n: Bound<PyAny>) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// split vertically - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
#[pyo3(signature = (n=None))]
|
||||
#[expect(unused_variables)]
|
||||
fn vsplit(&self, n: Option<Bound<PyAny>>) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// boolean value
|
||||
fn __bool__(&self) -> PyResult<bool> {
|
||||
macro_rules! _bool {
|
||||
($t:tt) => {
|
||||
Ok(self.view.item::<$t>()? != $t::zero())
|
||||
};
|
||||
}
|
||||
|
||||
match self.dtype {
|
||||
PixelType::Bool => todo!(),
|
||||
PixelType::I8 => _bool!(i8),
|
||||
PixelType::U8 => _bool!(u8),
|
||||
PixelType::I16 => _bool!(i16),
|
||||
PixelType::U16 => _bool!(u16),
|
||||
PixelType::I32 => _bool!(i32),
|
||||
PixelType::U32 => _bool!(u32),
|
||||
PixelType::I64 => _bool!(i64),
|
||||
PixelType::U64 => _bool!(u64),
|
||||
PixelType::I128 => _bool!(i128),
|
||||
PixelType::U128 => _bool!(u128),
|
||||
PixelType::F32 => _bool!(f32),
|
||||
PixelType::F64 => _bool!(f64),
|
||||
PixelType::F128 => Err(PyTypeError::new_err("f128 type is not supported")),
|
||||
}
|
||||
}
|
||||
|
||||
/// convert to int - 0-dimensional Imread should always already be materialized
|
||||
fn __int__(&self) -> PyResult<()> {
|
||||
Err(PyTypeError::new_err(
|
||||
"only 0-dimensional arrays can be converted to Python scalars",
|
||||
))
|
||||
}
|
||||
|
||||
/// convert to float - 0-dimensional Imread should always already be materialized
|
||||
fn __float__(&self) -> PyResult<()> {
|
||||
Err(PyTypeError::new_err(
|
||||
"only 0-dimensional arrays can be converted to Python scalars",
|
||||
))
|
||||
}
|
||||
|
||||
/// convert to complex - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
fn __complex__(&self) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// convert to integer (index) - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
fn __index__(&self) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// object size in bytes - not implemented yet
|
||||
#[gen_stub(skip)]
|
||||
fn __sizeof__(&self) -> PyResult<()> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
submit! {
|
||||
|
||||
+20
-25
@@ -787,7 +787,25 @@ impl<D: Dimension, R: Reader> View<D, R> {
|
||||
let slice: Vec<_> = index.iter().map(|s| SliceInfoElem::Index(*s)).collect();
|
||||
let view = self.clone().into_dyn().slice(slice.as_slice())?;
|
||||
let arr = view.as_array()?;
|
||||
Ok(*arr.first().unwrap())
|
||||
Ok(*arr.first().expect("there should be exactly one value"))
|
||||
}
|
||||
|
||||
/// retrieve the single item in the slice
|
||||
pub fn item<T>(&self) -> Result<T, Error>
|
||||
where
|
||||
T: Number,
|
||||
ArrayD<T>: MinMax<Output = ArrayD<T>>,
|
||||
Array1<T>: MinMax<Output = Array0<T>>,
|
||||
Array2<T>: MinMax<Output = Array1<T>>,
|
||||
{
|
||||
match self.shape().cztyx().iter().product() {
|
||||
0 => Err(Error::EmptyView),
|
||||
1 => Ok(*self
|
||||
.as_array()?
|
||||
.first()
|
||||
.expect("there should be exactly one value")),
|
||||
_ => Err(Error::NotScalar),
|
||||
}
|
||||
}
|
||||
|
||||
/// collect the view into an ndarray
|
||||
@@ -1535,17 +1553,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// trait to define a function to retrieve the only item in a 0d array
|
||||
pub trait Item {
|
||||
/// the single item in the 0d array, cast to `T`
|
||||
fn item<T>(&self) -> Result<T, Error>
|
||||
where
|
||||
T: Number,
|
||||
ArrayD<T>: MinMax<Output = ArrayD<T>>,
|
||||
Array1<T>: MinMax<Output = Array0<T>>,
|
||||
Array2<T>: MinMax<Output = Array1<T>>;
|
||||
}
|
||||
|
||||
impl<R: Reader> View<Ix5, R> {
|
||||
/// create a view on the image at `path`, parsing series and position from the file name
|
||||
pub fn from_path<P>(path: P) -> Result<Self, Error>
|
||||
@@ -1557,18 +1564,6 @@ impl<R: Reader> View<Ix5, R> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Reader> Item for View<Ix0, R> {
|
||||
fn item<T>(&self) -> Result<T, Error>
|
||||
where
|
||||
T: Number,
|
||||
ArrayD<T>: MinMax<Output = ArrayD<T>>,
|
||||
Array1<T>: MinMax<Output = Array0<T>>,
|
||||
Array2<T>: MinMax<Output = Array1<T>>,
|
||||
{
|
||||
Ok(*self.as_array()?.first().ok_or(Error::EmptyView)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Dimension, R: Reader> Display for View<D, R> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
if let Ok(summary) = self.summary() {
|
||||
@@ -1612,7 +1607,7 @@ mod tests {
|
||||
use crate::error::Error;
|
||||
use crate::readers::{DynReader, Frame, Reader};
|
||||
use crate::stats::MinMax;
|
||||
use crate::view::{Item, View};
|
||||
use crate::view::View;
|
||||
use indexmap::IndexMap;
|
||||
use ndarray::{Array, Array4, Array5, Ix4, Ix5, NewAxis};
|
||||
use ndarray::{Array2, ArrayD, IxDyn, SliceInfoElem, s};
|
||||
|
||||
Reference in new issue
Block a user