Closed RainerHeintzmann closed 3 years ago
This is what the order
parameter of bf_import
(and bf_import_url
) specifies. I don't know what a more "natural" order would be but it seems like this could depend on the format/person/field. I believe the default that I chose ("TZYXC") was the same as the order used by default in the python nd2reader
library.
To get the 620x620x18x3
format you can use:
julia> data = BioformatsLoader.bf_import_url("https://samples.fiji.sc/150707_WTstack.lsm"; order="YXZC"); size(data[1])
(620, 620, 18, 3)
docstring for bf_import
:
help?> bf_import
search: bf_import
bf_import(filename::AbstractString; order::AbstractString="TZYXC", squeeze::Bool=false)
Import all images and metadata in the file using Bio-Formats.
The order keyword argument is the output order of dimensions, allowing you to
reshuffle the dimensions of the images or skip singleton dimensions. Providing
"CYX" for order gives you three-dimensional images in a "channels-first" data
format but will fail with an error if any of the images in the file has a size
greater than one in the T or Z dimension.
By setting the squeeze keyword argument to true all singleton dimensions in the
images will be dropped (even if they are in the order argument).
Thanks a lot for the hint with the "order" argument, which I did not know about.
My choice would have been "XYZCT" as this is the standard order, I would think. Is this not also the way that ImageJ would load the data by default? At least this is the way that View5D.jl
expects it normally. Do the axes have names or is there a way to find out in which order the data is present in the resulting data structure?
Do the axes have names or is there a way to find out in which order the data is present in the resulting data structure?
Unfortunately not currently, but I'm considering depending on AxisArrays.jl and using it to name the axes, I agree that it would be convenient.
My choice would have been "XYZCT" as this is the standard order, I would think.
I'll look around a bit more at what other libraries are doing. However, "XY" doesn't really make sense for most purposes in Julia since that would mean that the "row" direction is the X-axis. The JuliaImages ecosystem renders an image the same way the corresponding matrix would be rendered, see the example below.
The good old neverending XY problem with images :-). My take on this is that the X-axis has to point to the right direction and axes are ordered XYZ. If some display packages handle this differently than this is the problem of the display package. I would not require that the image display has to agree with the way that Julia prints matrices.
But yes, if you encapsulate your loaded image into an ImageMeta
this probably has to be of this order to agree with the default display of such a type. Given this I revise my statement to suggest YXZCT
as the default order for ImageMeta
.
The quickest solution to retrospectively figure out how the data was loaded would be to save an entry ImportOrder
with the string that was used into the properties
dict. With this I should be able to choose the corresponding directions in View5D
and I might also allow the user to select a preferred axis assignment. I wouldn't necessarily think that you need to support axes. They anyway vanish far to quickly when processing these images.
I have now added the ImportOrder
entry tor the metadata in addition to using AxisArrays.jl (since ImageMetadata anyways depends on AxisArrays). ImportOrder
contains a Tuple
of Symbol
s:
img = bf_import(path; order="XYZCT")
img.ImportOrder
(:X, :Y, :Z, :C, :T)
I have also changed the default to CYXZT
. While I don't disagree with your points, this seems to be the order that currently is most compatible with the rest of the JuliaImages ecosystem. Functions like ImageCore.colorview assume an interleaved/channel-first structure.
Thanks! I tried updating to the 0.3.0 version but get an error attempting to load data. See below. Also loading an example file resulted in the same error:
julia> data = BioformatsLoader.bf_import("https://samples.fiji.sc/150707_WTstack.lsm")
ERROR: KeyError: key "C" not found
Stacktrace:
[1] getindex
@ .\dict.jl:482 [inlined]
[2] bf_import(uri::String; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ BioformatsLoader ~\.julia\packages\BioformatsLoader\vtWPq\src\BioformatsLoader.jl:122
[3] bf_import
@ ~\.julia\packages\BioformatsLoader\vtWPq\src\BioformatsLoader.jl:121 [inlined]
[4] (::BioformatsLoader.var"#62#63"{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, URIs.URI, String})(path::String)
@ BioformatsLoader ~\.julia\packages\BioformatsLoader\vtWPq\src\BioformatsLoader.jl:169
[5] mktempdir(fn::BioformatsLoader.var"#62#63"{Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, URIs.URI, String}, parent::String; prefix::String)
@ Base.Filesystem .\file.jl:729
[6] mktempdir (repeats 2 times)
@ .\file.jl:727 [inlined]
[7] #bf_import_http#61
@ ~\.julia\packages\BioformatsLoader\vtWPq\src\BioformatsLoader.jl:166 [inlined]
[8] bf_import_http
@ ~\.julia\packages\BioformatsLoader\vtWPq\src\BioformatsLoader.jl:166 [inlined]
[9] #bf_import_http#60
@ ~\.julia\packages\BioformatsLoader\vtWPq\src\BioformatsLoader.jl:162 [inlined]
[10] bf_import_http(url::URIs.URI)
@ BioformatsLoader ~\.julia\packages\BioformatsLoader\vtWPq\src\BioformatsLoader.jl:160
[11] bf_import(uri::String; kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ BioformatsLoader ~\.julia\packages\BioformatsLoader\vtWPq\src\BioformatsLoader.jl:122
[12] bf_import(uri::String)
@ BioformatsLoader ~\.julia\packages\BioformatsLoader\vtWPq\src\BioformatsLoader.jl:121
[13] top-level scope
@ REPL[5]:1
I see, I didn't consider the Windows path format. The drive letter C:
is interpreted as a URI scheme. I'll have to handle that (even if you're loading from a URL the issue manifests for the temporary file path).
I see. Sounds like a good explanation :-)
The latest commit on master should fix the Windows issue and also be a bit more robust against strange paths. The CI tests are passing on Windows but unfortunately, I don't have a Windows machine handy so I can't do any manual verification. If you can confirm that it seems to work for both URLs and local files, @RainerHeintzmann, I'll release a new patch version :-)
Sure, I am happy to test it, yet I am for the moment stuck with the aforementioned problem of the missing XML file. With the usual installation route it somehow downloads it after a couple of tries, but activating the package does not seem to make it download the XML file.
julia> using BioformatsLoader
[ Info: Precompiling BioformatsLoader [d1f74bce-bb60-11ea-2eff-3d75f256b4d8]
I/O warning : failed to load external entity "file:/C:/Users/pi96doc/Documents/Programming/Julia/BioformatsLoader.jl/src/../deps/ome.xsd"
ERROR: LoadError: LoadError: LightXML.XMLParseError{String}("Failure in parsing an XML file.")
I also tried installing via ] add https://github.com/ahnlabb/BioformatsLoader.jl.git
with a similar result.
Not sure how to proceed.
I copied the xml file from a previous installation, but this seems to also cause problems:
julia> BioformatsLoader.init(); # Initializes JavaCall with opt and classpath
ERROR: JavaCall.JavaCallError("Class Not Found loci/common/DebugTools")
Stacktrace:
[1] _metaclass(class::Symbol)
@ JavaCall ~\.julia\packages\JavaCall\tjlYt\src\core.jl:383
[2] metaclass(class::Symbol)
@ JavaCall ~\.julia\packages\JavaCall\tjlYt\src\core.jl:389
[3] jcall(typ::Type{JavaObject{Symbol("loci.common.DebugTools")}}, method::String, rettype::Type, argtypes::Tuple{DataType}, args::String)
@ JavaCall ~\.julia\packages\JavaCall\tjlYt\src\core.jl:225
[4] enableLogging(level::String)
@ BioformatsLoader ~\.julia\packages\BioformatsLoader\mdbKZ\src\BioformatsLoader.jl:230
[5] init(; memory::Int64, log_level::String)
@ BioformatsLoader ~\.julia\packages\BioformatsLoader\mdbKZ\src\BioformatsLoader.jl:238
[6] init()
@ BioformatsLoader ~\.julia\packages\BioformatsLoader\mdbKZ\src\BioformatsLoader.jl:236
[7] top-level scope
@ REPL[10]:1
I copied the xml file from a previous installation, but this seems to also cause problems:
This looks like the JAR file is missing. I really need to handle these dependencies better but for now could you try:
]build BioformatsLoader
or copying the bioformats_package.jar
from the previous installation?
Brilliant. Works great! Please make a release. I adapted View5D.jl
to read the :ImportOrder
and permute accordingly if necessary.
When importing multidimensional files, the order of the dimensions does not agree to what is expected:
It should be 620x620x18x3. I fixed this in
View5D.jl
bypermutedims(img[1].data, (3,4,2,5,1))
but this is a problem that many will encouter, if they just want to use the data.