From f7bac85876c8517ccff42f5890df83f66b4f1c98 Mon Sep 17 00:00:00 2001 From: AntonOresten Date: Mon, 18 Nov 2024 19:56:47 +0100 Subject: [PATCH] Support writing dict-like properties with string keys + bugfix --- Project.toml | 2 +- src/chain.jl | 2 +- src/properties.jl | 1 + src/store/io.jl | 9 +++++++++ src/structure.jl | 2 +- test/runtests.jl | 7 ++++--- 6 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Project.toml b/Project.toml index dd94e90..dfa74fa 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "ProteinChains" uuid = "b8e8f2a5-48d3-44f1-ba0d-c71cb7726ff8" authors = ["Anton Oresten and contributors"] -version = "0.5.0" +version = "0.5.1" [deps] Backboner = "9ac9c2a2-1cfe-46d3-b3fd-6fa470ea56a7" diff --git a/src/chain.jl b/src/chain.jl index 1001dbb..546472c 100644 --- a/src/chain.jl +++ b/src/chain.jl @@ -69,7 +69,7 @@ Base.getproperty(chain::ProteinChain, name::Symbol) = Base.propertynames(chain::ProteinChain, private::Bool=false) = (setdiff(fieldnames(ProteinChain), private ? () : (:properties,))..., propertynames(chain.properties)...) function setproperties!(chain::ProteinChain, ps::NamedTuple) - chain.properties = setproperties(chain.properties, ps) + chain.properties = setproperties(chain.properties, sortnames(ps)) chain end diff --git a/src/properties.jl b/src/properties.jl index f56afaa..d897c6a 100644 --- a/src/properties.jl +++ b/src/properties.jl @@ -24,6 +24,7 @@ function setproperties! end function addproperties! end function removeproperties! end +# probably shouldnt deepcopy setproperties(x, args...) = setproperties!(deepcopy(x), args...) addproperties(x, args...; kwargs...) = addproperties!(deepcopy(x), args...; kwargs...) removeproperties(x, args...) = removeproperties!(deepcopy(x), args...) diff --git a/src/store/io.jl b/src/store/io.jl index 9d125c9..ca93c19 100644 --- a/src/store/io.jl +++ b/src/store/io.jl @@ -39,6 +39,15 @@ function deleteproperty(group::HDF5.Group, ::Type, ::Val{:properties}, names::Sy return group end +function writeproperty(group::HDF5.Group, T::Type, ::Val{name}, dict::AbstractDict{<:AbstractString}) where name + haskey(group, string(name)) && HDF5.delete_object(group[string(name)]) + dict_group = HDF5.create_group(group, string(name)) + for (key, value) in pairs(dict) + writeproperty(dict_group, T, Val(Symbol(key)), value) + end + return dict_group +end + ## chain properties function writeproperty(group::HDF5.Group, ::Type{ProteinChain{T}}, ::Val{:atoms}, atoms::Vector{Vector{Atom{T}}}) where T diff --git a/src/structure.jl b/src/structure.jl index 4ef171b..d37e6db 100644 --- a/src/structure.jl +++ b/src/structure.jl @@ -80,7 +80,7 @@ Base.getproperty(structure::ProteinStructure, name::Symbol) = Base.propertynames(structure::ProteinStructure, private::Bool=false) = (setdiff(fieldnames(ProteinStructure), private ? () : (:properties,))..., propertynames(structure.properties)...) function setproperties!(structure::ProteinStructure, properties::NamedTuple) - structure.properties = setproperties(structure.properties, properties) + structure.properties = setproperties(structure.properties, sortnames(properties)) structure end diff --git a/test/runtests.jl b/test/runtests.jl index e92a734..88b5ca6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -91,10 +91,10 @@ using Test filename = joinpath(dir, "store.h5") structures = [pdb"1EYE", pdb"3HFM"] for (i, chain) in enumerate(structures[1]) - structures[1][i] = addproperties(chain, rand3=rand(3)) + addproperties!(chain, rand3=rand(3)) end for (i, chain) in enumerate(structures[2]) - structures[2][i] = addproperties(chain, rand3=rand(3), taxid=-1) + addproperties!(chain, rand3=rand(3), taxid=-1, dict=Dict("a"=>1, "b"=>2)) end ProteinChains.serialize(filename, structures) structures_copy = ProteinChains.deserialize(filename) @@ -103,7 +103,8 @@ using Test store = ProteinStructureStore(filename) @test haskey(store, "1EYE.cif") @test issubset((:rand3,), propertynames(store["1EYE.cif"][1])) - @test all(chain -> issubset((:rand3, :taxid), propertynames(chain)), store["3HFM.cif"]) + @test all(chain -> issubset((:rand3, :taxid, :dict), propertynames(chain)), store["3HFM.cif"]) + @test store["3HFM.cif"][1].dict == Dict("a"=>1, "b"=>2) delete!(store, "1EYE.cif") @test !haskey(store, "1EYE.cif")