Skip to content

Commit

Permalink
Added code to verify that minc data type is consistent with requested…
Browse files Browse the repository at this point in the history
… data type
  • Loading branch information
vfonov committed Sep 11, 2024
1 parent a0861bd commit 6334006
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 22 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Minc2"
uuid = "8e6f2f06-34e2-40fe-8437-e396464d2a7f"
authors = ["Vladimir S. FONOV <[email protected]>"]
version = "0.1.4"
version = "0.1.5"

[deps]
CBinding = "d43a6710-96b8-4a2d-833c-c424785e5374"
Expand Down
76 changes: 55 additions & 21 deletions src/minc2_io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ function store_header(h::VolumeHandle)::MincHeader
end





"""
empty_like_minc_volume_raw( h::VolumeHandle,
::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader}
Expand All @@ -306,30 +309,58 @@ Allocate empty volume using handle
return volume, storage header
"""
function empty_like_minc_volume_raw( h::VolumeHandle,
::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader} where {T}
::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader} where {T<:Number}
# TODO: use ImageMetadata to store header contents?
store_hdr = store_header( h )
volume = Array{T}(undef, store_hdr.dims...)

@minc2_check minc2_simple.minc2_load_complete_volume(h.x[], Base.unsafe_convert(Ptr{Cvoid},volume), julia_to_minc2[Type{T}] )
return volume, store_hdr
end


"""
Internal function that makes sure types are compatible
"""
function minc2_load_and_convert_complete_volume(
h::VolumeHandle, volume::Array{Tin}, dtype::Type{Tout}) where {Tin<:Number,Tout<:Number}

@minc2_check minc2_simple.minc2_load_complete_volume(h.x[],
Base.unsafe_convert(Ptr{Cvoid},volume), julia_to_minc2[Type{Tin}] )

return convert.(Tout,volume)
end


"""
Internal function that makes sure types are compatible
"""
function minc2_load_and_convert_complete_volume(
h::VolumeHandle, volume::Array{Tin}, dtype::Type{Tout}) where {Tin<:Real,Tout<:Integer}

@warn "Truncating volume data to integer type " Tin Tout

@minc2_check minc2_simple.minc2_load_complete_volume(h.x[],
Base.unsafe_convert(Ptr{Cvoid},volume), julia_to_minc2[Type{Tin}] )

return trunc.(Tout,volume)
end



"""
read_minc_volume_raw(h::VolumeHandle,
::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader}
Read the actual volume using handle
return volume, storage header
"""
function read_minc_volume_raw(h::VolumeHandle,
::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader} where {T}
function read_minc_volume_raw(h::VolumeHandle,
dtype::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader} where {T<:Number}

volume,store_hdr = empty_like_minc_volume_raw(h,T)
@minc2_check minc2_simple.minc2_load_complete_volume(h.x[], Base.unsafe_convert(Ptr{Cvoid},volume), julia_to_minc2[Type{T}] )
fdtype=representation_type(h)
volume, store_hdr = empty_like_minc_volume_raw(h, fdtype.parameters[1])

return volume, store_hdr
return minc2_load_and_convert_complete_volume(h, volume, dtype), store_hdr
end


Expand All @@ -341,7 +372,7 @@ Read the actual volume using handle
return volume, representation header,storage header
"""
function empty_like_minc_volume_std(h::VolumeHandle,
::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader, Minc2.MincHeader} where {T}
::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader, Minc2.MincHeader} where {T<:Number}
# TODO: use ImageMetadata to store header contents?
setup_standard_order( h )
store_hdr = store_header( h )
Expand All @@ -360,12 +391,15 @@ Read the actual volume using handle
return volume, representation header,storage header
"""
function read_minc_volume_std(h::VolumeHandle,
::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader, Minc2.MincHeader} where {T}
dtype::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader, Minc2.MincHeader} where {T<:Number}
# TODO: use ImageMetadata to store header contents?
volume, hdr, store_hdr = empty_like_minc_volume_std(h,T)

@minc2_check minc2_simple.minc2_load_complete_volume(h.x[], Base.unsafe_convert(Ptr{Cvoid},volume), julia_to_minc2[Type{T}] )
return volume, hdr, store_hdr
fdtype=representation_type(h)

volume, hdr, store_hdr = empty_like_minc_volume_std(h,fdtype.parameters[1])

return minc2_load_and_convert_complete_volume(h, volume, dtype), hdr,store_hdr

end


Expand All @@ -377,7 +411,7 @@ allocate empty volume using path as a reference
return volume, representation header,storage header
"""
function empty_like_minc_volume_std(path::String,
::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader, Minc2.MincHeader} where {T}
::Type{T}=Float32 )::Tuple{Array{T}, Minc2.MincHeader, Minc2.MincHeader} where {T<:Number}
handle = open_minc_file(path)
volume, hdr, store_hdr = empty_like_minc_volume_std(handle,T)
close_minc_file(handle)
Expand All @@ -391,7 +425,7 @@ end
allocate empty volume using path
return volume, representation header,storage header
"""
function empty_like_minc_volume_std_history(path::String, ::Type{T}=Float32 ) where {T}
function empty_like_minc_volume_std_history(path::String, ::Type{T}=Float32 ) where {T<:Number}
handle = open_minc_file(path)
volume, hdr, store_hdr = empty_like_minc_volume_std(handle,T)
history = read_history(handle)
Expand All @@ -409,7 +443,7 @@ Read the actual volume using path
return volume, representation header,storage header
"""
function read_minc_volume_std(path::String, ::Type{T}=Float32 )::
Tuple{Array{T}, Minc2.MincHeader, Minc2.MincHeader} where {T}
Tuple{Array{T}, Minc2.MincHeader, Minc2.MincHeader} where {T<:Number}
handle = open_minc_file(path)
volume, hdr, store_hdr = read_minc_volume_std(handle,T)
close_minc_file(handle)
Expand All @@ -426,7 +460,7 @@ Read the actual volume using path
return volume, representation header,storage header
"""
function read_minc_volume_std_history(path::String, ::Type{T}=Float32 )::
Tuple{Array{T}, Minc2.MincHeader, Minc2.MincHeader, Union{String,Nothing}} where {T}
Tuple{Array{T}, Minc2.MincHeader, Minc2.MincHeader, Union{String,Nothing}} where {T<:Number}
handle = open_minc_file(path)
volume, hdr, store_hdr = read_minc_volume_std(handle,T)
history = read_history(handle)
Expand All @@ -445,7 +479,7 @@ Create empty volume similar to existing file
return volume, representation header,storage header
"""
function empty_like_minc_volume_raw(path::String, ::Type{T}=Float32 )::
Tuple{Array{T}, Minc2.MincHeader} where {T}
Tuple{Array{T}, Minc2.MincHeader} where {T<:Number}
handle = open_minc_file(path)
volume, store_hdr = empty_like_minc_volume_raw(handle,T)
close_minc_file(handle)
Expand All @@ -462,7 +496,7 @@ Read the actual volume using path
return volume, representation header,storage header
"""
function read_minc_volume_raw(path::String, ::Type{T}=Float32 )::
Tuple{Array{T}, Minc2.MincHeader} where {T}
Tuple{Array{T}, Minc2.MincHeader} where {T<:Number}
handle = open_minc_file(path)
volume, store_hdr = read_minc_volume_raw(handle,T)
close_minc_file(handle)
Expand All @@ -476,7 +510,7 @@ end
Read the actual volume using path
return volume, representation header,storage header
"""
function read_minc_volume_raw_history(path::String, ::Type{T}=Float32 ) where {T}
function read_minc_volume_raw_history(path::String, ::Type{T}=Float32 ) where {T<:Number}
handle = open_minc_file(path)
volume, store_hdr = read_minc_volume_raw(handle,T)
history = read_history(h)
Expand All @@ -493,7 +527,7 @@ end
write full volume to file, file should be defined and created
return nothing
"""
function write_minc_volume_raw(h::VolumeHandle, volume::Array{T} ) where {T}
function write_minc_volume_raw(h::VolumeHandle, volume::Array{T} ) where {T<:Number}
@minc2_check minc2_simple.minc2_save_complete_volume(h.x[], Base.unsafe_convert(Ptr{Cvoid},volume),julia_to_minc2[Type{T}])
return nothing
end
Expand All @@ -505,7 +539,7 @@ end
write full volume to file, file should be defined and created
return nothing
"""
function write_minc_volume_std(h::VolumeHandle, volume::Array{T} ) where {T}
function write_minc_volume_std(h::VolumeHandle, volume::Array{T} ) where {T<:Number}
setup_standard_order( h )
write_minc_volume_raw(h, volume)
return nothing
Expand Down
5 changes: 5 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ end
end
end

@testset "Testing reading wrong voxel type" begin
vol,hdr,store_hdr = Minc2.read_minc_volume_std("input/t1_z-_long_sag.mnc",Int16)
@test eltype(vol) == Int16
end

@testset "Reading 4D volume, raw" begin
vol,hdr = Minc2.read_minc_volume_raw("input/dti_sample.mnc",Float64)

Expand Down

2 comments on commit 6334006

@vfonov
Copy link
Owner Author

@vfonov vfonov commented on 6334006 Sep 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/115015

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.1.5 -m "<description of version>" 633400681f900abca715063cbd44a1c3e373a194
git push origin v0.1.5

Please sign in to comment.