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 — TypeFragmentA 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 theTopologyid::Int- The ID of theTopologyitems::Vector{Segment}- All theSegmentinstances in thisTopology(default: empty)size::Int- The number ofSegmentinstances in thisTopology(default: 0)root::Residue- The rootResidueof thisTopologycontainer::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 theSegmentid::Int- The ID of theSegmentindex::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 ofResidueinstances in thisSegment(default: empty)container::Opt{AbstractTopology}- An optional container for thisSegment(default:nothing)size::Int- The number ofResidueinstances 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 theResidueid::Int- The ID of theResidueindex::Int- The index of theResidue(default: same as:id)items::Vector{Atom}- A list ofAtominstances in thisResidue(default: empty)itemsbyname::Dict{String, Atom}- ADictobject containing a link to each of theAtominstances in thisResiduebsed on the:nameof theAtom(default: empty)container::Opt{AbstractSegment}- An optional container for thisResidue(default:nothing)size::Int- The number ofAtominstances in thisResidue(default: 0)visited::Bool- Check whether thisResiduehas been visited (used by a some functions) (default:false)parent::Opt{Residue}- Optionally, the parent of thisResiduein the directional graph (default:nothing)children::Vector{Residue}- Optionally, the list of childrenResidueinstances 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) <: AbstractStringA string overload to accomodate different known and expected denominations of certain residues ("HIS" == "HIE" for example).
Example
julia> ProtoSyn.ResidueName("HIS")
HISProtoSyn.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 theAtomid::Int- The ID of theAtomindex::Int- The index of theAtom(default: same as:id)symbol::String- The chemical element symbol of thisAtombonds::Vector{Atom}- A list ofAtominstances connected to thisAtomby a bond (default: empty)container::Opt{AbstractResidue}- An optional container for thisAtom(default:nothing)visited::Bool- Check whether thisAtomhas been visited (used by a some functions) (default:false)parent::Opt{Atom}- Optionally, the parent of thisAtomin the directional graph (default:nothing)children::Vector{Atom}- Optionally, the list of childrenAtominstances 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 ofAtomStateinstances in thisState(default: empty)size::Int- The number ofAtomStateinstances in thisState(default: 0)id::Int- The Id (to be matched to the correspondingTopologyin aPose) (default: -1)i2c::Bool- Flag indicating thisStateneeds to be synched to cartesian coordinates (default: false)c2i::Bool- Flag indicating thisStateneeds to be synched to internal coordinates (default: false)index_offset::Int- Ignore the first NAtomStateinstances (default: 3)x::StateMatrix{T}- The cartesian coordinate matrix of allAtomStateinstances in thisState(default: empty)f::Matrix{T}- The force matrix of allAtomStateinstances 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 parentStatecontaining thisAtomState(default: nothing)index::Int- the index of thisAtomStatet::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 thisAtomStatehas 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: falseProtoSyn.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 parentStatecontaining 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.0Array 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
Atominstances. Each coordinate vector of allAtominstances is contiguous in memory. - Array of Structures (AoS) - The main object is a vector of
Atominstances, where eachAtomstructure holds a field for each coordinate. EachAtomset 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).