- improve Imread slicing
- can_open function for Reader trait
This commit is contained in:
1 parent
f0404d0419
commit
3e33fe18c1
13 files changed
+808
-264
No files matched your search
@@ -52,6 +52,8 @@ class Flags:
|
|||||||
def __new__(cls) -> Flags: ...
|
def __new__(cls) -> Flags: ...
|
||||||
def __getnewargs__(self) -> None: ...
|
def __getnewargs__(self) -> None: ...
|
||||||
def __getitem__(self, item: builtins.str) -> builtins.bool: ...
|
def __getitem__(self, item: builtins.str) -> builtins.bool: ...
|
||||||
|
def __str__(self) -> builtins.str: ...
|
||||||
|
def __repr__(self) -> builtins.str: ...
|
||||||
|
|
||||||
class Imread:
|
class Imread:
|
||||||
r"""
|
r"""
|
||||||
@@ -211,6 +213,16 @@ class Imread:
|
|||||||
the name of the tube lens
|
the name of the tube lens
|
||||||
"""
|
"""
|
||||||
@property
|
@property
|
||||||
|
def channel_names(self) -> builtins.dict[builtins.int, builtins.str]:
|
||||||
|
r"""
|
||||||
|
names of the channels in order
|
||||||
|
"""
|
||||||
|
@property
|
||||||
|
def summary(self) -> builtins.str:
|
||||||
|
r"""
|
||||||
|
gives a helpful summary of the recorded experiment
|
||||||
|
"""
|
||||||
|
@property
|
||||||
def interpolation_order(self) -> typing.Optional[builtins.int]:
|
def interpolation_order(self) -> typing.Optional[builtins.int]:
|
||||||
r"""
|
r"""
|
||||||
the bspline order used for interpolation when using transforms
|
the bspline order used for interpolation when using transforms
|
||||||
@@ -293,7 +305,9 @@ class Imread:
|
|||||||
r"""
|
r"""
|
||||||
reshape the view with a new axis order
|
reshape the view with a new axis order
|
||||||
"""
|
"""
|
||||||
def squeeze(self) -> numpy.ndarray | int | float: ...
|
def squeeze(
|
||||||
|
self, axes: str | typing.Sequence[int | str] = None
|
||||||
|
) -> Imread | float | int: ...
|
||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
r"""
|
r"""
|
||||||
close the file: does nothing as this is handled automatically
|
close the file: does nothing as this is handled automatically
|
||||||
@@ -306,7 +320,19 @@ class Imread:
|
|||||||
r"""
|
r"""
|
||||||
change the data type of the view: (u)int(8/16/32) or float(32/64)
|
change the data type of the view: (u)int(8/16/32) or float(32/64)
|
||||||
"""
|
"""
|
||||||
def __getitem__(self, n: typing.Any) -> typing.Any:
|
def __call__(
|
||||||
|
self,
|
||||||
|
c: typing.Optional[int | slice | numpy.ArrayLike] = None,
|
||||||
|
z: typing.Optional[int | slice | numpy.ArrayLike] = None,
|
||||||
|
t: typing.Optional[int | slice | numpy.ArrayLike] = None,
|
||||||
|
y: typing.Optional[int | slice | numpy.ArrayLike] = None,
|
||||||
|
x: typing.Optional[int | slice | numpy.ArrayLike] = None,
|
||||||
|
) -> typing.Optional[int | Imread]:
|
||||||
|
r"""
|
||||||
|
same as im[] but allowing keyword axes, but slices need to made with slice()
|
||||||
|
also, no ellipsis or new axes
|
||||||
|
"""
|
||||||
|
def __getitem__(self, n: typing.Any) -> typing.Optional[int | Imread]:
|
||||||
r"""
|
r"""
|
||||||
slice the view and return a new view or a single number
|
slice the view and return a new view or a single number
|
||||||
"""
|
"""
|
||||||
@@ -314,7 +340,7 @@ class Imread:
|
|||||||
self,
|
self,
|
||||||
dtype: typing.Optional[numpy.typing.DTypeLike] = None,
|
dtype: typing.Optional[numpy.typing.DTypeLike] = None,
|
||||||
copy: typing.Optional[builtins.bool] = None,
|
copy: typing.Optional[builtins.bool] = None,
|
||||||
) -> typing.Any:
|
) -> numpy.typing.NDArray:
|
||||||
r"""
|
r"""
|
||||||
convert to a numpy array, optionally with a different dtype
|
convert to a numpy array, optionally with a different dtype
|
||||||
"""
|
"""
|
||||||
@@ -322,139 +348,199 @@ class Imread:
|
|||||||
r"""
|
r"""
|
||||||
check if an item is contained in the view (not implemented)
|
check if an item is contained in the view (not implemented)
|
||||||
"""
|
"""
|
||||||
def __lt__(self, other: typing.Any) -> typing.Any:
|
def __lt__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise less than comparison
|
element-wise less than comparison
|
||||||
"""
|
"""
|
||||||
def __le__(self, other: typing.Any) -> typing.Any:
|
def __le__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise less than or equal comparison
|
element-wise less than or equal comparison
|
||||||
"""
|
"""
|
||||||
def __eq__(self, other: typing.Any) -> typing.Any:
|
def __eq__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise equality comparison
|
element-wise equality comparison
|
||||||
"""
|
"""
|
||||||
def __ne__(self, other: typing.Any) -> typing.Any:
|
def __ne__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise not equal comparison
|
element-wise not equal comparison
|
||||||
"""
|
"""
|
||||||
def __gt__(self, other: typing.Any) -> typing.Any:
|
def __gt__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise greater than comparison
|
element-wise greater than comparison
|
||||||
"""
|
"""
|
||||||
def __ge__(self, other: typing.Any) -> typing.Any:
|
def __ge__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise greater than or equal comparison
|
element-wise greater than or equal comparison
|
||||||
"""
|
"""
|
||||||
def __add__(self, other: typing.Any) -> typing.Any:
|
def __add__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise addition
|
element-wise addition
|
||||||
"""
|
"""
|
||||||
def __radd__(self, other: typing.Any) -> typing.Any:
|
def __radd__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise addition (reflected)
|
element-wise addition (reflected)
|
||||||
"""
|
"""
|
||||||
def __sub__(self, other: typing.Any) -> typing.Any:
|
def __sub__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise subtraction
|
element-wise subtraction
|
||||||
"""
|
"""
|
||||||
def __rsub__(self, other: typing.Any) -> typing.Any:
|
def __rsub__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise subtraction (reflected)
|
element-wise subtraction (reflected)
|
||||||
"""
|
"""
|
||||||
def __mul__(self, other: typing.Any) -> typing.Any:
|
def __mul__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise multiplication
|
element-wise multiplication
|
||||||
"""
|
"""
|
||||||
def __rmul__(self, other: typing.Any) -> typing.Any:
|
def __rmul__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise multiplication (reflected)
|
element-wise multiplication (reflected)
|
||||||
"""
|
"""
|
||||||
def __truediv__(self, other: typing.Any) -> typing.Any:
|
def __truediv__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise true division
|
element-wise true division
|
||||||
"""
|
"""
|
||||||
def __rtruediv__(self, other: typing.Any) -> typing.Any:
|
def __rtruediv__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise true division (reflected)
|
element-wise true division (reflected)
|
||||||
"""
|
"""
|
||||||
def __floordiv__(self, other: typing.Any) -> typing.Any:
|
def __floordiv__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise floor division
|
element-wise floor division
|
||||||
"""
|
"""
|
||||||
def __rfloordiv__(self, other: typing.Any) -> typing.Any:
|
def __rfloordiv__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise floor division (reflected)
|
element-wise floor division (reflected)
|
||||||
"""
|
"""
|
||||||
def __mod__(self, other: typing.Any) -> typing.Any:
|
def __mod__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise modulo
|
element-wise modulo
|
||||||
"""
|
"""
|
||||||
def __rmod__(self, other: typing.Any) -> typing.Any:
|
def __rmod__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise modulo (reflected)
|
element-wise modulo (reflected)
|
||||||
"""
|
"""
|
||||||
def __matmul__(self, other: typing.Any) -> typing.Any:
|
def __matmul__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise matrix multiplication
|
element-wise matrix multiplication
|
||||||
"""
|
"""
|
||||||
def __rmatmul__(self, other: typing.Any) -> typing.Any:
|
def __rmatmul__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise matrix multiplication (reflected)
|
element-wise matrix multiplication (reflected)
|
||||||
"""
|
"""
|
||||||
def __and__(self, other: typing.Any) -> typing.Any:
|
def __and__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise bitwise AND
|
element-wise bitwise AND
|
||||||
"""
|
"""
|
||||||
def __rand__(self, other: typing.Any) -> typing.Any:
|
def __rand__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise bitwise AND (reflected)
|
element-wise bitwise AND (reflected)
|
||||||
"""
|
"""
|
||||||
def __or__(self, other: typing.Any) -> typing.Any:
|
def __or__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise bitwise OR
|
element-wise bitwise OR
|
||||||
"""
|
"""
|
||||||
def __ror__(self, other: typing.Any) -> typing.Any:
|
def __ror__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise bitwise OR (reflected)
|
element-wise bitwise OR (reflected)
|
||||||
"""
|
"""
|
||||||
def __xor__(self, other: typing.Any) -> typing.Any:
|
def __xor__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise bitwise XOR
|
element-wise bitwise XOR
|
||||||
"""
|
"""
|
||||||
def __rxor__(self, other: typing.Any) -> typing.Any:
|
def __rxor__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | bool:
|
||||||
r"""
|
r"""
|
||||||
element-wise bitwise XOR (reflected)
|
element-wise bitwise XOR (reflected)
|
||||||
"""
|
"""
|
||||||
def __lshift__(self, other: typing.Any) -> typing.Any:
|
def __lshift__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise left shift
|
element-wise left shift
|
||||||
"""
|
"""
|
||||||
def __rlshift__(self, other: typing.Any) -> typing.Any:
|
def __rlshift__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise left shift (reflected)
|
element-wise left shift (reflected)
|
||||||
"""
|
"""
|
||||||
def __rshift__(self, other: typing.Any) -> typing.Any:
|
def __rshift__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise right shift
|
element-wise right shift
|
||||||
"""
|
"""
|
||||||
def __rrshift__(self, other: typing.Any) -> typing.Any:
|
def __rrshift__(
|
||||||
|
self, other: float | numpy.ArrayLike | Imread
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise right shift (reflected)
|
element-wise right shift (reflected)
|
||||||
"""
|
"""
|
||||||
def __neg__(self) -> typing.Any:
|
def __neg__(self) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise negation
|
element-wise negation
|
||||||
"""
|
"""
|
||||||
def __pos__(self) -> typing.Any:
|
def __pos__(self) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise positive
|
element-wise positive
|
||||||
"""
|
"""
|
||||||
def __abs__(self) -> typing.Any:
|
def __abs__(self) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise absolute value
|
element-wise absolute value
|
||||||
"""
|
"""
|
||||||
def __invert__(self) -> typing.Any:
|
def __invert__(self) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
element-wise bitwise inversion
|
element-wise bitwise inversion
|
||||||
"""
|
"""
|
||||||
@@ -507,13 +593,19 @@ class Imread:
|
|||||||
r"""
|
r"""
|
||||||
the file path as a string
|
the file path as a string
|
||||||
"""
|
"""
|
||||||
|
def frame(
|
||||||
|
self, c: builtins.int, z: builtins.int, t: builtins.int
|
||||||
|
) -> numpy.typing.NDArray | float:
|
||||||
|
r"""
|
||||||
|
retrieve a single frame at czt, sliced accordingly, alias of get_frame
|
||||||
|
"""
|
||||||
def get_frame(
|
def get_frame(
|
||||||
self, c: builtins.int, z: builtins.int, t: builtins.int
|
self, c: builtins.int, z: builtins.int, t: builtins.int
|
||||||
) -> typing.Any:
|
) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
retrieve a single frame at czt, sliced accordingly
|
retrieve a single frame at czt, sliced accordingly
|
||||||
"""
|
"""
|
||||||
def flatten(self) -> typing.Any:
|
def flatten(self) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
flatten the view into a 1D numpy array
|
flatten the view into a 1D numpy array
|
||||||
"""
|
"""
|
||||||
@@ -529,6 +621,10 @@ class Imread:
|
|||||||
r"""
|
r"""
|
||||||
find the position of an axis
|
find the position of an axis
|
||||||
"""
|
"""
|
||||||
|
def swapaxes(self, ax0: int | str, ax1: int | str) -> Imread:
|
||||||
|
r"""
|
||||||
|
swap two axes
|
||||||
|
"""
|
||||||
def swap_axes(self, ax0: int | str, ax1: int | str) -> Imread:
|
def swap_axes(self, ax0: int | str, ax1: int | str) -> Imread:
|
||||||
r"""
|
r"""
|
||||||
swap two axes
|
swap two axes
|
||||||
@@ -539,7 +635,7 @@ class Imread:
|
|||||||
r"""
|
r"""
|
||||||
permute the order of the axes
|
permute the order of the axes
|
||||||
"""
|
"""
|
||||||
def as_array(self) -> typing.Any:
|
def as_array(self) -> numpy.typing.NDArray | float:
|
||||||
r"""
|
r"""
|
||||||
collect data into a numpy array
|
collect data into a numpy array
|
||||||
"""
|
"""
|
||||||
@@ -573,10 +669,6 @@ class Imread:
|
|||||||
r"""
|
r"""
|
||||||
the name of a particular channel
|
the name of a particular channel
|
||||||
"""
|
"""
|
||||||
def summary(self) -> builtins.str:
|
|
||||||
r"""
|
|
||||||
gives a helpful summary of the recorded experiment
|
|
||||||
"""
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_available_series(
|
def get_available_series(
|
||||||
path: str | pathlib.Path | Imread, reader: typing.Optional[builtins.str] = None
|
path: str | pathlib.Path | Imread, reader: typing.Optional[builtins.str] = None
|
||||||
@@ -793,7 +885,7 @@ class Shape:
|
|||||||
arguments for pickling
|
arguments for pickling
|
||||||
"""
|
"""
|
||||||
def __getitem__(
|
def __getitem__(
|
||||||
self, idx: str | int | None | Ellipsis | slice | list[int] | tuple[int]
|
self, idx: str | int | None | Ellipsis | slice | typing.Sequence[int]
|
||||||
) -> typing.Optional[int | tuple[int]]:
|
) -> typing.Optional[int | tuple[int]]:
|
||||||
r"""
|
r"""
|
||||||
get dimension size by index or axis name
|
get dimension size by index or axis name
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ ndbioimage_generate_stub = "ndbioimage:ndbioimage_generate_stub"
|
|||||||
|
|
||||||
[tool.maturin]
|
[tool.maturin]
|
||||||
python-source = "py"
|
python-source = "py"
|
||||||
features = ["python", "bioformats_java", "gpl-formats", "czi", "tiff", "tiffseq", "tiffwrite", "movie", "transforms"]
|
features = ["python", "bioformats_java", "gpl-formats", "bioformats_rust", "czi", "tiff", "tiffseq", "tiffwrite", "movie", "transforms"]
|
||||||
no-default-features = true
|
no-default-features = true
|
||||||
module-name = "ndbioimage.ndbioimage_rs"
|
module-name = "ndbioimage.ndbioimage_rs"
|
||||||
include = ["py/ndbioimage/jassets/j4rs*", "py/ndbioimage/deps/libj4rs*"]
|
include = ["py/ndbioimage/jassets/j4rs*", "py/ndbioimage/deps/libj4rs*"]
|
||||||
|
|||||||
+13
-4
@@ -314,16 +314,16 @@ impl Index<&Axis> for Shape {
|
|||||||
impl Index<usize> for Shape {
|
impl Index<usize> for Shape {
|
||||||
type Output = usize;
|
type Output = usize;
|
||||||
|
|
||||||
fn index(&self, dim: usize) -> &Self::Output {
|
fn index(&self, index: usize) -> &Self::Output {
|
||||||
&self[self.order[dim % self.order.len()]]
|
&self[self.order[index]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Index<&usize> for Shape {
|
impl Index<&usize> for Shape {
|
||||||
type Output = usize;
|
type Output = usize;
|
||||||
|
|
||||||
fn index(&self, dim: &usize) -> &Self::Output {
|
fn index(&self, index: &usize) -> &Self::Output {
|
||||||
&self[self.order[dim % self.order.len()]]
|
&self[self.order[*index]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +406,10 @@ impl Shape {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, index: &usize) -> Option<&usize> {
|
||||||
|
self.order.get(*index).map(|axis| &self[axis])
|
||||||
|
}
|
||||||
|
|
||||||
/// the number of axes in the shape
|
/// the number of axes in the shape
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.order.len()
|
self.order.len()
|
||||||
@@ -421,6 +425,11 @@ impl Shape {
|
|||||||
self.order.iter().map(|axis| self[axis]).collect()
|
self.order.iter().map(|axis| self[axis]).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// the sizes in cztyx order
|
||||||
|
pub fn cztyx(&self) -> [usize; 5] {
|
||||||
|
[self.c, self.z, self.t, self.y, self.x]
|
||||||
|
}
|
||||||
|
|
||||||
/// the sizes along the axes as a map from axis to size
|
/// the sizes along the axes as a map from axis to size
|
||||||
pub fn to_hashmap(&self) -> HashMap<Axis, usize> {
|
pub fn to_hashmap(&self) -> HashMap<Axis, usize> {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
|
|||||||
+483
-188
File diff suppressed because it is too large.
Load diff
@@ -188,6 +188,12 @@ pub trait Reader: Clone + Sized + Debug + Send + Hash + Into<DynReader> {
|
|||||||
where
|
where
|
||||||
P: AsRef<Path>;
|
P: AsRef<Path>;
|
||||||
|
|
||||||
|
/// a simple fast test to see if the reader can open a path without parsing the whole file
|
||||||
|
/// not a guarantee of success, but rather an early failure
|
||||||
|
fn can_open<P>(path: P) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>;
|
||||||
|
|
||||||
/// the name of the reader type
|
/// the name of the reader type
|
||||||
fn reader_name(&self) -> &'static str {
|
fn reader_name(&self) -> &'static str {
|
||||||
type_name::<Self>()
|
type_name::<Self>()
|
||||||
@@ -478,6 +484,34 @@ impl Reader for DynReader {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn can_open<P>(path: P) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let mut can_open = false;
|
||||||
|
#[cfg(feature = "tiff")]
|
||||||
|
{
|
||||||
|
can_open |= tiff::TiffReader::can_open(&path)?;
|
||||||
|
}
|
||||||
|
#[cfg(feature = "tiffseq")]
|
||||||
|
{
|
||||||
|
can_open |= tiffseq::TiffSeqReader::can_open(&path)?;
|
||||||
|
}
|
||||||
|
#[cfg(feature = "czi")]
|
||||||
|
{
|
||||||
|
can_open |= czi::CziReader::can_open(&path)?;
|
||||||
|
}
|
||||||
|
#[cfg(feature = "bioformats_rust")]
|
||||||
|
{
|
||||||
|
can_open |= bioformats_rust::BioFormatsRustReader::can_open(&path)?;
|
||||||
|
}
|
||||||
|
#[cfg(feature = "bioformats_java")]
|
||||||
|
{
|
||||||
|
can_open |= bioformats_java::BioFormatsJavaReader::can_open(&path)?;
|
||||||
|
}
|
||||||
|
Ok(can_open)
|
||||||
|
}
|
||||||
|
|
||||||
fn reader_name(&self) -> &'static str {
|
fn reader_name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "tiff")]
|
#[cfg(feature = "tiff")]
|
||||||
|
|||||||
@@ -666,6 +666,13 @@ impl Reader for BioFormatsJavaReader {
|
|||||||
Ok(new)
|
Ok(new)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn can_open<P>(_path: P) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Result<Ome, Error> {
|
fn metadata(&self) -> Result<Ome, Error> {
|
||||||
self.get_ome()
|
self.get_ome()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,6 +274,13 @@ impl Reader for BioFormatsRustReader {
|
|||||||
Ok(new)
|
Ok(new)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn can_open<P>(path: P) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
Ok(path.as_ref().extension() != Some(std::ffi::OsStr::new("czi")))
|
||||||
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Result<Ome, Error> {
|
fn metadata(&self) -> Result<Ome, Error> {
|
||||||
let reader = self.get_reader()?;
|
let reader = self.get_reader()?;
|
||||||
let metadata = reader.metadata();
|
let metadata = reader.metadata();
|
||||||
|
|||||||
@@ -215,6 +215,13 @@ impl Reader for CziReader {
|
|||||||
Ok(new)
|
Ok(new)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn can_open<P>(path: P) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
Ok(path.as_ref().extension() == Some(std::ffi::OsStr::new("czi")))
|
||||||
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Result<Ome, Error> {
|
fn metadata(&self) -> Result<Ome, Error> {
|
||||||
let mut ome = Ome::default();
|
let mut ome = Ome::default();
|
||||||
let xml = xmltree::Element::parse(self.metadata_xml()?.as_bytes())?;
|
let xml = xmltree::Element::parse(self.metadata_xml()?.as_bytes())?;
|
||||||
|
|||||||
@@ -232,6 +232,24 @@ impl Reader for TiffReader {
|
|||||||
Ok(new)
|
Ok(new)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn can_open<P>(path: P) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let path = path.as_ref();
|
||||||
|
let mut file = File::open(path)?;
|
||||||
|
let mut sig = [0; 2];
|
||||||
|
file.read_exact(&mut sig)?;
|
||||||
|
if sig == [73, 73] {
|
||||||
|
file.read_exact(&mut sig)?;
|
||||||
|
Ok((sig[0] == 42) || (sig[0] == 43))
|
||||||
|
} else if sig == [77, 77] {
|
||||||
|
Ok((sig[1] == 42) || (sig[1] == 43))
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Result<Ome, Error> {
|
fn metadata(&self) -> Result<Ome, Error> {
|
||||||
let mut reader = self.get_reader()?;
|
let mut reader = self.get_reader()?;
|
||||||
let image_description = reader.current_ifd().get_tag(Tag::ImageDescription);
|
let image_description = reader.current_ifd().get_tag(Tag::ImageDescription);
|
||||||
@@ -466,18 +484,36 @@ impl Reader for TiffReader {
|
|||||||
&self.pixel_type
|
&self.pixel_type
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_available_positions<P>(_path: P, _series: usize) -> Result<HashSet<usize>, Error>
|
fn get_available_positions<P>(path: P, _series: usize) -> Result<HashSet<usize>, Error>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
Ok(HashSet::from([0]))
|
let path = path.as_ref();
|
||||||
|
if Self::can_open(path)? {
|
||||||
|
Ok(HashSet::from([0]))
|
||||||
|
} else {
|
||||||
|
Err(Error::InvalidReader(
|
||||||
|
"TiffReader".to_string(),
|
||||||
|
path.to_string_lossy().to_string(),
|
||||||
|
"it is not a tiff".to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_available_series<P>(_path: P) -> Result<HashSet<usize>, Error>
|
fn get_available_series<P>(path: P) -> Result<HashSet<usize>, Error>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
Ok(HashSet::from([0]))
|
let path = path.as_ref();
|
||||||
|
if Self::can_open(path)? {
|
||||||
|
Ok(HashSet::from([0]))
|
||||||
|
} else {
|
||||||
|
Err(Error::InvalidReader(
|
||||||
|
"TiffReader".to_string(),
|
||||||
|
path.to_string_lossy().to_string(),
|
||||||
|
"it is not a tiff".to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -239,6 +239,13 @@ impl Reader for TiffSeqReader {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn can_open<P>(path: P) -> Result<bool, Error>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
Ok(path.as_ref().is_dir())
|
||||||
|
}
|
||||||
|
|
||||||
fn metadata(&self) -> Result<Ome, Error> {
|
fn metadata(&self) -> Result<Ome, Error> {
|
||||||
let mut ome = Ome::default();
|
let mut ome = Ome::default();
|
||||||
let info = self.metadata_map.get("Info").and_then(|v| v.as_mapping());
|
let info = self.metadata_map.get("Info").and_then(|v| v.as_mapping());
|
||||||
@@ -580,11 +587,20 @@ impl Reader for TiffSeqReader {
|
|||||||
&self.pixel_type
|
&self.pixel_type
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_available_positions<P>(_path: P, _series: usize) -> Result<HashSet<usize>, Error>
|
fn get_available_positions<P>(path: P, _series: usize) -> Result<HashSet<usize>, Error>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
Ok(HashSet::from([0]))
|
let path = path.as_ref();
|
||||||
|
if Self::can_open(path)? {
|
||||||
|
Ok(HashSet::from([0]))
|
||||||
|
} else {
|
||||||
|
Err(Error::InvalidReader(
|
||||||
|
"TiffSeqReader".to_string(),
|
||||||
|
path.to_string_lossy().to_string(),
|
||||||
|
"not a tiff sequence".to_string(),
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_available_series<P>(path: P) -> Result<HashSet<usize>, Error>
|
fn get_available_series<P>(path: P) -> Result<HashSet<usize>, Error>
|
||||||
|
|||||||
@@ -284,6 +284,21 @@ impl<D: Dimension, R: Reader> View<D, R> {
|
|||||||
.ok_or(Error::NoChannel(channel))
|
.ok_or(Error::NoChannel(channel))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// names of the channels in order
|
||||||
|
pub fn channel_names(&self) -> Result<HashMap<usize, String>, Error> {
|
||||||
|
if self.channel_names.get().is_none() {
|
||||||
|
let names = self.metadata()?.image[0]
|
||||||
|
.pixels
|
||||||
|
.channel
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, c)| (i, c.name.clone().unwrap_or_else(|| format!("{}", i))))
|
||||||
|
.collect::<HashMap<_, _>>();
|
||||||
|
let _ = self.channel_names.set(names);
|
||||||
|
}
|
||||||
|
Ok(self.channel_names.get().cloned().unwrap_or_default())
|
||||||
|
}
|
||||||
|
|
||||||
/// set the maximum number of frames the process-wide cache may hold,
|
/// set the maximum number of frames the process-wide cache may hold,
|
||||||
/// evicting the least recently used frames
|
/// evicting the least recently used frames
|
||||||
pub fn with_cache_capacity(self, capacity: usize) -> Self {
|
pub fn with_cache_capacity(self, capacity: usize) -> Self {
|
||||||
@@ -404,6 +419,28 @@ impl<D: Dimension, R: Reader> View<D, R> {
|
|||||||
view.slice(slice.as_slice())
|
view.slice(slice.as_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// remove axes of size 1 in axes
|
||||||
|
pub fn squeeze_axes(&self, axes: HashSet<Axis>) -> Result<View<IxDyn, R>, Error> {
|
||||||
|
let view = self.clone().into_dyn();
|
||||||
|
let slice: Vec<_> = self
|
||||||
|
.shape()
|
||||||
|
.into_iter()
|
||||||
|
.zip(self.axes().iter())
|
||||||
|
.map(|(s, a)| {
|
||||||
|
if s == 1 && axes.contains(a) {
|
||||||
|
SliceInfoElem::Index(0)
|
||||||
|
} else {
|
||||||
|
SliceInfoElem::Slice {
|
||||||
|
start: 0,
|
||||||
|
end: None,
|
||||||
|
step: 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
view.slice(slice.as_slice())
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn op_axes(&self) -> Vec<Axis> {
|
pub(crate) fn op_axes(&self) -> Vec<Axis> {
|
||||||
self.operations.keys().cloned().collect()
|
self.operations.keys().cloned().collect()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ def image(array):
|
|||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"s",
|
"s",
|
||||||
combinations_with_replacement(
|
list(
|
||||||
(0, -1, 1, slice(None), slice(0, 1), slice(-1, 0), slice(1, 1)), 5
|
combinations_with_replacement(
|
||||||
|
(0, -1, 1, slice(None), slice(0, 1), slice(-1, 0), slice(1, 1)), 5
|
||||||
|
)
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_slicing(s, image, array):
|
def test_slicing(s, image, array):
|
||||||
|
|||||||
@@ -26,24 +26,26 @@ def image(array):
|
|||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"fun_and_axis",
|
"fun_and_axis",
|
||||||
product(
|
list(
|
||||||
(
|
product(
|
||||||
np.sum,
|
(
|
||||||
np.nansum,
|
np.sum,
|
||||||
np.min,
|
np.nansum,
|
||||||
np.nanmin,
|
np.min,
|
||||||
np.max,
|
np.nanmin,
|
||||||
np.nanmax,
|
np.max,
|
||||||
np.argmin,
|
np.nanmax,
|
||||||
np.argmax,
|
np.argmin,
|
||||||
np.mean,
|
np.argmax,
|
||||||
np.nanmean,
|
np.mean,
|
||||||
np.var,
|
np.nanmean,
|
||||||
np.nanvar,
|
np.var,
|
||||||
np.std,
|
np.nanvar,
|
||||||
np.nanstd,
|
np.std,
|
||||||
),
|
np.nanstd,
|
||||||
(None, 0, 1, 2, 3, 4),
|
),
|
||||||
|
(None, 0, 1, 2, 3, 4),
|
||||||
|
)
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
def test_ufuncs(fun_and_axis, image, array):
|
def test_ufuncs(fun_and_axis, image, array):
|
||||||
|
|||||||
Reference in new issue
Block a user