1mod bioformats;
2
3pub mod axes;
4pub mod metadata;
5#[cfg(feature = "python")]
6mod py;
7pub mod reader;
8pub mod stats;
9pub mod view;
10
11pub mod colors;
12#[cfg(feature = "movie")]
13pub mod movie;
14#[cfg(feature = "tiff")]
15pub mod tiff;
16
17pub use bioformats::download_bioformats;
18
19#[cfg(test)]
20mod tests {
21 use crate::axes::Axis;
22 use crate::reader::{Frame, Reader};
23 use crate::stats::MinMax;
24 use crate::view::Item;
25 use anyhow::Result;
26 use ndarray::{Array, Array4, Array5, NewAxis};
27 use ndarray::{Array2, s};
28 use rayon::prelude::*;
29
30 fn open(file: &str) -> Result<Reader> {
31 let path = std::env::current_dir()?
32 .join("tests")
33 .join("files")
34 .join(file);
35 Reader::new(&path, 0)
36 }
37
38 fn get_pixel_type(file: &str) -> Result<String> {
39 let reader = open(file)?;
40 Ok(format!(
41 "file: {}, pixel type: {:?}",
42 file, reader.pixel_type
43 ))
44 }
45
46 fn get_frame(file: &str) -> Result<Frame> {
47 let reader = open(file)?;
48 reader.get_frame(0, 0, 0)
49 }
50
51 #[test]
52 fn read_ser() -> Result<()> {
53 let file = "Experiment-2029.czi";
54 let reader = open(file)?;
55 println!("size: {}, {}", reader.size_y, reader.size_y);
56 let frame = reader.get_frame(0, 0, 0)?;
57 if let Ok(arr) = <Frame as TryInto<Array2<i8>>>::try_into(frame) {
58 println!("{:?}", arr);
59 } else {
60 println!("could not convert Frame to Array<i8>");
61 }
62 Ok(())
63 }
64
65 #[test]
66 fn read_par() -> Result<()> {
67 let files = vec!["Experiment-2029.czi", "test.tif"];
68 let pixel_type = files
69 .into_par_iter()
70 .map(|file| get_pixel_type(file).unwrap())
71 .collect::<Vec<_>>();
72 println!("{:?}", pixel_type);
73 Ok(())
74 }
75
76 #[test]
77 fn read_frame_par() -> Result<()> {
78 let files = vec!["Experiment-2029.czi", "test.tif"];
79 let frames = files
80 .into_par_iter()
81 .map(|file| get_frame(file).unwrap())
82 .collect::<Vec<_>>();
83 println!("{:?}", frames);
84 Ok(())
85 }
86
87 #[test]
88 fn read_sequence() -> Result<()> {
89 let file = "YTL1841B2-2-1_1hr_DMSO_galinduction_1/Pos0/img_000000000_mScarlet_GFP-mSc-filter_004.tif";
90 let reader = open(file)?;
91 println!("reader: {:?}", reader);
92 let frame = reader.get_frame(0, 4, 0)?;
93 println!("frame: {:?}", frame);
94 let frame = reader.get_frame(0, 2, 0)?;
95 println!("frame: {:?}", frame);
96 Ok(())
97 }
98
99 #[test]
100 fn read_sequence1() -> Result<()> {
101 let file = "4-Pos_001_002/img_000000000_Cy3-Cy3_filter_000.tif";
102 let reader = open(file)?;
103 println!("reader: {:?}", reader);
104 Ok(())
105 }
106
107 #[test]
108 fn ome_xml() -> Result<()> {
109 let file = "Experiment-2029.czi";
110 let reader = open(file)?;
111 let xml = reader.get_ome_xml()?;
112 println!("{}", xml);
113 Ok(())
114 }
115
116 #[test]
117 fn view() -> Result<()> {
118 let file = "YTL1841B2-2-1_1hr_DMSO_galinduction_1/Pos0/img_000000000_mScarlet_GFP-mSc-filter_004.tif";
119 let reader = open(file)?;
120 let view = reader.view();
121 let a = view.slice(s![0, 5, 0, .., ..])?;
122 let b = reader.get_frame(0, 5, 0)?;
123 let c: Array2<isize> = a.try_into()?;
124 let d: Array2<isize> = b.try_into()?;
125 assert_eq!(c, d);
126 Ok(())
127 }
128
129 #[test]
130 fn view_shape() -> Result<()> {
131 let file = "YTL1841B2-2-1_1hr_DMSO_galinduction_1/Pos0/img_000000000_mScarlet_GFP-mSc-filter_004.tif";
132 let reader = open(file)?;
133 let view = reader.view();
134 let a = view.slice(s![0, ..5, 0, .., 100..200])?;
135 let shape = a.shape();
136 assert_eq!(shape, vec![5, 1024, 100]);
137 Ok(())
138 }
139
140 #[test]
141 fn view_new_axis() -> Result<()> {
142 let file = "YTL1841B2-2-1_1hr_DMSO_galinduction_1/Pos0/img_000000000_mScarlet_GFP-mSc-filter_004.tif";
143 let reader = open(file)?;
144 let view = reader.view();
145 let a = Array5::<u8>::zeros((1, 9, 1, 1024, 1024));
146 let a = a.slice(s![0, ..5, 0, NewAxis, 100..200, ..]);
147 let v = view.slice(s![0, ..5, 0, NewAxis, 100..200, ..])?;
148 assert_eq!(v.shape(), a.shape());
149 let a = a.slice(s![NewAxis, .., .., NewAxis, .., .., NewAxis]);
150 let v = v.slice(s![NewAxis, .., .., NewAxis, .., .., NewAxis])?;
151 assert_eq!(v.shape(), a.shape());
152 Ok(())
153 }
154
155 #[test]
156 fn view_permute_axes() -> Result<()> {
157 let file = "YTL1841B2-2-1_1hr_DMSO_galinduction_1/Pos0/img_000000000_mScarlet_GFP-mSc-filter_004.tif";
158 let reader = open(file)?;
159 let view = reader.view();
160 let s = view.shape();
161 let mut a = Array5::<u8>::zeros((s[0], s[1], s[2], s[3], s[4]));
162 assert_eq!(view.shape(), a.shape());
163 let b: Array5<usize> = view.clone().try_into()?;
164 assert_eq!(b.shape(), a.shape());
165
166 let view = view.swap_axes(Axis::C, Axis::Z)?;
167 a.swap_axes(0, 1);
168 assert_eq!(view.shape(), a.shape());
169 let b: Array5<usize> = view.clone().try_into()?;
170 assert_eq!(b.shape(), a.shape());
171 let view = view.permute_axes(&[Axis::X, Axis::Z, Axis::Y])?;
172 let a = a.permuted_axes([4, 1, 2, 0, 3]);
173 assert_eq!(view.shape(), a.shape());
174 let b: Array5<usize> = view.clone().try_into()?;
175 assert_eq!(b.shape(), a.shape());
176 Ok(())
177 }
178
179 macro_rules! test_max {
180 ($($name:ident: $b:expr $(,)?)*) => {
181 $(
182 #[test]
183 fn $name() -> Result<()> {
184 let file = "YTL1841B2-2-1_1hr_DMSO_galinduction_1/Pos0/img_000000000_mScarlet_GFP-mSc-filter_004.tif";
185 let reader = open(file)?;
186 let view = reader.view();
187 let array: Array5<usize> = view.clone().try_into()?;
188 let view = view.max_proj($b)?;
189 let a: Array4<usize> = view.clone().try_into()?;
190 let b = array.max($b)?;
191 assert_eq!(a.shape(), b.shape());
192 assert_eq!(a, b);
193 Ok(())
194 }
195 )*
196 };
197 }
198
199 test_max! {
200 max_c: 0
201 max_z: 1
202 max_t: 2
203 max_y: 3
204 max_x: 4
205 }
206
207 macro_rules! test_index {
208 ($($name:ident: $b:expr $(,)?)*) => {
209 $(
210 #[test]
211 fn $name() -> Result<()> {
212 let file = "YTL1841B2-2-1_1hr_DMSO_galinduction_1/Pos0/img_000000000_mScarlet_GFP-mSc-filter_004.tif";
213 let reader = open(file)?;
214 let view = reader.view();
215 let v4: Array<usize, _> = view.slice($b)?.try_into()?;
216 let a5: Array5<usize> = reader.view().try_into()?;
217 let a4 = a5.slice($b).to_owned();
218 assert_eq!(a4, v4);
219 Ok(())
220 }
221 )*
222 };
223 }
224
225 test_index! {
226 index_0: s![.., .., .., .., ..]
227 index_1: s![0, .., .., .., ..]
228 index_2: s![.., 0, .., .., ..]
229 index_3: s![.., .., 0, .., ..]
230 index_4: s![.., .., .., 0, ..]
231 index_5: s![.., .., .., .., 0]
232 index_6: s![0, 0, .., .., ..]
233 index_7: s![0, .., 0, .., ..]
234 index_8: s![0, .., .., 0, ..]
235 index_9: s![0, .., .., .., 0]
236 index_a: s![.., 0, 0, .., ..]
237 index_b: s![.., 0, .., 0, ..]
238 index_c: s![.., 0, .., .., 0]
239 index_d: s![.., .., 0, 0, ..]
240 index_e: s![.., .., 0, .., 0]
241 index_f: s![.., .., .., 0, 0]
242 index_g: s![0, 0, 0, .., ..]
243 index_h: s![0, 0, .., 0, ..]
244 index_i: s![0, 0, .., .., 0]
245 index_j: s![0, .., 0, 0, ..]
246 index_k: s![0, .., 0, .., 0]
247 index_l: s![0, .., .., 0, 0]
248 index_m: s![0, 0, 0, 0, ..]
249 index_n: s![0, 0, 0, .., 0]
250 index_o: s![0, 0, .., 0, 0]
251 index_p: s![0, .., 0, 0, 0]
252 index_q: s![.., 0, 0, 0, 0]
253 index_r: s![0, 0, 0, 0, 0]
254 }
255
256 #[test]
257 fn dyn_view() -> Result<()> {
258 let file = "YTL1841B2-2-1_1hr_DMSO_galinduction_1/Pos0/img_000000000_mScarlet_GFP-mSc-filter_004.tif";
259 let reader = open(file)?;
260 let a = reader.view().into_dyn();
261 let b = a.max_proj(1)?;
262 let c = b.slice(s![0, 0, .., ..])?;
263 let d = c.as_array::<usize>()?;
264 assert_eq!(d.shape(), [1024, 1024]);
265 Ok(())
266 }
267
268 #[test]
269 fn item() -> Result<()> {
270 let file = "1xp53-01-AP1.czi";
271 let reader = open(file)?;
272 let view = reader.view();
273 let a = view.slice(s![.., 0, 0, 0, 0])?;
274 let b = a.slice(s![0])?;
275 let item = b.item::<usize>()?;
276 assert_eq!(item, 2);
277 Ok(())
278 }
279
280 #[test]
281 fn slice_cztyx() -> Result<()> {
282 let file = "1xp53-01-AP1.czi";
283 let reader = open(file)?;
284 let view = reader.view().max_proj(Axis::Z)?.into_dyn();
285 println!("view.axes: {:?}", view.get_axes());
286 println!("view.slice: {:?}", view.get_slice());
287 let r = view.reset_axes()?;
288 println!("r.axes: {:?}", r.get_axes());
289 println!("r.slice: {:?}", r.get_slice());
290 let a = view.slice_cztyx(s![0, 0, 0, .., ..])?;
291 println!("a.axes: {:?}", a.get_axes());
292 println!("a.slice: {:?}", a.get_slice());
293 assert_eq!(a.axes(), [Axis::Y, Axis::X]);
294 Ok(())
295 }
296
297 #[test]
298 fn reset_axes() -> Result<()> {
299 let file = "1xp53-01-AP1.czi";
300 let reader = open(file)?;
301 let view = reader.view().max_proj(Axis::Z)?;
302 let view = view.reset_axes()?;
303 assert_eq!(view.axes(), [Axis::C, Axis::New, Axis::T, Axis::Y, Axis::X]);
304 let a = view.as_array::<f64>()?;
305 assert_eq!(a.ndim(), 5);
306 Ok(())
307 }
308
309 #[test]
310 fn reset_axes2() -> Result<()> {
311 let file = "Experiment-2029.czi";
312 let reader = open(file)?;
313 let view = reader.view().squeeze()?;
314 let a = view.reset_axes()?;
315 assert_eq!(a.axes(), [Axis::C, Axis::Z, Axis::T, Axis::Y, Axis::X]);
316 Ok(())
317 }
318
319 #[test]
320 fn reset_axes3() -> Result<()> {
321 let file = "Experiment-2029.czi";
322 let reader = open(file)?;
323 let view4 = reader.view().squeeze()?;
324 let view = view4.max_proj(Axis::Z)?.into_dyn();
325 let slice = view.slice_cztyx(s![0, .., .., .., ..])?.into_dyn();
326 let a = slice.as_array::<u16>()?;
327 assert_eq!(slice.shape(), [1, 10, 1280, 1280]);
328 assert_eq!(a.shape(), [1, 10, 1280, 1280]);
329 let r = slice.reset_axes()?;
330 let b = r.as_array::<u16>()?;
331 assert_eq!(r.shape(), [1, 1, 10, 1280, 1280]);
332 assert_eq!(b.shape(), [1, 1, 10, 1280, 1280]);
333 let q = slice.max_proj(Axis::C)?.max_proj(Axis::T)?;
334 let c = q.as_array::<f64>()?;
335 assert_eq!(q.shape(), [1, 1280, 1280]);
336 assert_eq!(c.shape(), [1, 1280, 1280]);
337 let p = q.reset_axes()?;
338 let d = p.as_array::<u16>()?;
339 println!("axes: {:?}", p.get_axes());
340 println!("operations: {:?}", p.get_operations());
341 println!("slice: {:?}", p.get_slice());
342 assert_eq!(p.shape(), [1, 1, 1, 1280, 1280]);
343 assert_eq!(d.shape(), [1, 1, 1, 1280, 1280]);
344 Ok(())
345 }
346
347 #[test]
348 fn max() -> Result<()> {
349 let file = "Experiment-2029.czi";
350 let reader = open(file)?;
351 let view = reader.view();
352 let m = view.max_proj(Axis::T)?;
353 let a = m.as_array::<u16>()?;
354 assert_eq!(m.shape(), [2, 1, 1280, 1280]);
355 assert_eq!(a.shape(), [2, 1, 1280, 1280]);
356 let mc = view.max_proj(Axis::C)?;
357 let a = mc.as_array::<u16>()?;
358 assert_eq!(mc.shape(), [1, 10, 1280, 1280]);
359 assert_eq!(a.shape(), [1, 10, 1280, 1280]);
360 let mz = mc.max_proj(Axis::Z)?;
361 let a = mz.as_array::<u16>()?;
362 assert_eq!(mz.shape(), [10, 1280, 1280]);
363 assert_eq!(a.shape(), [10, 1280, 1280]);
364 let mt = mz.max_proj(Axis::T)?;
365 let a = mt.as_array::<u16>()?;
366 assert_eq!(mt.shape(), [1280, 1280]);
367 assert_eq!(a.shape(), [1280, 1280]);
368 Ok(())
369 }
370}