diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..700707c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index a0ded2a..2a6e43a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -20,7 +20,7 @@ jobs: arch: - x64 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: julia-actions/setup-julia@latest with: version: ${{ matrix.version }} diff --git a/Project.toml b/Project.toml index 2540e2d..0aac4ec 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "MAT" uuid = "23992714-dd62-5051-b70f-ba57cb901cac" -version = "0.10.3" +version = "0.10.4" [deps] BufferedStreams = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d" diff --git a/src/MAT.jl b/src/MAT.jl index b84f1ef..ab888e6 100644 --- a/src/MAT.jl +++ b/src/MAT.jl @@ -166,7 +166,6 @@ end ### v0.10.0 deprecations ### -import HDF5: exists export exists @noinline function exists(matfile::Union{MAT_v5.Matlabv5File,MAT_HDF5.MatlabHDF5File}, varname::String) Base.depwarn("`exists(matfile, varname)` is deprecated, use `haskey(matfile, varname)` instead.", :exists) diff --git a/src/MAT_v4_Modelica.jl b/src/MAT_v4_Modelica.jl index 55eac3b..ca611c9 100644 --- a/src/MAT_v4_Modelica.jl +++ b/src/MAT_v4_Modelica.jl @@ -134,7 +134,7 @@ function readAclass( filepath::String ) end nameuint = read!(matio, Vector{UInt8}(undef, namelen)) # read the full namelen to make the pointer ready to read the data - name = replace(String(nameuint), '\0'=>"") + name = strip(replace(String(nameuint), '\0'=>"")) if name != "Aclass" error("First matrix must be named Aclass, is instead [$name]. This likely means that [$filepath] is not a Modelica MAT v4 file.") end @@ -143,10 +143,10 @@ function readAclass( filepath::String ) fmt = dataFormat(dtype) # read the format type before reading realint = read!(matio, Matrix{UInt8}(undef, nrows,ncols)) - Aclass1 = replace(String(realint[1,:]), '\0'=>"") - Aclass2 = replace(String(realint[2,:]), '\0'=>"") - Aclass3 = replace(String(realint[3,:]), '\0'=>"") - Aclass4 = replace(String(realint[4,:]), '\0'=>"") + Aclass1 = strip(replace(String(realint[1,:]), '\0'=>"")) + Aclass2 = strip(replace(String(realint[2,:]), '\0'=>"")) + Aclass3 = strip(replace(String(realint[3,:]), '\0'=>"")) + Aclass4 = strip(replace(String(realint[4,:]), '\0'=>"")) if Aclass1 == "Atrajectory" && Aclass2 == "1.1" && isempty(Aclass3) && Aclass4 == "binNormal" || Aclass4 == "binTrans" return Aclass( filepath, Aclass4 == "binTranspose", startP, position(matio) ) end @@ -180,7 +180,7 @@ function readVariableNames(ac::Aclass) #read the matrix name nameuint = read!(matio, Vector{UInt8}(undef, namelen)) # read the full namelen to make the pointer ready to read the data - matrixName = replace(String(nameuint), '\0'=>"") + matrixName = strip(replace(String(nameuint), '\0'=>"")) if matrixName != "name" error("trying to read matrix [name] but read [$matrixName]") end @@ -197,7 +197,7 @@ function readVariableNames(ac::Aclass) #pull the names out of the matrix vnames = [] for i in 1:ncols - push!(vnames, replace(String(realint[:,i]), '\0'=>"")) # note :,1 = implicit transpose + push!(vnames, strip(replace(String(realint[:,i]), '\0'=>""))) # note :,1 = implicit transpose end return VariableNames(vnames, startP, position(matio)) @@ -247,7 +247,7 @@ function readVariableDescriptions(ac::Aclass, vn::VariableNames) #read the matrix name nameuint = read!(matio, Vector{UInt8}(undef, namelen)) # read the full namelen to make the pointer ready to read the data - matrixName = replace(String(nameuint), '\0'=>"") + matrixName = strip(replace(String(nameuint), '\0'=>"")) if matrixName != "description" error("trying to read matrix [description] but read [$matrixName]") end @@ -263,7 +263,7 @@ function readVariableDescriptions(ac::Aclass, vn::VariableNames) vdesc = [] for i in 1:ncols - push!(vdesc, replace(String(realread[:,i]), '\0'=>"")) # note :,1 = implicit transpose + push!(vdesc, strip(replace(String(realread[:,i]), '\0'=>""))) # note :,1 = implicit transpose end return VariableDescriptions(vn.names, vdesc, startP, position(matio)) @@ -306,7 +306,7 @@ function readDataInfo(ac::Aclass, vd::VariableDescriptions) #read the matrix name nameuint = read!(matio, Vector{UInt8}(undef, namelen)) # read the full namelen to make the pointer ready to read the data - matrixName = replace(String(nameuint), '\0'=>"") + matrixName = strip(replace(String(nameuint), '\0'=>"")) if matrixName != "dataInfo" error("trying to read variable [dataInfo] but read [$matrixName]") end @@ -355,7 +355,7 @@ function readMatrixHeader!(matio::IOStream) :: MatrixHeader # data1MatrixName = mark(matio) nameuint = read!(matio, Vector{UInt8}(undef, namelen)) # read the full namelen to make the pointer ready to read the data - matrixName = replace(String(nameuint), '\0'=>"") + matrixName = strip(replace(String(nameuint), '\0'=>"")) fmt = dataFormat(dtype) # read the format type before reading @@ -406,7 +406,7 @@ function readVariable(ac::Aclass, vn::VariableNames, vd::VariableDescriptions, d return readns end - elseif name == "time" || di.info[varInd]["locatedInData"] == 2 #data_2 + elseif name == "Time" || name == "time" || di.info[varInd]["locatedInData"] == 2 #data_2 #read the matrix data_2 if ac.isTranspose == false # data is sequential: time(t0), var1(t0), var2(t0),... varN(t0), time(t1), var1(t1),... diff --git a/test/runtests_modelica.jl b/test/runtests_modelica.jl index 2e29e4e..ce7e9a8 100644 --- a/test/runtests_modelica.jl +++ b/test/runtests_modelica.jl @@ -15,8 +15,8 @@ include("../src/MAT.jl") #OpenModelica v1.19.0 matBBO = joinpath(@__DIR__, "v4_Modelica","BouncingBall","BouncingBall_res.mat") matFBB = joinpath(@__DIR__, "v4_Modelica","FallingBodyBox","FallingBodyBox_res.mat") -#Dymola v2021 -- not implemented -# matBBD = joinpath(@__DIR__, "v4_Modelica","BouncingBall","BouncingBall_dymola2021.mat") +#Dymola v2021 +matBBD = joinpath(@__DIR__, "v4_Modelica","BouncingBall","BouncingBall_dymola2021.mat") @testset "isLittleEndian" begin @@ -85,7 +85,7 @@ end @test di.info[11]["isWithinTimeRange"] == 0 end -@testset "readVariable: BouncingBall" begin +@testset "readVariable: BouncingBall OpenModelica" begin ac = MAT.MAT_v4_Modelica.readAclass(matBBO) vn = MAT.MAT_v4_Modelica.readVariableNames(ac) vd = MAT.MAT_v4_Modelica.readVariableDescriptions(ac,vn) @@ -112,6 +112,33 @@ end @test isapprox(vel[2], -0.981, rtol=1e-3) end +@testset "readVariable: BouncingBall Dymola" begin + ac = MAT.MAT_v4_Modelica.readAclass(matBBD) + vn = MAT.MAT_v4_Modelica.readVariableNames(ac) + vd = MAT.MAT_v4_Modelica.readVariableDescriptions(ac,vn) + di = MAT.MAT_v4_Modelica.readDataInfo(ac,vd) + + eff = MAT.MAT_v4_Modelica.readVariable(ac, vn, vd, di, "eff") #data1 + @test length(eff) == 2 + @test eff[1] ≈ 0.77 + @test eff[2] ≈ 0.77 + + grav = MAT.MAT_v4_Modelica.readVariable(ac, vn, vd, di, "grav") #data1 + @test length(grav) == 2 + @test grav[1] ≈ 9.81 + @test grav[2] ≈ 9.81 + + Time = MAT.MAT_v4_Modelica.readVariable(ac, vn, vd, di, "Time") # data0 + @test all(isapprox.(Time, [0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1,1], rtol=1e-3)) + + height = MAT.MAT_v4_Modelica.readVariable(ac, vn, vd, di, "height") #data2 + @test isapprox(height[1], 111, rtol=1e-3) + @test isapprox(height[2], 110.9509, rtol=1e-3) + + vel = MAT.MAT_v4_Modelica.readVariable(ac, vn, vd, di, "vel") #data2 + @test isapprox(vel[2], -0.981, rtol=1e-3) +end + @testset "readVariable: FallingBodyBox" begin ac = MAT.MAT_v4_Modelica.readAclass(matFBB) vn = MAT.MAT_v4_Modelica.readVariableNames(ac)