@@ -18,15 +18,45 @@ function load(io::Stream{format"OMETIFF"})
18
18
images = find (omexml, " /ns:OME/ns:Image" ,[" ns" => namespace (omexml)])
19
19
results = Array {AxisArray} (length (images))
20
20
21
- for (idx, image) in enumerate (images)
22
- files = Dict {String, TiffFile} ()
21
+ pos_names = nodecontent .(find (omexml, " /ns:OME/ns:Image/ns:StageLabel[@Name]/@Name" ,[" ns" => namespace (omexml)]))
22
+ # if all position names aren't unique then substitute names
23
+ if length (pos_names) == 0 || ! allunique (pos_names)
24
+ pos_names = [" Pos$i " for i in 1 : length (images)]
25
+ end
23
26
27
+ pixels = []
28
+ master_rawtype = Nullable {DataType} ()
29
+ mappedtype = Int64
30
+ master_dims = []
31
+ axes_dims = Nullable {Vector{AxisArrays.Axis}} ()
32
+ for (idx, image) in enumerate (images)
24
33
pixel = findfirst (image, " ./ns:Pixels" , [" ns" => namespace (omexml)])
25
- tiffdatas = find (pixel, " ./ns:TiffData" , [" ns" => namespace (omexml)])
26
-
34
+ dims, axes_info = build_axes (pixel)
27
35
rawtype, mappedtype = type_mapping[pixel[" Type" ]]
28
36
29
- dims, axes_info = build_axes (pixel)
37
+ if isnull (master_rawtype)
38
+ master_rawtype = Nullable (rawtype)
39
+ elseif get (master_rawtype) != rawtype
40
+ throw (FileIO. LoaderError (" OMETIFF" , " Multiple different storage types not supported in a multi position image" ))
41
+ end
42
+
43
+ if isnull (axes_dims)
44
+ axes_dims = Nullable (axes_info)
45
+ master_dims = dims
46
+ elseif get (axes_dims) != axes_info
47
+ throw (FileIO. LoaderError (" OMETIFF" , " Axes changing between multiple imaging positions is not supported yet" ))
48
+ end
49
+ push! (pixels, pixel)
50
+ end
51
+ push! (get (axes_dims), Axis {:position} (Symbol .(pos_names)))
52
+ push! (master_dims, length (pos_names))
53
+
54
+ data = Array {get(master_rawtype), length(master_dims)} (master_dims... )
55
+
56
+ for (pos_idx, pixel) in enumerate (pixels)
57
+ files = Dict {String, TiffFile} ()
58
+
59
+ tiffdatas = find (pixel, " ./ns:TiffData" , [" ns" => namespace (omexml)])
30
60
31
61
# TODO : Only the IFDs with a corresponding slice should be loaded.
32
62
slices = DefaultDict {String, Dict{Int, ImageSlice}} (Dict {Int, ImageSlice} ())
@@ -35,8 +65,7 @@ function load(io::Stream{format"OMETIFF"})
35
65
slices[slice. file. filepath][slice. ifd_idx] = slice
36
66
end
37
67
38
- data = Array {rawtype, length(dims)} (dims... )
39
- height, width = dims[1 : 2 ]
68
+ height, width = master_dims[1 : 2 ]
40
69
41
70
for (filepath, ifds) in slices
42
71
file = files[filepath]
@@ -49,26 +78,25 @@ function load(io::Stream{format"OMETIFF"})
49
78
read_dims = n_strips > 1 ? (strip_len) : (height, width)
50
79
51
80
# TODO : This shouldn't be allocated for each ifd
52
- tmp = Array {rawtype } (read_dims... )
81
+ tmp = Array {get(master_rawtype) } (read_dims... )
53
82
for j in 1 : n_strips
54
83
seek (file. io, strip_offsets[j])
55
84
read! (file. io, tmp)
56
85
tmp = file. need_bswap ? bswap .(tmp) : tmp
57
86
if n_strips > 1
58
- data[j, :, ifd. z_idx, ifd. c_idx, ifd. t_idx]= tmp
87
+ data[j, :, ifd. z_idx, ifd. c_idx, ifd. t_idx, pos_idx ]= tmp
59
88
else
60
- data[:, :, ifd. z_idx, ifd. c_idx, ifd. t_idx] = tmp
89
+ data[:, :, ifd. z_idx, ifd. c_idx, ifd. t_idx, pos_idx ] = tmp
61
90
end
62
91
end
63
92
end
64
93
end
65
94
66
95
# drop unnecessary axes
67
96
# TODO : Reduce the number of allocations here
68
- squeezed_data = squeeze (Gray .(reinterpret (mappedtype, data)), (find (dims .== 1 )... ))
69
- results[idx] = AxisArray (squeezed_data, axes_info[dims .> 1 ]. .. )
70
97
end
71
- length (results) == 1 ? results[1 ] : results
98
+ squeezed_data = squeeze (Gray .(reinterpret (mappedtype, data)), (find (master_dims .== 1 )... ))
99
+ AxisArray (squeezed_data, get (axes_dims)[master_dims .> 1 ]. .. )
72
100
end
73
101
74
102
""" Corresponding Julian types for OME-XML types"""
0 commit comments