-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4bf2b78
commit 04c9b5e
Showing
16 changed files
with
454 additions
and
321 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using PeriodicTable: elements | ||
|
||
const ELEMENT_SYMBOL_TO_ATOMIC_NUMBER = Dict(uppercase(elements[atomic_number].symbol) => atomic_number for atomic_number in 1:118) | ||
const ATOMIC_NUMBER_TO_ELEMENT_SYMBOL = Dict(n => s for (s, n) in ELEMENT_SYMBOL_TO_ATOMIC_NUMBER) | ||
|
||
element_symbol_to_atomic_number(element_symbol::AbstractString) = ELEMENT_SYMBOL_TO_ATOMIC_NUMBER[uppercase(element_symbol)] | ||
atomic_number_to_element_symbol(atomic_number::Integer) = ATOMIC_NUMBER_TO_ELEMENT_SYMBOL[atomic_number] | ||
|
||
encode_atom_name(atom_name::AbstractString) = reinterpret(UInt32, codeunits(lpad(atom_name, 4)))[1] | ||
decode_atom_name(atom_name::UInt32) = String(reinterpret(UInt8, [atom_name])) | ||
|
||
mutable struct Atom{T<:AbstractFloat} | ||
atom_name::UInt32 | ||
atomic_number::UInt8 | ||
x::T | ||
y::T | ||
z::T | ||
end | ||
|
||
coords(atom::Atom) = [atom.x, atom.y, atom.z] | ||
|
||
Base.summary(atom::Atom) = "$(elements[atom.atomic_number].name) atom at [$(atom.x), $(atom.y), $(atom.z)])" | ||
|
||
Atom(atom_name::UInt32, atomic_number::Integer, x::T, y::T, z::T) where T = Atom{T}(atom_name, atomic_number, x, y, z) | ||
Atom(atom_name::UInt32, element_symbol::AbstractString, args...) = Atom(atom_name, element_symbol_to_atomic_number(element_symbol), args...) | ||
Atom(atom_name::AbstractString, args...) = Atom(encode_atom_name(atom_name), args...) | ||
Atom(atom_name::AbstractString, element_symbol, coords::AbstractVector{<:AbstractFloat}) = Atom(atom_name, element_symbol, coords...) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,79 @@ | ||
# TODO: store non-backbone atoms | ||
|
||
function assign_bond_lengths!(chain::ProteinChain) | ||
chain.bond_lengths = Backboner.get_bond_lengths(Backboner.Backbone(chain.backbone)) | ||
end | ||
export assign_property! | ||
|
||
function assign_bond_angles!(chain::ProteinChain) | ||
chain.bond_angles = Backboner.get_bond_angles(Backboner.Backbone(chain.backbone)) | ||
end | ||
export residue_indexing_function | ||
export ResidueIndexingUndefined | ||
|
||
function assign_torsion_angles!(chain::ProteinChain) | ||
chain.torsion_angles = Backboner.get_torsional_angles(Backboner.Backbone(chain.backbone)) | ||
end | ||
assign_property!(x, name::Symbol, args...) = assign_property!(x, Val(name), args...) | ||
|
||
function assign_secondary_structure!(chain::ProteinChain, dict::Union{Dict{ProteinChain,Any},Nothing}=nothing) | ||
function assign_property!(chain::ProteinChain, ::Val{:secondary_structure}, dict::Union{Dict{ProteinChain,Any},Nothing}=nothing) | ||
number_vector = isnothing(dict) ? ASS.assign_secondary_structure(chain) : dict[chain] | ||
chain.secondary_structure = number_vector_to_code_string(number_vector) | ||
end | ||
|
||
function assign_standard_residue!(chain::ProteinChain, standard_residue::Matrix{<:Real}=STANDARD_RESIDUE_ANGSTROM) | ||
chain.standard_residue = standard_residue | ||
function assign_property!(chain::ProteinChain, ::Val{:ideal_residue}, ideal_residue::AbstractMatrix{<:Real}=DEFAULT_IDEAL_RESIDUE) | ||
chain.ideal_residue = collect(ideal_residue) | ||
end | ||
|
||
function assign_residue_rotations!(chain::ProteinChain) | ||
frames = Backboner.Frames(Backboner.Backbone(chain.backbone), chain.standard_residue) | ||
function assign_property!(chain::ProteinChain, ::Val{:residue_rotations}) | ||
frames = Backboner.Frames(Backboner.Backbone(chain.backbone), chain.ideal_residue) | ||
chain.residue_rotations = frames.rotations | ||
end | ||
|
||
function assign_residue_rotations_quat!(chain::ProteinChain) | ||
frames = Backboner.Frames(Backboner.Backbone(chain.backbone), chain.standard_residue) | ||
function assign_property!(chain::ProteinChain, ::Val{:residue_rotations_quat}) | ||
frames = Backboner.Frames(Backboner.Backbone(chain.backbone), chain.ideal_residue) | ||
chain.residue_rotations_quat = rotation_matrices_to_quaternions(frames.rotations) | ||
end | ||
|
||
function assign_residue_translations!(chain::ProteinChain) | ||
function assign_property!(chain::ProteinChain, ::Val{:residue_translations}) | ||
chain.residue_translations = Backboner.centroid(chain.backbone; dims=2) | ||
end | ||
|
||
function assign_is_knotted!(chain::ProteinChain) | ||
function assign_property!(chain::ProteinChain, ::Val{:bond_lengths}) | ||
chain.bond_lengths = Backboner.get_bond_lengths(Backboner.Backbone(chain.backbone)) | ||
end | ||
|
||
function assign_property!(chain::ProteinChain, ::Val{:bond_angles}) | ||
chain.bond_angles = Backboner.get_bond_angles(Backboner.Backbone(chain.backbone)) | ||
end | ||
|
||
function assign_property!(chain::ProteinChain, ::Val{:torsion_angles}) | ||
chain.torsion_angles = Backboner.get_torsional_angles(Backboner.Backbone(chain.backbone)) | ||
end | ||
|
||
function assign_property!(chain::ProteinChain, ::Val{:is_knotted}) | ||
chain.is_knotted = Backboner.is_knotted(Backboner.Backbone(chain.backbone)[2:3:end]) | ||
end | ||
|
||
|
||
struct ResidueIndexingUndefined <: Exception | ||
name::Symbol | ||
end | ||
|
||
ResidueIndexingUndefined(val::Val) = typeof(val).type_parameters[1] | ||
|
||
Base.showerror(io::IO, err::ResidueIndexingUndefined) = print(io, "$(typeof(err)): property `:$(err.name)` does not have a defined reorder function. Property needs reassignment.") | ||
|
||
residue_indexing_function(name::Symbol) = residue_indexing_function(Val(name)) | ||
|
||
# move non-properties to getindex(::ProteinChain) | ||
residue_indexing_function(::Val{:id}) = (x, i) -> x[i] | ||
residue_indexing_function(::Val{:sequence}) = (x, i) -> x[i] | ||
residue_indexing_function(::Val{:backbone}) = (x, i) -> x[:, :, i] | ||
residue_indexing_function(::Val{:atoms}) = (x, i) -> x[i] | ||
|
||
residue_indexing_function(::Val{:secondary_structure}) = (x, i) -> x[i] | ||
residue_indexing_function(::Val{:residue_rotations}) = (x, i) -> x[:, :, i] | ||
residue_indexing_function(::Val{:residue_rotations_quat}) = (x, i) -> x[:, i] | ||
residue_indexing_function(::Val{:residue_translations}) = (x, i) -> x[:, i] | ||
|
||
residue_indexing_function(name::Val{:bond_lengths}) = throw(ResidueIndexingUndefined(name)) | ||
residue_indexing_function(name::Val{:bond_angles}) = throw(ResidueIndexingUndefined(name)) | ||
residue_indexing_function(name::Val{:torsion_angles}) = throw(ResidueIndexingUndefined(name)) | ||
residue_indexing_function(name::Val{:is_knotted}) = throw(ResidueIndexingUndefined(name)) | ||
|
||
flatten_property(chains::AbstractVector{<:ProteinChain}, ::Val{:sequence}) = join(chain -> chain.sequence, chains) | ||
|
||
|
||
function extend_property! end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,54 @@ | ||
""" | ||
ProteinChain | ||
ProteinChain{T<:AbstractFloat} | ||
## Examples | ||
```jldoctest | ||
julia> structure = pdb"1EYE" | ||
julia> structure = pdb"1EYE"; | ||
[ Info: Downloading file from PDB: 1EYE | ||
1-chain ProteinStructure "1EYE.cif" with 0 properties: | ||
256-residue ProteinChain "A" with 0 properties | ||
julia> structure[1] | ||
256-residue ProteinChain "A" with 0 properties: | ||
253-residue ProteinChain "A" with 2 properties: | ||
fields: | ||
id::String = "A" | ||
aminoacids::String = "PVQVMGVLNVTDDSFSDGGCYLDLDDAVKHGLAMAAAGAGIVDVGGETSRVIPVVKELAAQGITVSIDTMRADVARAALQNGAQMVNDVSGGRADPAM… | ||
backbone::Array{Float64, 3} = [45.592 44.171 43.719; -10.864 -10.936 -9.688; 30.192 30.504 31.278;;; 42.568 42.02 40.707; -9.163 … | ||
numbers::Vector{Int64} = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14 … 265, 266, 267, 268, 269, 270, 271, 272, 273, 274] | ||
properties: (none) | ||
sequence::String = "PVQVMGVLNVTDDSFSDGGCYLDLDDAVKHGLAMAAAGAGIVDVGGETSRVIPVVKELAAQGITVIDTMRADVARAALQNGAQMVNDVSGGRADPAMG… | ||
backbone::Array{Float64,3} = [45.592 44.171 43.719; -10.864 -10.936 -9.688; 30.192 30.504 31.278;;; 42.568 42.02 40.707; -9.163 … | ||
atoms::Vector{Vector{ProteinChains.Atom{Float64}}} = Vector{Atom{Float64}}[[Atom{Float64}(0x4f202020, 0x08, 44.41, -9.176, 32.157), Atom{Float64}(0x4243… | ||
properties: | ||
numbering::Vector{Int64} = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14 … 265, 266, 267, 268, 269, 270, 271, 272, 273, 274] | ||
modelnum::Int64 = 1 | ||
``` | ||
""" | ||
mutable struct ProteinChain | ||
mutable struct ProteinChain{T<:AbstractFloat} | ||
id::String | ||
aminoacids::String | ||
backbone::Array{Float64,3} | ||
numbers::Vector{Int} | ||
properties::Dict{Symbol,Any} | ||
|
||
function ProteinChain(id::String, aminoacids::String, backbone::Array{Float64,3}, numbers::Vector{Int}, properties::Dict{Symbol,Any}) | ||
chain = new(id, aminoacids, backbone, numbers, properties) | ||
countresidues(chain) | ||
@assert all(!in(fieldnames(ProteinChain)), keys(properties)) | ||
return chain | ||
end | ||
sequence::String | ||
backbone::Array{T,3} | ||
atoms::Vector{Vector{Atom{T}}} | ||
properties::Properties | ||
end | ||
|
||
Base.getproperty(chain::ProteinChain, property::Symbol) = _getproperty(chain, property) | ||
Base.setproperty!(chain::ProteinChain, property::Symbol, value) = _setproperty!(chain, property, value) | ||
|
||
function countresidues(chain::ProteinChain) | ||
@assert length(chain.aminoacids) == size(chain.backbone, 3) == length(chain.numbers) | ||
return length(chain.aminoacids) | ||
@assert length(chain.sequence) == size(chain.backbone, 3) | ||
return length(chain.sequence) | ||
end | ||
|
||
function ProteinChain(id::String, aminoacids::String, backbone::Array{Float64,3}, numbers::Vector{Int}; kwargs...) | ||
chain = ProteinChain(id, aminoacids, backbone, numbers, Dict{Symbol,Any}()) | ||
!isempty(kwargs) && push!(chain.properties, kwargs...) | ||
function ProteinChain(id::String, sequence::String, backbone::Array{T,3}, atoms::Vector{Vector{Atom{T}}}, properties::Properties) where T | ||
chain = ProteinChain{T}(id, sequence, backbone, atoms, properties) | ||
countresidues(chain) | ||
@assert size(backbone)[1:2] == (3, 3) | ||
return chain | ||
end | ||
|
||
function ProteinChain(id::String, sequence::String, backbone::Array{T,3}, atoms::Vector{Vector{Atom{T}}}=Vector{Atom{T}}[]; kwargs...) where T | ||
return ProteinChain(id, sequence, backbone, atoms, Properties(; kwargs...)) | ||
end | ||
|
||
Base.hasproperty(chain::ProteinChain, name::Symbol) = hasproperty(HasProperties(chain), name) | ||
Base.getproperty(chain::ProteinChain, name::Symbol) = getproperty(HasProperties(chain), name) | ||
Base.setproperty!(chain::ProteinChain, name::Symbol, value) = setproperty!(HasProperties(chain), name, value) | ||
Base.propertynames(chain::ProteinChain) = propertynames(HasProperties(chain)) | ||
|
||
Base.summary(chain::ProteinChain) = "$(countresidues(chain))-residue ProteinChain \"$(chain.id)\" with $(length(chain.properties)) properties" | ||
# where T <: Union{ProteinChain,ProteinStructure} | ||
|
||
function Base.show(io::IO, ::MIME"text/plain", chain::ProteinChain) | ||
context = IOContext(io, :compact => true, :limit => true) | ||
print(context, summary(chain), ":") | ||
printstyled(context, "\n fields:", color=:yellow) | ||
for fieldname in fieldnames(ProteinChain)[1:end-1] | ||
printfield(context, chain, fieldname) | ||
end | ||
printstyled(context, "\n properties:", color=:yellow) | ||
isempty(chain.properties) && print(io, " (none)") | ||
for property in keys(chain.properties) | ||
printfield(context, chain, property) | ||
end | ||
end | ||
Base.show(io::IO, ::MIME"text/plain", chain::ProteinChain) = showproperties(io, chain) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.