Types
In this section we will explore the main struct
instances that compose the core of ProtoSyn's engine, divided in the following topics, for organization purposes:
Pose
A pose holds all necessary information regarding a molecular system. This information is divided in the Graph and State .
ProtoSyn.Pose
— TypePose{T <: AbstractContainer}(graph::T, state::State)
Return a Pose instance. A Pose is a complete description of a molecular system at any given point, having both the interaction graph and the current state of the system coordinates represented. A Pose
is typed by an [AbstractContainer], usually a Topology
.
Pose(::T, frag::Fragment) where {T <: AbstractContainer}
Return a Pose instance from a Fragment
, where the State is empty/blank. The graph contents are copied to the new Pose. If no type T <: AbstractFloat
is provided, the Units.defaultFloat
will be used.
See also
Fragment
ProtoSyn.jl package uses a pose of a single Segment
(therefore without a Root) to carry information during certain processes (such as building a new peptide from a sequence).
ProtoSyn.Fragment
— TypeFragment
A Fragment
is a type overload for Pose{Segment}
and therefore does not contain a root/origin. These are usually used as temporary carriers of information, without the ability to be directly incorporated in simulations.
See also
Graph
The directed graph holds the information regarding the hierarchical organization of a molecular system, where the top level of organization is a Topology
instance, which can contain one or more instances of Segment
. This structure, in turn, is comprised of one or more Residue
instances, which are themselves a set of Atom
instances, this being the lowest level of data organization in ProtoSyn. By being a directed graph, this data organization structure introduces the concept of parenthood between particles in the system: each Atom
has a parent, and may have one or more child Atom
instances. The same concept is extended to Residue
and Segment
instances. Ultimately, the initial Atom
in a Pose
is a child of the root structure, a group of three virtual atoms. The parenthood relationships not only allow for directed traveling of the graph, but also offer interesting opportunities when coupled with the hybrid coordinate system of the Pose
's State.
ProtoSyn.Topology
— TypeTopology <: AbstractContainer{Segment}
Topology(name::String, id::Int)
Construct a Topology
, with the given name
and id
. A Topology
is the top level of hierarchy in a Graph, and holds a Root
Residue
, therefore initializing the internal coordinates system in the corresponding [State] of a Pose. Note: Topology
is of super type AbstractTopology
, which is an AbstractContainer
.
Fields
name::String
- The name of theTopology
id::Int
- The ID of theTopology
items::Vector{Segment}
- All theSegment
instances in thisTopology
(default: empty)size::Int
- The number ofSegment
instances in thisTopology
(default: 0)root::Residue
- The rootResidue
of thisTopology
container::Nothing
- Used to identify the rootResidue
(default:nothing
)
See also
Examples
julia> top = Topology("UNK", 1)
Topology{/UNK:1}
ProtoSyn.Segment
— TypeSegment <: AbstractContainer{Residue}
Segment(name::String, id::Int)
Construct a Segment
, with the given name
and id
. The created segment has no container. A Segment
is a group of Residue
instances. Note: Segment
is of super type AbstractSegment
, which is an AbstractContainer
.
Fields
name::String
- The name of theSegment
id::Int
- The ID of theSegment
index::Int
- The index of theSegment
(default: same as:id
)code::Char
- A 1-letter code for the chain (used in PDB formatting) (default: '?')items::Vector{Residue}
- A list ofResidue
instances in thisSegment
(default: empty)container::Opt{AbstractTopology}
- An optional container for thisSegment
(default:nothing
)size::Int
- The number ofResidue
instances in thisSegment
(default: 0)
See also
Examples
julia> res = Segment("UNK", 1)
Segment{/UNK:1}
ProtoSyn.Residue
— TypeResidue <: AbstractContainer{Atom}
Residue(name::String, id::Int)
Construct a Residue
, with the given name
and id
. The created residue has no container; it is also a free directed-graph node (no parent/children). A Residue
is a group of Atom
instances. Note: Residue
is of super type AbstractResidue
, which is an AbstractContainer
.
Fields
name::ResidueName
- The name of theResidue
id::Int
- The ID of theResidue
index::Int
- The index of theResidue
(default: same as:id
)items::Vector{Atom}
- A list ofAtom
instances in thisResidue
(default: empty)itemsbyname::Dict{String, Atom}
- ADict
object containing a link to each of theAtom
instances in thisResidue
bsed on the:name
of theAtom
(default: empty)container::Opt{AbstractSegment}
- An optional container for thisResidue
(default:nothing
)size::Int
- The number ofAtom
instances in thisResidue
(default: 0)visited::Bool
- Check whether thisResidue
has been visited (used by a some functions) (default:false
)parent::Opt{Residue}
- Optionally, the parent of thisResidue
in the directional graph (default:nothing
)children::Vector{Residue}
- Optionally, the list of childrenResidue
instances downstream of thisResidue
(default: empty)ascedents::Opt{NTuple{4, Int}}
- Optionally, the list of 4ascendents
, including thisResidue
(default:nothing
)
See also
Segment
Atom
ascendents
ResidueName
Examples
julia> res = Residue("UNK", 1)
Residue{/UNK:1}
Instead of defining Residue
.name as a String, ProtoSyn uses a specific type (ResidueName
) to accomodate specific conventions in aminoacid naming.
ProtoSyn.ResidueName
— TypeResidueName(s::String) <: AbstractString
A string overload to accomodate different known and expected denominations of certain residues ("HIS" == "HIE" for example).
Example
julia> ProtoSyn.ResidueName("HIS")
HIS
ProtoSyn.Atom
— TypeAtom <: AbstractContainer{Nothing}
An Atom
type.
Atom(name::String, id::Int, index::Int, symbol::String)
Construct an Atom
, with the given name
, id
, index
, and symbol
. The created atom has no bonds and container; it is also a free directed-graph node (no parent/children). Note: Atom
is of super type AbstractAtom
, which is an AbstractContainer
.
Fields
name::String
- The name of theAtom
id::Int
- The ID of theAtom
index::Int
- The index of theAtom
(default: same as:id
)symbol::String
- The chemical element symbol of thisAtom
bonds::Vector{Atom}
- A list ofAtom
instances connected to thisAtom
by a bond (default: empty)container::Opt{AbstractResidue}
- An optional container for thisAtom
(default:nothing
)visited::Bool
- Check whether thisAtom
has been visited (used by a some functions) (default:false
)parent::Opt{Atom}
- Optionally, the parent of thisAtom
in the directional graph (default:nothing
)children::Vector{Atom}
- Optionally, the list of childrenAtom
instances downstream of thisAtom
(default: empty)ascedents::Opt{NTuple{4, Int}}
- Optionally, the list of 4 ascendents, including thisAtom
(default:nothing
)
See also
Residue
[ascendents]
Examples
julia> at = Atom("H1", 1, 1, "H")
Atom{/H1:1}
State
A State structure is responsible for holding the current state of the internal and cartesian coordinates, as well as the forces felt on each atom and the resulting energy of the system (as calculated by an [EnergyFunction]). This structure is sub-divided in a list of AtomState
instances and a StateMatrix
. Both of these structures are complementary, meaning that any change in one in synched in the other. While AtomState
instances hold both the internal and cartesian coordinates relative to a single Atom
, StateMatrix
is a 2D matrix of all cartesian coordinates of the atoms in a given Pose.
ProtoSyn.State
— TypeState([::T]) where {T <: AbstractFloat}
A State
is a complete representation of a given molecular system regarding the position, the forces felt and the resulting energetic contribution by each atom. Each AtomState
in a system.
State([::T], n::Int) where {T <: AbstractFloat}
Return a State
with size n
, with all items
set to be an empty AtomState
.
State([::T], items::Vector{AtomState{T}}) where {T <: AbstractFloat}
Return a State
with size length(items)
, with all the given items
.
If no type T <: AbstractFloat
is provided, Units.defaultFloat
will be used.
Fields
items::Vector{AtomState{T}}
- The list ofAtomState
instances in thisState
(default: empty)size::Int
- The number ofAtomState
instances in thisState
(default: 0)id::Int
- The Id (to be matched to the correspondingTopology
in aPose
) (default: -1)i2c::Bool
- Flag indicating thisState
needs to be synched to cartesian coordinates (default: false)c2i::Bool
- Flag indicating thisState
needs to be synched to internal coordinates (default: false)index_offset::Int
- Ignore the first NAtomState
instances (default: 3)x::StateMatrix{T}
- The cartesian coordinate matrix of allAtomState
instances in thisState
(default: empty)f::Matrix{T}
- The force matrix of allAtomState
instances in thisState
(default: empty)e::Dict{Symbol, T}
- The list of all energetic components evaluated for thisState
(default: empty)
See also
Topology
AtomState
StateMatrix
Examples
julia> State(4)
State{Float64}:
Size: 4
i2c: false | c2i: false
Energy: Dict(:Total => Inf)
ProtoSyn.AtomState
— TypeAtomState{T}(parent::Any, index::Int, t::MVector{3, T}, r::MMatrix{3, 3, T, 9}, b::T, θ::T, ϕ::T, δ::T, Δϕ::T, changed::Bool) where {T <: AbstractFloat}
An AtomState
instance. Holds information regarding the state of the atom, including the cartesian and internal coordinates.
AtomState([::T]) where {T <: AbstractFloat}
Return an empty AtomState
instance, with all default values.
If no type T <: AbstractFloat
is provided, Units.defaultFloat
will be used.
Changing this AtomState
cartesian coordinates will update and sync changes with a sibling StateMatrix
, as long as this structs parent
is correctly set.
Fields
parent::Any
- If set, should point to the parentState
containing thisAtomState
(default: nothing)index::Int
- the index of thisAtomState
t::MVector{3, T}
- The translation vector from origin (cartesian coordinates) (default: empty)r::MMatrix{3, 3, T, 9}
- The rotation matrix for cartesian to internal coordinate sync (default: empty)b::T
- Distance (in Angstrom Å) to parent atom (default: 0)θ::T
- Angle (in radians) to ascendent atoms (default: 0)ϕ::T
- Dihedral angle (in radians) to ascendent atoms (default: 0)δ::T
- Atomic partial charge (default: 0.0)Δϕ::T
- Dihedral angle change (in radians) to be applied to children atoms (default: 0)changed::Bool
- Flag indicating whether thisAtomState
has been modified (useful in some functions such asi2c!
andc2i!
) (default: false)
The Δϕ
field in AtomState
allows for easy set-up of dihedral angles in molecular structures. By modifying Δϕ
in an atom, all child atoms will be rotated by the same amount, even in being branched structures.
See also
Examples
julia> AtomState()
AtomState{Float64}:
Index: -1
T: [0.000, 0.000, 0.000]
b: 0.000 Å | θ: 0.000 rad ( 0.00°) | ϕ: 0.000 rad ( 0.00°) | Δϕ: 0.000 rad ( 0.00°)
δ: 0.000
Changed: false
ProtoSyn.StateMatrix
— TypeStateMatrix{T}(parent::Any, coords::Matrix{T}) where {T <: AbstractFloat}
A StateMatrix
instance holds the cartesian coordinates of all AtomState
instances in a State
. It is an overload of a Matrix
struct, and used to efficiently apply substantial changes to a system or a large number of atoms.
If no type T <: AbstractFloat
is provided, Units.defaultFloat
will be used.
Changing this StateMatrix
cartesian coordinates will update and sync changes with a sibling AtomState
, as long as this structs parent
is correctly set. In such case, the parent.c2i
flag is also set to true
.
Fields
parent::Any
- If set, should point to the parentState
containing thisStateMatrix
(default: nothing)coords::Matrix
- The cartesian coordinates matrix
See also
Examples
julia> StateMatrix(zeros(3, 3))
StateMatrix{Float64}:
Parent set: false
3×3 Matrix{Float64}:
0.0 0.0 0.0
0.0 0.0 0.0
0.0 0.0 0.0
Array of Structures vs Structure of Arrays
Given this organization of cartesian coordinates in a Pose, a decades old dilemma naturally emerges: should the data be organized in Array of Structures or in a Structure of Arrays. The differences are illustrated bellow:
- Structure of Arrays (SoA) - The main object is a single structure which holds a vector for each of the coordinates of all
Atom
instances. Each coordinate vector of allAtom
instances is contiguous in memory. - Array of Structures (AoS) - The main object is a vector of
Atom
instances, where eachAtom
structure holds a field for each coordinate. EachAtom
set of coordinates is contiguous in memory.
Figure 1 | Visualization of Atom
instances organization in memory: Structure of Arrays (SoA) vs Array of Structures (AoS). In one hand, when employing the Structure of Arrays (SoA) paradigm, memory is contiguous when accessing all the X coordinates of each Atom
instance (for example). On the other hand, when employing the Array of Structures (AoS) paradigm, memory is contiguous when accessing all the X, Y and Z coordinates of a single atom (or adjacently indexed atoms).
Given that Julia is a column major programming language and based on performance benchmarks during early development cycles, ProtoSyn is developed using the Array of Structures (AoS) paradigm (each State
contains an array of structures AtomState
).