Skip to content

Commit 49dac0c

Browse files
authored
Encode bond lengths and angles (#73)
This extracts more data from ff14SB, but just the portion that is independent of the force field.
1 parent a507527 commit 49dac0c

File tree

3 files changed

+405
-6
lines changed

3 files changed

+405
-6
lines changed

extractdata/bonding.jl

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,33 @@ function parsestring(str)
2121
return String(str[2:end-1])
2222
end
2323

24-
function parsexmlline(f, line, tag, keyname)
24+
function parsexmlline(f, line, tag, keynames...; skip=())
2525
@assert startswith(line, "<$tag ")
2626
@assert endswith(line, "/>")
2727
kv = split(strip(line[length(tag)+2:end-2]), ' ')
28-
key = ""
28+
key = String[]
2929
vals = Pair{Symbol,Any}[]
3030
for kvp in kv
3131
k, v = split(kvp, '=')
32-
if k == keyname
33-
key = parsestring(v)
32+
k skip && continue
33+
if k keynames
34+
push!(key, parsestring(v))
3435
else
3536
push!(vals, Symbol(k) => f(k, v))
3637
end
3738
end
39+
@assert length(key) == length(keynames)
40+
key = length(key) == 1 ? only(key) : (key...,)
3841
return key => (; vals...)
3942
end
4043

41-
atomtypes, residues = open("protein.ff14SB.xml", "r") do io
44+
atomtypes, residues, bondlengths, bondangles = open("protein.ff14SB.xml", "r") do io
4245
line = readline(io)
4346
@assert line == "<ForceField>"
4447
atomtypes = Dict{String, @NamedTuple{element::String, mass::Float32, name::String}}()
4548
residues = Dict{String, @NamedTuple{atoms::Dict{String, @NamedTuple{charge::Float32, type::String}}, bonds::Vector{Tuple{String,String}}, externalbonds::Vector{String}}}()
49+
harmonicbonds = Dict{Tuple{String,String}, @NamedTuple{length::Float32}}()
50+
harmonicangles = Dict{Tuple{String,String,String}, @NamedTuple{angle::Float32}}()
4651
parsexmblock(io, "</ForceField>") do line
4752
if line == "<AtomTypes>"
4853
parsexmblock(io, "</AtomTypes>") do line
@@ -92,9 +97,31 @@ atomtypes, residues = open("protein.ff14SB.xml", "r") do io
9297
error("Unknown Residues line $line")
9398
end
9499
end
100+
elseif line == "<HarmonicBondForce>"
101+
parsexmblock(io, "</HarmonicBondForce>") do line
102+
push!(harmonicbonds, parsexmlline(line, "Bond", "type1", "type2"; skip=("k",)) do k, v
103+
if k == "length"
104+
return parse(Float32, v[2:end-1])
105+
else
106+
error("Unknown Bond key $k")
107+
end
108+
end)
109+
end
110+
elseif line == "<HarmonicAngleForce>"
111+
parsexmblock(io, "</HarmonicAngleForce>") do line
112+
push!(harmonicangles, parsexmlline(line, "Angle", "type1", "type2", "type3"; skip=("k",)) do k, v
113+
if k == "k"
114+
return parse(Float32, v[2:end-1]) # strip the quotes
115+
elseif k == "angle"
116+
return parse(Float32, v[2:end-1]) # strip the quotes
117+
else
118+
error("Unknown Angle key $k")
119+
end
120+
end)
121+
end
95122
end
96123
end
97-
atomtypes, residues
124+
atomtypes, residues, Dict(k => 10 * v.length for (k, v) in harmonicbonds), Dict(k => v.angle for (k, v) in harmonicangles)
98125
end
99126

100127
open(joinpath(dirname(@__DIR__), "src", "bonding.jl"), "w") do io
@@ -117,4 +144,18 @@ open(joinpath(dirname(@__DIR__), "src", "bonding.jl"), "w") do io
117144
println(io, " externalbonds = ", v.externalbonds, "),")
118145
end
119146
println(io, ")")
147+
148+
println(io, "\nconst bondlengths = Dict{Tuple{String,String}, Float32}(")
149+
hb = sort!(collect(bondlengths); by=first)
150+
for pr in hb
151+
println(io, " ", pr, ',')
152+
end
153+
println(io, ")")
154+
155+
println(io, "\nconst bondangles = Dict{Tuple{String,String,String}, Float32}(")
156+
ha = sort!(collect(bondangles); by=first)
157+
for pr in ha
158+
println(io, " ", pr, ',')
159+
end
160+
println(io, ")")
120161
end

0 commit comments

Comments
 (0)