Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More tests #29

Merged
merged 11 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://m3g.github.io/PDBTools.jl/stable)
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://m3g.github.io/PDBTools.jl/dev)
[![Tests](https://img.shields.io/badge/build-passing-green)](https://github.com/m3g/PDBTools.jl/actions)
[![codecov](https://codecov.io/gh/m3g/PDBTools.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/m3g/PDBTools.jl)
[![Aqua QA](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)

# PDBTools
Expand Down
32 changes: 28 additions & 4 deletions src/Atom.jl
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,17 @@ atom_line(atom::Atom) = @sprintf(
atoms = read_pdb(PDBTools.SMALLPDB, "protein and index 1")
@test PDBTools.atom_line(atoms[1]) ==
" 1 N ALA A 1 1 -9.229 -14.861 -5.481 0.00 0.00 1 PROT 1"
buff = IOBuffer()
printatom(buff, atoms[1])
@test length(split(String(take!(buff)))) == 28
end

"""
printatom(atom::Atom)
printatom(io::IO, atom::Atom)

Prints an `Atom` structure in a human-readable format, with a title line.
Prints an `Atom` structure in a human-readable format, with a title line. By default the output is printed to `stdout`,
and the `io` argument can be used to specify a different output stream.

### Example

Expand All @@ -315,10 +320,11 @@ julia> atoms[1] # default show method
```

"""
function printatom(atom::Atom)
println(atom_title)
println(atom_line(atom))
function printatom(io::IO, atom::Atom)
println(io, atom_title)
println(io, atom_line(atom))
end
printatom(atom::Atom) = printatom(stdout, atom)

#
# Print a formatted list of atoms
Expand Down Expand Up @@ -452,6 +458,8 @@ end
@test element(Atom(name = "N", pdb_element="A")) == "A"
@test element(Atom(name = "A")) === nothing
@test element(Atom(name = " ")) === nothing
atom = Atom(name="", pdb_element="")
@test element(atom) === nothing
end

#
Expand Down Expand Up @@ -624,3 +632,19 @@ end
@test atomic_mass(at) ≈ 14.0067
@test position(at) ≈ StaticArrays.SVector(0.0, 0.0, 0.0)
end

@testitem "atom - show" begin
using PDBTools: print_short_atom_list
at = Atom(;segname="X")
buff = IOBuffer()
show(buff, at)
@test length(split(String(take!(buff)))) == 14
print_short_atom_list(buff, [at, at])
@test length(split(String(take!(buff)))) == 14*3
print_short_atom_list(buff, [at, at])
@test length(split(String(take!(buff)))) == 14*3
print_short_atom_list(buff, [copy(at) for _ in 1:20])
@test length(split(String(take!(buff)))) == 14*7 + 1
show(buff, [at])
@test String(take!(buff)) == "PDBTools.Atom{Nothing}[ 0 X XXX X 0 0 0.000 0.000 0.000 0.00 0.00 0 X 0]"
end
6 changes: 6 additions & 0 deletions src/distance.jl
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ end
@test all(isapprox.(closest(r1[1], coor(r2[2])),(1, 1, 5.121218702613667); atol=1e-3))
@test all(isapprox.(closest(coor(r1[1]), r2[2]),(1, 1, 5.121218702613667); atol=1e-3))
@test all(isapprox.(closest(r1[1], r2[2]),(1, 1, 5.121218702613667); atol=1e-3))
@test all(isapprox.(closest(r1[1], r2), (1, 2, 5.121218702613667); atol=1e-3))
@test all(isapprox.(closest(r2, r1[1]), (2, 1, 5.121218702613667); atol=1e-3))

@test distance(r1, r2) ≈ 3.6750402718881863 atol=1e-3
@test distance(coor(r1), r2) ≈ 3.6750402718881863 atol=1e-3
Expand All @@ -173,6 +175,10 @@ end
r = collect(eachresidue(atoms))
@test all(isapprox.(closest(r[1], [0.0, 0.0, 0.0]), (12, 1, 16.545482827648158); atol=1e-3))
@test all(isapprox.(closest([0.0, 0.0, 0.0], r[1]), (1, 12, 16.545482827648158); atol=1e-3))
@test all(isapprox.(closest(Atom(), r[1]), (1, 12, 16.545482827648158); atol=1e-3))
@test all(isapprox.(closest(r[1], Atom()), (12, 1, 16.545482827648158); atol=1e-3))
@test all(isapprox.(closest([coor(Atom())], r[1]), (1, 12, 16.545482827648158); atol=1e-3))
@test all(isapprox.(closest(r[1], [coor(Atom())]), (12, 1, 16.545482827648158); atol=1e-3))

end

34 changes: 28 additions & 6 deletions src/formula.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
struct Formula
formula::Vector{Tuple{Atom,Int}}
end
Base.getindex(f::Formula, i) = f.formula[i]
Base.getindex(f::Formula, i) = (String(pdb_element(first(f.formula[i]))), last(f.formula[i]))

const sub_int = (
"0" => "₀",
Expand All @@ -22,7 +22,8 @@ const sub_int = (
"""
formula(atoms::AbstractVector{<:Atom})

Returns the molecular formula of the current selection.
Returns the molecular formula of the current selection. The output is an indexable
"Formula" structure, where each element is a tuple with the element name and the number of atoms.

## Example

Expand All @@ -34,13 +35,17 @@ julia> pdb = read_pdb(PDBTools.TESTPDB, "residue 1"); # testing PDB file
julia> resname(pdb[1])
"ALA"

julia> formula(pdb)
julia> f = formula(pdb)
H₇C₃N₁O₁

julia> f[1]
("H", 7)

```

"""
function formula(atoms::AbstractVector{<:Atom})
f = Formula(Tuple{Atom,Int}[])
function formula(atoms::AbstractVector{<:AtomType}) where {AtomType<:Atom}
f = Formula(Tuple{AtomType,Int}[])
for at in atoms
i = findfirst(el -> pdb_element(first(el)) == element(at), f.formula)
if isnothing(i)
Expand Down Expand Up @@ -71,7 +76,7 @@ Returns the stoichiometry of atom selection in a `Formula` structure.

### Example

```julia-repl
```jldoctest
julia> using PDBTools

julia> pdb = read_pdb(PDBTools.TESTPDB, "water"); # testing PDB file
Expand All @@ -89,3 +94,20 @@ function stoichiometry(atoms::AbstractVector{<:Atom})
end
f
end

@testitem "Formula" begin
using PDBTools
pdb = read_pdb(PDBTools.TESTPDB, "resname GLY")
f = formula(pdb)
buff = IOBuffer()
show(buff, f)
@test String(take!(buff)) == "H₃₆C₂₄N₁₂O₁₂"
@test f[1] == ("H", 36)
@test f[4] == ("O", 12)
s = stoichiometry(pdb)
buff = IOBuffer()
show(buff, s)
@test String(take!(buff)) == "H₃C₂N₁O₁"
@test s[1] == ("H", 3)
@test s[4] == ("O", 1)
end
35 changes: 30 additions & 5 deletions src/getseq.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,25 @@ Returns the sequence of aminoacids from the vector of atoms or file name. Select

### Example

```julia-repl
julia> protein = wget("1LBD");
```jldoctest
julia> using PDBTools

julia> protein = read_pdb(PDBTools.TESTPDB);

julia> getseq(protein,"residue < 3")
2-element Vector{String}:
"S"
"A"
"C"

julia> getseq(protein,"residue < 3", code=2)
2-element Vector{String}:
"SER"
"ALA"
"CYS"

julia> getseq(protein,"residue < 3",code=3)
2-element Vector{String}:
"Serine"
"Alanine"
"Cysteine"

```

Expand Down Expand Up @@ -64,3 +66,26 @@ function getseq(file::String, selection::String; code::Int=1)
end

getseq(file::String; only=all, code::Int=1) = getseq(read_pdb(file), only=only, code=code)

@testitem "getseq" begin
using PDBTools
ats = read_pdb(PDBTools.TESTPDB)
s = getseq(ats, "residue < 3")
@test s == ["A", "C"]
s = getseq(ats, "residue < 3"; code=2)
@test s == ["ALA", "CYS"]
s = getseq(ats, "residue < 3"; code=3)
@test s == ["Alanine", "Cysteine"]
wat = select(ats, "water")
s = getseq(wat, "resnum < 3")
@test s == ["T", "T", "T", "T"]
s = getseq(wat, "resnum < 3"; code=2)
@test s == ["TIP3", "TIP3", "TIP3", "TIP3"]
s = getseq(wat, "resnum < 3"; code=3)
@test s == ["TIP3", "TIP3", "TIP3", "TIP3"]
s = getseq(PDBTools.TESTPDB, "residue < 3")
s = getseq(ats, "residue < 3")
@test s == ["A", "C"]
s = getseq(PDBTools.TESTPDB; only = at -> resnum(at) == 1)
@test s == ["A", "C", "S", "T", "T", "T"]
end
41 changes: 28 additions & 13 deletions src/parsers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function _parse(
x = _tryparse(T, s)
!isnothing(x) && return x
if isnothing(alt)
error("Could not read $T from string: \"$s\"")
throw(ArgumentError("Could not read $T from string: \"$s\""))
else
return alt
end
Expand Down Expand Up @@ -105,16 +105,31 @@ function setfield_recursive!(atom::AtomType, field_values::FIELDS, inds_and_name
setfield_recursive!(atom, field_values, Base.tail(inds_and_names))
end

# Alternative implementation using generated functions (same peformance as far as tested)
# https://discourse.julialang.org/t/unroll-setfield/122545/22?u=lmiq
@generated function setfield_generated!(atom, field_values::FIELDS, inds_and_names::TUPTUP, ::Val{N}) where {FIELDS,TUPTUP,N}
quote
@inline
Base.@nexprs $N i -> begin
ifield, valfield = inds_and_names[i]
field = unwrap(valfield)
T = typeof(getfield(atom, field))
setfield!(atom, field, _parse(T, field_values[ifield]; alt=_alt(T)))
end
end
## Alternative implementation using generated functions (same peformance as far as tested)
## https://discourse.julialang.org/t/unroll-setfield/122545/22?u=lmiq
#@generated function setfield_generated!(atom, field_values::FIELDS, inds_and_names::TUPTUP, ::Val{N}) where {FIELDS,TUPTUP,N}
# quote
# @inline
# Base.@nexprs $N i -> begin
# ifield, valfield = inds_and_names[i]
# field = unwrap(valfield)
# T = typeof(getfield(atom, field))
# setfield!(atom, field, _parse(T, field_values[ifield]; alt=_alt(T)))
# end
# end
#end

@testitem "_parse" begin
using PDBTools: _parse, _parse_charge
@test _parse(Int, " 1 ") == 1
@test _parse(Int, " A ") == 10
@test _parse(Float32, " 1.0 ") == 1.0f0
@test_throws ArgumentError _parse(Int, " ??? ")
@test_throws ArgumentError _parse(Float32, " A ")
@test _parse(String, " A ") == "A"
@test _parse(String, "") === nothing
@test _parse_charge("1+") == "1"
@test _parse_charge("+1") == "1"
@test _parse_charge("1-") == "-1"
@test _parse_charge("-1") == "-1"
end
Loading