JuliaIO / MAT.jl

Julia module for reading MATLAB files
MIT License
278 stars 71 forks source link

Cannot read MAT v5 files with a struct in them #80

Open jondoesntgit opened 6 years ago

jondoesntgit commented 6 years ago

Hello,

The previous grad student had a bunch of .mat files (v5) that were saved with a custom matlab struct. I can open them up using Matlab on a colleagues computer, but I'm wondering if I can also do so with Julia.

When I load a simple v5 .mat file, I'm able to read variables without a problem. But when I load the .mat files with struct, and run this code:

file = matopen("mat_with_struct.mat", "r")
names(file)

I get this error: ERROR: zlib error: incorrect header check (Z_DATA_ERROR)

The bottom of the stack trace is

[11] names(::MAT.MAT_v5.Matlabv5File) at /Users/jamwheel/.julia/v0.6/MAT/src/MAT_v5.jl:386

If I run matread("mat_with_struct.mat", "r") I get ERROR: EOFError: read end of file

maximilianpreisinger commented 6 years ago

I have a similar issue. I have a matlab file with 7 variables: 1x1 struct 1x1 SimulationOutput (which seems to behave like a struct) 22x4 cell (Matlab's kind of special cell matrix) one array and two ints.

When I do a data = matread(filename) I get this error:

ERROR: EOFError: read end of file
Stacktrace:
 [1] unsafe_read(::BufferedStreams.BufferedInputStream{Libz.Source{:inflate,BufferedStreams.BufferedInputStream{BufferedStreams.EmptyStream}}}, ::Ptr{UInt8}, ::UInt64) at /home/maximilian/.julia/v0.6/BufferedStreams/src/bufferedinputstream.jl:221
 [2] read!(::BufferedStreams.BufferedInputStream{Libz.Source{:inflate,BufferedStreams.BufferedInputStream{BufferedStreams.EmptyStream}}}, ::Array{UInt8,1}) at ./io.jl:387
 [3] read_bswap(::BufferedStreams.BufferedInputStream{Libz.Source{:inflate,BufferedStreams.BufferedInputStream{BufferedStreams.EmptyStream}}}, ::Bool, ::Type{UInt8}, ::Int64) at /home/maximilian/.julia/v0.6/MAT/src/MAT_v5.jl:90
 [4] read_element(::BufferedStreams.BufferedInputStream{Libz.Source{:inflate,BufferedStreams.BufferedInputStream{BufferedStreams.EmptyStream}}}, ::Bool, ::Type{UInt8}) at /home/maximilian/.julia/v0.6/MAT/src/MAT_v5.jl:119
 [5] read_matrix(::BufferedStreams.BufferedInputStream{Libz.Source{:inflate,BufferedStreams.BufferedInputStream{BufferedStreams.EmptyStream}}}, ::Bool) at /home/maximilian/.julia/v0.6/MAT/src/MAT_v5.jl:318
 [6] read_matrix(::IOStream, ::Bool) at /home/maximilian/.julia/v0.6/MAT/src/MAT_v5.jl:302
 [7] read(::MAT.MAT_v5.Matlabv5File) at /home/maximilian/.julia/v0.6/MAT/src/MAT_v5.jl:352
 [8] matread(::String) at /home/maximilian/.julia/v0.6/MAT/src/MAT.jl:132
 [9] macro expansion at /home/maximilian/.julia/v0.6/Atom/src/repl.jl:118 [inlined]
 [10] anonymous at ./<missing>:?

When I try the second variant with first open then read, I got a strange behaviour:

f=matopen(filename) > MAT.MAT_v5.Matlabv5File
names(f) > ERROR (see below)
names(f) > Base.KeyIterator for a Dict{String,Int64} with 2 entries. Keys: "var 1 (a struct)" "var 2 (the array)"
data=read(f,"var 1") > Dict String -> Any with x entries

So the first time I call names(f) I get this error:

zlib error: incorrect header check (Z_DATA_ERROR)
zerror(::Libz.ZStream, ::Int32) at lowlevel.jl:221
process(::Libz.Source{:inflate,BufferedStreams.BufferedInputStream{IOStream}}, ::Int32) at source.jl:182
[...]
withpath(::Function, ::String) at eval.jl:38
hideprompt(::Atom.##101#106{String,Int64,String}) at repl.jl:67
macro expansion at eval.jl:80 [inlined]
(::Atom.##100#105{Dict{String,Any}})() at task.jl:80

However when I evaluate the very same command once more, it is successfull. But it only contains 2 out of 7 variables. All other variables are not loaded.

It also seems like this package is no longer maintained, since the last activity was on Sep 15, 2017. Which is a pity, because I would prefer to work and analyze my results with julia than with matlab. Maybe somebody feels like keeping this packed up to date?

By the way: I have been using MAT Version 0.4.0

Leon6j commented 2 years ago

Same problem here. I have some Matlab table variables that are stored in MAT files. They can not be opened using MAT.jl as far as I know.

StefanPofahl commented 2 years ago

Here my update (Julia v1.7.2, MAT v0.10.3, HDF5 v0.16.3): My mat-file contains a Matlab-table and the command names(hd_mat_file) works in line-by-line-execution mode and if I call afterwards keys(hd_mat_file) no error message is thrown. But unfortunatly the resulting Base.KeySet has the length of zero. As I do not know where this problem is originated, I have reported this also in the project HDF5.jl: matlab table causes trouble: zlib error: incorrect header check (code: -3)

Here my code snippet: using MAT hd_mat_file = matopen("filename.mat") variable_keys = keys(hd_mat_file) variable_names = names(hd_mat_file)

Table_PolCurve.zip

mkitti commented 2 years ago

This currently works for me given the last sample and MAT v0.10.3.

julia> mat = matread("Table_PolCurve.mat")
Dict{String, Any} with 2 entries:
  "__opaque__" => Dict{String, Any}("s1"=>Int8[77, 67, 79, 83], "arr"=>("", UInt32[0xdd000000; 0x00000002; … ; 0x00000001; 0…
  ""           => UInt8[0x00 0x01 … 0x00 0x00]
lmulder1991 commented 10 months ago

I've got the same issue. I have a table stored inside the struct. It also gets converted to a Dict{String,Any}("s1"=>Int8[77,67,79,83],.....

mkitti commented 10 months ago

@lmulder1991 Could you start a new issue and supply a sample file?

lmulder1991 commented 10 months ago

@lmulder1991 Could you start a new issue and supply a sample file? Done: Hope description is clear enough: https://github.com/JuliaIO/MAT.jl/issues/194