Skip to content

Commit 6ffcbfc

Browse files
Merge branch 'master' into bcif
2 parents 88d6940 + a507527 commit 6ffcbfc

File tree

10 files changed

+37
-26
lines changed

10 files changed

+37
-26
lines changed

NEWS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# BioStructures.jl release notes
22

3+
## v4.5.0 - May 2025
4+
5+
* `chiangle` and `chiangles` are added to calculate the sidechain dihedral angles in protein residues.
6+
* mmCIF files with secondary structure annotations will now, by default, parse and assign secondary structure. Setting `run_dssp` or `run_stride` to `true` will cause DSSP or STRIDE to be run and provide the secondary structure, as before.
7+
* A constructor for `MetaGraph` on a `Chain` is added that constructs a graph of atoms where edges are determined by the known bonds of standard amino acids in the chain.
8+
39
## v4.4.2 - Mar 2025
410

511
* A bug in storing indices for `Transformation` is fixed.

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "BioStructures"
22
uuid = "de9282ab-8554-53be-b2d6-f6c222edabfc"
33
authors = ["Joe G Greener <jgreener@hotmail.co.uk>"]
4-
version = "4.4.2"
4+
version = "4.5.0"
55

66
[deps]
77
BioGenerics = "47718e42-2ac5-11e9-14af-e5595289c2ea"

docs/src/documentation.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ The coordinate sets must be the same size and have the number of dimensions in t
527527

528528
The contacting elements in a molecular structure form a graph, and this can be retrieved using `MetaGraph`.
529529
This extends `MetaGraph` from [MetaGraphs.jl](https://github.com/JuliaGraphs/MetaGraphs.jl), allowing you to use all the graph analysis tools in [Graphs.jl](https://github.com/JuliaGraphs/Graphs.jl).
530-
For example:
530+
For example to find the graph from a contact map of Cβ atoms closer than 8 Å:
531531

532532
```julia-repl
533533
julia> using Graphs, MetaGraphs
@@ -552,6 +552,9 @@ See the [Graphs docs](https://juliagraphs.org/Graphs.jl/dev) for details on how
552552
Similar to [`ContactMap`](@ref), contacts are found between any element type passed in.
553553
So if you wanted the graph of chain contacts in a protein complex you could give a [`Model`](@ref) as the first argument.
554554

555+
Calling `MetaGraph` on a [`Chain`](@ref) without a contact distance does something different: it constructs a graph of atoms where edges are determined by the known bonds of standard amino acids in the chain.
556+
Hydrogens should be present and atom names should match those in OpenMM.
557+
555558
## Assigning secondary structure
556559

557560
Any secondary structure assignment at a residue is accessed via [`sscode`](@ref):

ext/BioStructuresGraphsExt.jl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ using BioStructures: findatombyname
88
"""
99
MetaGraph(element, contact_distance)
1010
11-
Construct a graph of atoms where edges are contacts separated by less than `contact_distance`.
11+
Construct a graph of elements where edges are contacts separated by less
12+
than `contact_distance`.
1213
1314
See Graphs.jl and MetaGraphs.jl for more on how to use graphs.
1415
"""
@@ -30,22 +31,24 @@ function MetaGraphs.MetaGraph(el::StructuralElementOrList, contact_dist::Real)
3031
end
3132

3233
"""
33-
MetaGraph(chain::Chain; strict::Bool = true)
34+
MetaGraph(chain::Chain; strict::Bool=true)
3435
35-
Construct a graph of atoms where edges are determined by the known bonds of residues in the chain.
36+
Construct a graph of atoms where edges are determined by the known bonds
37+
of residues in the chain.
3638
3739
By default, the graph is constructed in `strict` mode, which means that:
3840
3941
- residue and atom names must be standard
4042
- all hydrogens are present
4143
- HIS must be disambiguated as HIE, HID, or HIP
4244
43-
These constraints can be relaxed by setting `strict = false`, at some risk to accuracy.
45+
These constraints can be relaxed by setting `strict = false`, at some
46+
risk to accuracy.
4447
4548
See Graphs.jl and MetaGraphs.jl for more on how to use graphs.
4649
"""
47-
function MetaGraphs.MetaGraph(chain::Chain; strict::Bool = true)
48-
el_list = collectatoms(chain; expand_disordered = true)
50+
function MetaGraphs.MetaGraph(chain::Chain; strict::Bool=true)
51+
el_list = collectatoms(chain; expand_disordered=true)
4952
mg = MetaGraph(length(el_list))
5053
for (i, el) in enumerate(el_list)
5154
set_prop!(mg, i, :element, el)

ext/BioStructuresMMTFExt.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ function BioStructures.writemmtf(output::Union{AbstractString, IO},
197197
atom_selectors::Function...;
198198
expand_disordered::Bool=true,
199199
gzip::Bool=false)
200-
loop_el = isa(el, MolecularStructure) ? collectmodels(el) : el
200+
loop_el = (isa(el, MolecularStructure) ? collectmodels(el) : el)
201201
ats = sort(sort(sort(collectatoms(loop_el, atom_selectors...;
202202
expand_disordered=expand_disordered)),
203203
by=residue), by=model)
@@ -251,7 +251,7 @@ function BioStructures.writemmtf(output::Union{AbstractString, IO},
251251
"chainIndexList" => Any[length(d["chainIdList"]) - 1],
252252
"description" => "",
253253
"sequence" => "", # This is changed later
254-
"type" => ishetero(res) ? "non-polymer" : "polymer",
254+
"type" => (ishetero(res) ? "non-polymer" : "polymer"),
255255
))
256256
end
257257
if !ishetero(res)
@@ -286,7 +286,7 @@ function BioStructures.writemmtf(output::Union{AbstractString, IO},
286286
"bondAtomList" => Any[],
287287
"elementList" => Any[element(at) for at in ats_res],
288288
# MMTF specifies missing charges as zero
289-
"formalChargeList" => Any[charge(at) == "" ? 0 : parse(Int64, charge(at)) for at in ats_res],
289+
"formalChargeList" => Any[(charge(at) == "" ? 0 : parse(Int64, charge(at))) for at in ats_res],
290290
"singleLetterCode" => "",
291291
"chemCompType" => "",
292292
"atomNameList" => Any[at_names...],
@@ -295,17 +295,17 @@ function BioStructures.writemmtf(output::Union{AbstractString, IO},
295295
end
296296

297297
push!(d["groupIdList"], resnumber(res))
298-
push!(d["groupTypeList"], group_i == 0 ? length(d["groupList"]) - 1 : group_i - 1)
299-
push!(d["insCodeList"], inscode(res) == ' ' ? '\0' : inscode(res))
298+
push!(d["groupTypeList"], (group_i == 0 ? length(d["groupList"]) - 1 : group_i - 1))
299+
push!(d["insCodeList"], (inscode(res) == ' ' ? '\0' : inscode(res)))
300300
push!(d["secStructList"], -1)
301-
push!(d["sequenceIndexList"], ishetero(res) ? -1 : length(sequence) - 1)
301+
push!(d["sequenceIndexList"], (ishetero(res) ? -1 : length(sequence) - 1))
302302

303303
prev_resname = resname(res)
304304
prev_het = ishetero(res)
305305
last_res = res
306306
end
307307

308-
push!(d["altLocList"], altlocid(at) == ' ' ? '\0' : altlocid(at))
308+
push!(d["altLocList"], (altlocid(at) == ' ' ? '\0' : altlocid(at)))
309309
push!(d["atomIdList"], serial(at))
310310
push!(d["bFactorList"], tempfactor(at))
311311
push!(d["occupancyList"], occupancy(at))

extractdata/bonding.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ function parsexmlline(f, line, tag, keyname)
3838
return key => (; vals...)
3939
end
4040

41-
4241
atomtypes, residues = open("protein.ff14SB.xml", "r") do io
4342
line = readline(io)
4443
@assert line == "<ForceField>"

src/mmcif.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@ function writemmcif(output::IO,
573573
atom_selectors::Function...;
574574
expand_disordered::Bool=true, gzip::Bool=false)
575575
# Ensure multiple models get written out correctly
576-
loop_el = isa(el, MolecularStructure) ? collectmodels(el) : el
576+
loop_el = (isa(el, MolecularStructure) ? collectmodels(el) : el)
577577
ats = collectatoms(loop_el, atom_selectors...;
578578
expand_disordered=expand_disordered)
579579
if length(ats) > 0
@@ -590,7 +590,7 @@ function writemmcif(output::IO,
590590
appendatom!(atom_dict, at, string(modelnumber(at)),
591591
strip(chainid(at)) == "" ? "." : chainid(at),
592592
string(resnumber(at)), resname(at),
593-
ishetero(at) ? "HETATM" : "ATOM")
593+
(ishetero(at) ? "HETATM" : "ATOM"))
594594
end
595595

596596
# Now the MMCIFDict has been generated, write it out to the file

src/model.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ function Residue(r::Residue, ch::StructuralElement)
153153
rnew = Residue(r.name, r.number, r.ins_code, r.het_res, [name for name in r.atom_list],
154154
atom_dict, ch, r.ss_code)
155155
for (name, atom) in r.atoms
156-
atom_dict[name] = isa(atom, Atom) ? Atom(atom, rnew) : DisorderedAtom(atom, rnew)
156+
atom_dict[name] = (isa(atom, Atom) ? Atom(atom, rnew) : DisorderedAtom(atom, rnew))
157157
end
158158
return rnew
159159
end
@@ -183,7 +183,7 @@ function Chain(c::Chain, mo::StructuralElement)
183183
res_dict = Dict{String,AbstractResidue}()
184184
cnew = Chain(c.id, [id for id in c.res_list], res_dict, mo)
185185
for (id, res) in c.residues
186-
res_dict[id] = isa(res, Residue) ? Residue(res, cnew) : DisorderedResidue(res, cnew)
186+
res_dict[id] = (isa(res, Residue) ? Residue(res, cnew) : DisorderedResidue(res, cnew))
187187
end
188188
return cnew
189189
end
@@ -1412,7 +1412,7 @@ function collectresidues(el::Union{Chain,Vector{<:AbstractResidue}};
14121412
end
14131413
return res_list
14141414
else
1415-
return isa(el, Chain) ? collect(el) : el
1415+
return (isa(el, Chain) ? collect(el) : el)
14161416
end
14171417
end
14181418

@@ -1506,7 +1506,7 @@ function collectatoms(el::Union{Residue,Vector{<:AbstractAtom}};
15061506
end
15071507
return at_list
15081508
else
1509-
return isa(el, Residue) ? collect(el) : el
1509+
return (isa(el, Residue) ? collect(el) : el)
15101510
end
15111511
end
15121512

src/pdb.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,12 @@ end
201201

202202
function parseoccupancy(line::String)
203203
ret = tryparse(Float64, line[55:60])
204-
return ret === nothing ? 1.0 : ret
204+
return (ret === nothing ? 1.0 : ret)
205205
end
206206

207207
function parsetempfac(line::String)
208208
ret = tryparse(Float64, line[61:66])
209-
return ret === nothing ? 0.0 : ret
209+
return (ret === nothing ? 0.0 : ret)
210210
end
211211

212212
function parseelement(line::String)

test/runtests.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2426,7 +2426,7 @@ end
24262426
]
24272427
# Read from file - write a small multicif manually and read it back
24282428
for gzip in (false, true)
2429-
transcoder = gzip ? (GzipCompressorStream,) : ()
2429+
transcoder = (gzip ? (GzipCompressorStream,) : ())
24302430
open(transcoder..., temp_filename, "w") do f_out
24312431
open(testfilepath("mmCIF", "1AKE.cif")) do f_in
24322432
write(f_out, f_in)
@@ -3192,7 +3192,7 @@ end
31923192
@test isapprox(omegas[10], omegaangle(struc_1AKE['A'], 10), atol=1e-5)
31933193

31943194
# Test that the entries in `chitables` are bonded
3195-
sortt((a, b)) = a < b ? (a, b) : (b, a)
3195+
sortt((a, b)) = (a < b ? (a, b) : (b, a))
31963196
rd = BioStructures.residuedata
31973197
for ct in BioStructures.chitables
31983198
for (rname, alist) in ct

0 commit comments

Comments
 (0)