Skip to content

Commit 4e59f9f

Browse files
authored
Merge pull request #18 from tlnagy/tn/update-for-1.0
Update for Julia 1.0 and EzXML 0.8
2 parents 03a8963 + 7e2161c commit 4e59f9f

File tree

7 files changed

+62
-46
lines changed

7 files changed

+62
-46
lines changed

.travis.yml

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ os:
44
- linux
55
- osx
66
julia:
7-
- 0.6
8-
- 0.7
7+
- 1.0
98
- nightly
109
notifications:
1110
email: false
@@ -31,4 +30,4 @@ matrix:
3130
# - julia -e 'Pkg.clone(pwd()); Pkg.build("OMETIFF"); Pkg.test("OMETIFF"; coverage=true)'
3231
after_success:
3332
# push coverage results to Codecov
34-
- julia -e 'cd(Pkg.dir("OMETIFF")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
33+
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())'

REQUIRE

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
julia 0.6
2-
EzXML 0.4.2
1+
julia 0.7
2+
EzXML 0.8
33
Unitful
44
FixedPointNumbers
55
FileIO

src/files.jl

+30-15
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,21 @@ function loadxml(file::TiffFile)
5353
rawxml = ""
5454

5555
for i in 1:number_of_entries
56-
tag_bytes = Unsigned[]
57-
append!(tag_bytes, read(file.io, UInt16, 2))
58-
append!(tag_bytes, read(file.io, UInt32, 2))
59-
tag_id, tag_type, data_count, data_offset = Int.(do_bswap(file, tag_bytes))
56+
combined = Unsigned[]
57+
tag_info = Array{UInt16}(undef, 2)
58+
data_info = Array{UInt32}(undef, 2)
59+
read!(file.io, tag_info)
60+
read!(file.io, data_info)
61+
append!(combined, tag_info)
62+
append!(combined, data_info)
63+
tag_id, tag_type, data_count, data_offset = Int.(do_bswap(file, combined))
6064

6165
if tag_id == 270 # Image Description tag
6266
seek(file.io, data_offset)
6367
# strip null values from string
64-
raw_str = replace(String(read(file.io, UInt8, data_count)), "\0", "")
68+
_data = Array{UInt8}(undef, data_count)
69+
read!(file.io, _data)
70+
raw_str = replace(String(_data), "\0"=>"")
6571
# check if is xml since ImageJ display settings are also stored in
6672
# ImageDescription tags
6773
# TODO: This should be replaced with some proper validation
@@ -87,7 +93,8 @@ function load_master_xml(file::TiffFile)
8793
omexml = loadxml(file)
8894
try
8995
# Check if the full OME-XML metadata is stored in another file
90-
metadata_file = findfirst(omexml, "/ns:OME/ns:BinaryOnly", ["ns"=>namespace(omexml)])
96+
metadata_file = findfirst("/ns:OME/ns:BinaryOnly", omexml, ["ns"=>namespace(omexml)])
97+
(metadata_file == nothing) && return omexml
9198
uuid, filepath = metadata_file["UUID"], joinpath(dirname(file.filepath), metadata_file["MetadataFile"])
9299

93100
# we have a companion metadata file
@@ -108,12 +115,12 @@ end
108115

109116

110117
"""
111-
Base.next(file::TiffFile)
118+
next(file::TiffFile)
112119
113120
Loads the next IFD in `file` and returns a list of the strip offsets to load the
114121
data stored in this IFD.
115122
"""
116-
function Base.next(file::TiffFile)
123+
function next(file::TiffFile)
117124
next_ifd, strip_offset_list = _next(file, file.offsets[end])
118125
(next_ifd > 0) && push!(file.offsets, next_ifd)
119126
strip_offset_list
@@ -131,11 +138,15 @@ function _next(file::TiffFile, offset::Int)
131138
height = 0
132139

133140
for i in 1:number_of_entries
134-
tag_bytes = Unsigned[]
135-
append!(tag_bytes, read(file.io, UInt16, 2))
136-
append!(tag_bytes, read(file.io, UInt32, 2))
137-
tag_id, tag_type, data_count, data_offset = Int.(do_bswap(file, tag_bytes))
138-
141+
combined = Unsigned[]
142+
tag_info = Array{UInt16}(undef, 2)
143+
data_info = Array{UInt32}(undef, 2)
144+
read!(file.io, tag_info)
145+
read!(file.io, data_info)
146+
append!(combined, tag_info)
147+
append!(combined, data_info)
148+
tag_id, tag_type, data_count, data_offset = Int.(do_bswap(file, combined))
149+
139150
curr_pos = position(file.io)
140151
if tag_id == 256
141152
width = data_offset
@@ -152,7 +163,9 @@ function _next(file::TiffFile, offset::Int)
152163
# if the data is spread across multiple strips
153164
if strip_num > 1
154165
seek(file.io, strip_offset)
155-
strip_offsets = do_bswap(file, read(file.io, UInt32, strip_num))
166+
strip_info = Array{UInt32}(undef, strip_num)
167+
read!(file.io, strip_info)
168+
strip_offsets = do_bswap(file, strip_info)
156169
strip_offset_list = Int.(strip_offsets)
157170
else
158171
strip_offset_list = [strip_offset]
@@ -177,7 +190,9 @@ function load_comments(file)
177190
seek(file.io, comment_offset)
178191
comment_header = read(file.io, UInt32)
179192
comment_length = Int(do_bswap(file, read(file.io, UInt32)))
180-
metadata = JSON.parse(String(read(file.io, UInt8, comment_length)))
193+
metadata_bytes = Array{UInt8}(undef, comment_length)
194+
read!(file.io, metadata_bytes)
195+
metadata = JSON.parse(String(metadata_bytes))
181196
if !haskey(metadata, "Summary")
182197
return ""
183198
end

src/loader.jl

+19-19
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ function load(f::File{format"OMETIFF"})
55
end
66

77
function load(io::Stream{format"OMETIFF"})
8-
if io.filename != nothing && !contains(io.filename, ".ome.tif")
8+
if io.filename != nothing && !occursin(".ome.tif", io.filename)
99
throw(FileIO.LoaderError("OMETIFF", "Not an OME TIFF file!"))
1010
end
1111

@@ -16,48 +16,48 @@ function load(io::Stream{format"OMETIFF"})
1616
omexml = load_master_xml(orig_file)
1717

1818
# find all images in this dataset
19-
images = find(omexml, "/ns:OME/ns:Image",["ns"=>namespace(omexml)])
20-
results = Array{AxisArray}(length(images))
19+
images = findall("/ns:OME/ns:Image", omexml, ["ns"=>namespace(omexml)])
20+
results = Array{AxisArray}(undef, length(images))
2121

22-
pos_names = nodecontent.(find(omexml, "/ns:OME/ns:Image/ns:StageLabel[@Name]/@Name",["ns"=>namespace(omexml)]))
22+
pos_names = nodecontent.(findall("/ns:OME/ns:Image/ns:StageLabel[@Name]/@Name", omexml, ["ns"=>namespace(omexml)]))
2323
# if all position names aren't unique then substitute names
2424
if length(pos_names) == 0 || !allunique(pos_names)
2525
pos_names = ["Pos$i" for i in 1:length(images)]
2626
end
2727

2828
pixels = []
29-
master_rawtype = Nullable{DataType}()
29+
master_rawtype = nothing
3030
mappedtype = Int64
3131
master_dims = []
32-
axes_dims = Nullable{Vector{AxisArrays.Axis}}()
32+
axes_dims = nothing
3333
for (idx, image) in enumerate(images)
34-
pixel = findfirst(image, "./ns:Pixels", ["ns"=>namespace(omexml)])
34+
pixel = findfirst("./ns:Pixels", image, ["ns"=>namespace(omexml)])
3535
dims, axes_info = build_axes(pixel)
3636
rawtype, mappedtype = type_mapping[pixel["Type"]]
3737

38-
if isnull(master_rawtype)
39-
master_rawtype = Nullable(rawtype)
40-
elseif get(master_rawtype) != rawtype
38+
if master_rawtype == nothing
39+
master_rawtype = rawtype
40+
elseif master_rawtype != rawtype
4141
throw(FileIO.LoaderError("OMETIFF", "Multiple different storage types not supported in a multi position image"))
4242
end
4343

44-
if isnull(axes_dims)
45-
axes_dims = Nullable(axes_info)
44+
if axes_dims == nothing
45+
axes_dims = axes_info
4646
master_dims = dims
47-
elseif get(axes_dims) != axes_info
47+
elseif axes_dims != axes_info
4848
throw(FileIO.LoaderError("OMETIFF", "Axes changing between multiple imaging positions is not supported yet"))
4949
end
5050
push!(pixels, pixel)
5151
end
52-
push!(get(axes_dims), Axis{:position}(Symbol.(pos_names)))
52+
push!(axes_dims, Axis{:position}(Symbol.(pos_names)))
5353
push!(master_dims, length(pos_names))
5454

55-
data = Array{get(master_rawtype), length(master_dims)}(master_dims...)
55+
data = Array{master_rawtype, length(master_dims)}(undef, master_dims...)
5656

5757
for (pos_idx, pixel) in enumerate(pixels)
5858
files = Dict{String, TiffFile}()
5959

60-
tiffdatas = find(pixel, "./ns:TiffData", ["ns"=>namespace(omexml)])
60+
tiffdatas = findall("./ns:TiffData", pixel, ["ns"=>namespace(omexml)])
6161

6262
# TODO: Only the IFDs with a corresponding slice should be loaded.
6363
slices = DefaultDict{String, Dict{Int, ImageSlice}}(Dict{Int, ImageSlice}())
@@ -79,7 +79,7 @@ function load(io::Stream{format"OMETIFF"})
7979
read_dims = n_strips > 1 ? (strip_len) : (width, height)
8080

8181
# TODO: This shouldn't be allocated for each ifd
82-
tmp = Array{get(master_rawtype)}(read_dims...)
82+
tmp = Array{master_rawtype}(undef, read_dims...)
8383
for j in 1:n_strips
8484
seek(file.io, strip_offsets[j])
8585
read!(file.io, tmp)
@@ -96,8 +96,8 @@ function load(io::Stream{format"OMETIFF"})
9696
# drop unnecessary axes
9797
# TODO: Reduce the number of allocations here
9898
end
99-
squeezed_data = squeeze(Gray.(reinterpret(mappedtype, data)), (find(master_dims .== 1)...))
100-
ImageMeta(AxisArray(squeezed_data, get(axes_dims)[master_dims .> 1]...), Summary=summary)
99+
squeezed_data = dropdims(Gray.(reinterpret(mappedtype, data)); dims=tuple(findall(master_dims .== 1)...))
100+
ImageMeta(AxisArray(squeezed_data, axes_dims[master_dims .> 1]...), Summary=summary)
101101
end
102102

103103
"""Corresponding Julian types for OME-XML types"""

src/parsing.jl

+3-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ function read_tiffdata(tiffdata::EzXML.Node, files::Dict{String, TiffFile}, orig
4040
c = parse(Int, tiffdata["FirstC"])+1
4141
p = parse(Int, tiffdata["PlaneCount"])
4242

43-
uuid_node = findfirst(tiffdata, "./ns:UUID", ["ns"=>namespace(tiffdata)])
43+
uuid_node = findfirst("./ns:UUID", tiffdata, ["ns"=>namespace(tiffdata)])
4444
uuid = nodecontent(uuid_node)
4545
filepath = joinpath(dirname(orig_file.filepath), uuid_node["FileName"])
4646

@@ -70,7 +70,7 @@ function build_axes(image::EzXML.Node)
7070
dims = map(x->parse(Int, image[x]), dim_names)
7171

7272
# extract channel names
73-
channel_names = nodecontent.(find(image, "ns:Channel/@Name", ["ns"=>namespace(image)]))
73+
channel_names = nodecontent.(findall("ns:Channel/@Name", image, ["ns"=>namespace(image)]))
7474
if isempty(channel_names)
7575
channel_names = ["C$x" for x in 1:dims[4]]
7676
end
@@ -83,6 +83,7 @@ function build_axes(image::EzXML.Node)
8383
unittype = getfield(Unitful, Symbol(image["TimeIncrementUnit"]))
8484

8585
time_axis = Axis{:time}(Unitful.upreferred.((0:increment:increment*(dims[5]-1))*unittype))
86+
catch
8687
end
8788

8889
axes = [

src/utils.jl

+5-4
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
Cleans up `input` string and converts it into a symbol
55
"""
66
function to_symbol(input::String)
7-
fixed = replace(input, r"[^\w\ \-\_]", "")
8-
fixed = replace(fixed, r"[\ \-\_]+", "_")
9-
Symbol(replace(fixed, r"^[\d]", s"_\g<0>"))
7+
fixed = replace(input, r"[^\w\ \-\_]"=>"")
8+
fixed = replace(fixed, r"[\ \-\_]+"=>"_")
9+
Symbol(replace(fixed, r"^[\d]"=>s"_\g<0>"))
1010
end
1111

1212

@@ -37,7 +37,8 @@ function check_bswap(io::Union{Stream, IOStream})
3737
# check if we need to swap byte order
3838
need_bswap = endianness != myendian()
3939

40-
tiff_version = read(io, UInt8, 2)
40+
tiff_version = Array{UInt8}(undef, 2)
41+
read!(io, tiff_version)
4142
(tiff_version != [0x2a, 0x00] && tiff_version != [0x00, 0x2a]) && error("Big-TIFF files aren't supported yet")
4243

4344
return need_bswap

test/runtests.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using OMETIFF
22
using FileIO
33
using AxisArrays
4-
using Base.Test
4+
using Test
55

66
@testset "Single file OME-TIFFs" begin
77
@testset "Single Channel OME-TIFF" begin

0 commit comments

Comments
 (0)