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.PoseType
Pose{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

source

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.FragmentType
Fragment

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

fragment

source

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 graph

ProtoSyn.TopologyType
Topology <: 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 the Topology
  • id::Int - The ID of the Topology
  • items::Vector{Segment} - All the Segment instances in this Topology (default: empty)
  • size::Int - The number of Segment instances in this Topology (default: 0)
  • root::Residue - The root Residue of this Topology
  • container::Nothing - Used to identify the root Residue (default: nothing)
Note:

When in a Pose, both the Topology and the corresponding State need to share the same :id. This is used to identify situations where a change in one of this structures was not reflected on the other.

See also

root Segment

Examples

julia> top = Topology("UNK", 1)
Topology{/UNK:1}
source
ProtoSyn.SegmentType
Segment <: 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 the Segment
  • id::Int - The ID of the Segment
  • index::Int - The index of the Segment (default: same as :id)
  • code::Char - A 1-letter code for the chain (used in PDB formatting) (default: '?')
  • items::Vector{Residue} - A list of Residue instances in this Segment (default: empty)
  • container::Opt{AbstractTopology} - An optional container for this Segment (default: nothing)
  • size::Int - The number of Residue instances in this Segment (default: 0)

See also

Topology Residue

Examples

julia> res = Segment("UNK", 1)
Segment{/UNK:1}
source
ProtoSyn.ResidueType
Residue <: 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 the Residue
  • id::Int - The ID of the Residue
  • index::Int - The index of the Residue (default: same as :id)
  • items::Vector{Atom} - A list of Atom instances in this Residue (default: empty)
  • itemsbyname::Dict{String, Atom} - A Dict object containing a link to each of the Atom instances in this Residue bsed on the :name of the Atom (default: empty)
  • container::Opt{AbstractSegment} - An optional container for this Residue (default: nothing)
  • size::Int - The number of Atom instances in this Residue (default: 0)
  • visited::Bool - Check whether this Residue has been visited (used by a some functions) (default: false)
  • parent::Opt{Residue} - Optionally, the parent of this Residue in the directional graph (default: nothing)
  • children::Vector{Residue} - Optionally, the list of children Residue instances downstream of this Residue (default: empty)
  • ascedents::Opt{NTuple{4, Int}} - Optionally, the list of 4 ascendents, including this Residue (default: nothing)

See also

Segment Atom ascendents ResidueName

Examples

julia> res = Residue("UNK", 1)
Residue{/UNK:1}
source
Note:

Instead of defining Residue.name as a String, ProtoSyn uses a specific type (ResidueName) to accomodate specific conventions in aminoacid naming.

ProtoSyn.ResidueNameType
ResidueName(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
source
ProtoSyn.AtomType
Atom <: 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 the Atom
  • id::Int - The ID of the Atom
  • index::Int - The index of the Atom (default: same as :id)
  • symbol::String - The chemical element symbol of this Atom
  • bonds::Vector{Atom} - A list of Atom instances connected to this Atom by a bond (default: empty)
  • container::Opt{AbstractResidue} - An optional container for this Atom (default: nothing)
  • visited::Bool - Check whether this Atom has been visited (used by a some functions) (default: false)
  • parent::Opt{Atom} - Optionally, the parent of this Atom in the directional graph (default: nothing)
  • children::Vector{Atom} - Optionally, the list of children Atom instances downstream of this Atom (default: empty)
  • ascedents::Opt{NTuple{4, Int}} - Optionally, the list of 4 ascendents, including this Atom (default: nothing)

See also

Residue [ascendents]

Examples

julia> at = Atom("H1", 1, 1, "H")
Atom{/H1:1}
source

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.StateType
State([::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.

Note:

If no type T <: AbstractFloat is provided, Units.defaultFloat will be used.

Fields

  • items::Vector{AtomState{T}} - The list of AtomState instances in this State (default: empty)
  • size::Int - The number of AtomState instances in this State (default: 0)
  • id::Int - The Id (to be matched to the corresponding Topology in a Pose) (default: -1)
  • i2c::Bool - Flag indicating this State needs to be synched to cartesian coordinates (default: false)
  • c2i::Bool - Flag indicating this State needs to be synched to internal coordinates (default: false)
  • index_offset::Int - Ignore the first N AtomState instances (default: 3)
  • x::StateMatrix{T} - The cartesian coordinate matrix of all AtomState instances in this State (default: empty)
  • f::Matrix{T} - The force matrix of all AtomState instances in this State (default: empty)
  • e::Dict{Symbol, T} - The list of all energetic components evaluated for this State (default: empty)

See also

Topology AtomState StateMatrix

Examples

julia> State(4)
State{Float64}:
 Size: 4
 i2c: false | c2i: false
 Energy: Dict(:Total => Inf)
source
ProtoSyn.AtomStateType
AtomState{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.

Note:

If no type T <: AbstractFloat is provided, Units.defaultFloat will be used.

Note:

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 parent State containing this AtomState (default: nothing)
  • index::Int - the index of this AtomState
  • 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 this AtomState has been modified (useful in some functions such as i2c! and c2i!) (default: false)
Note:

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

State StateMatrix

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
source
ProtoSyn.StateMatrixType
StateMatrix{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.

Note:

If no type T <: AbstractFloat is provided, Units.defaultFloat will be used.

Note:

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 parent State containing this StateMatrix (default: nothing)
  • coords::Matrix - The cartesian coordinates matrix

See also

State AtomState

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
source

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 all Atom instances is contiguous in memory.
  • Array of Structures (AoS) - The main object is a vector of Atom instances, where each Atom structure holds a field for each coordinate. Each Atom set of coordinates is contiguous in memory.

ProtoSyn Energy Function

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).