From e6e32a85931efeff56d8d50d14dd39340f5ca847 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Sat, 29 Jul 2023 13:17:19 +0000 Subject: [PATCH] build based on 52e0580 --- dev/contrib/index.html | 2 +- dev/examples/index.html | 2 +- dev/help/index.html | 14 +++++++------- dev/index.html | 4 ++-- dev/installation/index.html | 2 +- dev/mddf/index.html | 2 +- dev/multiple/index.html | 2 +- dev/options/index.html | 2 +- dev/parallel/index.html | 2 +- dev/python/index.html | 2 +- dev/quickguide/index.html | 2 +- dev/references/index.html | 2 +- dev/results/index.html | 2 +- dev/save/index.html | 2 +- dev/search/index.html | 2 +- dev/search_index.js | 2 +- dev/selection/index.html | 2 +- dev/tools/index.html | 2 +- dev/trajectory/index.html | 2 +- 19 files changed, 26 insertions(+), 26 deletions(-) diff --git a/dev/contrib/index.html b/dev/contrib/index.html index 3f9677f9..f0bd5494 100644 --- a/dev/contrib/index.html +++ b/dev/contrib/index.html @@ -47,4 +47,4 @@ neutral_contributions = contributions(solute,R.solute_atom,neutral_residues)

The charged and neutral outputs are vectors containing the contributions of these residues to the total MDDF. The corresponding plot is:

plot(results.d,results.mddf,label="Total MDDF",linewidth=2)
 plot!(results.d,charged_contributions,label="Charged residues",linewidth=2)
 plot!(results.d,neutral_contributions,label="Neutral residues",linewidth=2)
-plot!(xlabel="Distance / Å",ylabel="MDDF")

Resulting in:

Note here how charged residues contribute strongly to the peak at hydrogen-bonding distances, but much less in general. Of course all selection options could be used, to obtain the contributions of specific types of residues, atoms, the backbone, the side-chains, etc.

+plot!(xlabel="Distance / Å",ylabel="MDDF")

Resulting in:

Note here how charged residues contribute strongly to the peak at hydrogen-bonding distances, but much less in general. Of course all selection options could be used, to obtain the contributions of specific types of residues, atoms, the backbone, the side-chains, etc.

diff --git a/dev/examples/index.html b/dev/examples/index.html index 91832662..1452918c 100644 --- a/dev/examples/index.html +++ b/dev/examples/index.html @@ -68,4 +68,4 @@ output_file="grid.pdb", dmin=1.5, dmax=3.5 -)

The command above will generate the grid, save it to grid.pdb and let it available in the grid.pdb array of atoms, for further inspection, if desired.

By changing dmin, dmax, and step, one controls the grid size and resolution. This may generate very large output files.

+)

The command above will generate the grid, save it to grid.pdb and let it available in the grid.pdb array of atoms, for further inspection, if desired.

By changing dmin, dmax, and step, one controls the grid size and resolution. This may generate very large output files.

diff --git a/dev/help/index.html b/dev/help/index.html index a816192a..e1b27396 100644 --- a/dev/help/index.html +++ b/dev/help/index.html @@ -1,7 +1,7 @@ -Help entries · ComplexMixtures.jl

Help entries

ComplexMixtures.ChemFileType
struct ChemFile{T<:(AbstractVector)} <: Trajectory

Structure to contain a trajectory as read by Chemfiles.jl

  • filename::String

  • format::AbstractString

  • stream::ComplexMixtures.Stream{<:Chemfiles.Trajectory}

  • nframes::Int64

  • sides::Vector{T} where T<:(AbstractVector)

  • solute::Selection

  • solvent::Selection

  • x_solute::Vector{T} where T<:(AbstractVector)

  • x_solvent::Vector{T} where T<:(AbstractVector)

  • natoms::Int64

source
ComplexMixtures.ChemFileMethod
ChemFile(filename::String, solute::Selection, solvent::Selection;format="" , T::Type = SVector{3,Float64})

Function open will set up the IO stream of the trajectory, fill up the number of frames field and additional parameters if required.

source
ComplexMixtures.DensityType
mutable struct Density

Structure to contain the density values obtained from the calculation.

  • solute::Float64: Default: 0.0

  • solvent::Float64: Default: 0.0

  • solvent_bulk::Float64: Default: 0.0

source
ComplexMixtures.MinimumDistanceType
struct MinimumDistance

Internal structure or function, interface may change.

Extended help

This structure contains the information, for each molecule, of if it is within the cutoff distance of the solute, the atom indexes of the associated minimum distance, the distance, and a label to mark if the reference atom of the molecule is within the cutoff distance of the solute.

The lists of minimum-distances are stored in arrays of type Vector{MinimumDistance}. The index of this vector corresponds to the index of the molecule in the original array.

  • within_cutoff::Bool

  • i::Int64

  • j::Int64

  • d::Float64

  • ref_atom_within_cutoff::Bool

  • d_ref_atom::Float64

source
ComplexMixtures.NamdDCDType
struct NamdDCD{T<:(AbstractVector)} <: Trajectory

Structure to contain the data of a trajectory in NAMD/DCD format.

  • filename::String

  • stream::ComplexMixtures.Stream{<:FortranFiles.FortranFile}

  • nframes::Int64

  • sides::Vector{T} where T<:(AbstractVector)

  • solute::Selection

  • solvent::Selection

  • x_solute::Vector{T} where T<:(AbstractVector)

  • x_solvent::Vector{T} where T<:(AbstractVector)

  • sides_in_dcd::Bool

  • lastatom::Int64

  • sides_read::Vector{Float64}

  • x_read::Vector{Float32}

  • y_read::Vector{Float32}

  • z_read::Vector{Float32}

source
ComplexMixtures.NamdDCDMethod
NamdDCD(filename::String, solute::Selection, solvent::Selection;T::Type = SVector{3,Float64})

This function initializes the structure above, returning the data and the vectors with appropriate lengths.

source
ComplexMixtures.OptionsType
struct Options

Structure that contains the detailed input options.

  • firstframe::Int64: Default: 1

  • lastframe::Int64: Default: -1

  • stride::Int64: Default: 1

  • irefatom::Int64: Default: -1

  • n_random_samples::Int64: Default: 10

  • binstep::Float64: Default: 0.02

  • dbulk::Float64: Default: 10.0

  • cutoff::Float64: Default: 10.0

  • usecutoff::Bool: Default: false

  • lcell::Int64: Default: 1

  • GC::Bool: Default: true

  • GC_threshold::Float64: Default: 0.1

  • seed::Int64: Default: 321

  • StableRNG::Bool: Default: false

  • nthreads::Int64: Default: 0

  • silent::Bool: Default: false

source
ComplexMixtures.OutputFilesType

Internal structure or function, interface may change.

mutable struct OutputFiles

Structure to contain the names of the output files.

  • output::String

  • solute_atoms::String

  • solvent_atoms::String

source
ComplexMixtures.OverviewType

Internal structure or function, interface may change.

mutable struct Overview

Structure that is used to dispatch the show of a overview.

  • R::Result

  • domain_molar_volume::Float64: Default: 0.0

  • density::ComplexMixtures.Density: Default: Density()

  • solvent_molar_volume::Float64: Default: 0.0

  • solvent_molar_volume_bulk::Float64: Default: 0.0

  • solute_molar_volume::Float64: Default: 0.0

source
ComplexMixtures.PDBTrajType
struct PDBTraj{T<:(AbstractVector)} <: Trajectory

Structure to contain PDB trajectories. Frames must be separated by "END", and with periodic cell sizes in the "CRYST1" field.

This structure and functions can be used as a template to implement the reading of other trajectory formats.

  • filename::String

  • stream::ComplexMixtures.Stream{<:IOStream}

  • nframes::Int64

  • sides::Vector{T} where T<:(AbstractVector)

  • solute::Selection

  • solvent::Selection

  • x_solute::Vector{T} where T<:(AbstractVector)

  • x_solvent::Vector{T} where T<:(AbstractVector)

source
ComplexMixtures.PDBTrajMethod
PDBTraj(pdbfile::String, solute::Selection, solvent::Selection;T::Type = SVector{3,Float64})

Function open will set up the IO stream of the trajectory, fill up the number of frames field and additional parameters if required

source
ComplexMixtures.ResultType
mutable struct Result{T<:VecOrMat{Float64}}

Structure to contain the results of the MDDF calculation.

  • nbins::Int64

  • dbulk::Float64

  • cutoff::Float64

  • d::Vector{Float64}: Default: zeros(nbins)

  • md_count::Vector{Float64}: Default: zeros(nbins)

  • md_count_random::Vector{Float64}: Default: zeros(nbins)

  • coordination_number::Vector{Float64}: Default: zeros(nbins)

  • coordination_number_random::Vector{Float64}: Default: zeros(nbins)

  • mddf::Vector{Float64}: Default: zeros(nbins)

  • kb::Vector{Float64}: Default: zeros(nbins)

  • autocorrelation::Bool

  • solvent::ComplexMixtures.SolSummary

  • solute::ComplexMixtures.SolSummary

  • solute_atom::VecOrMat{Float64}: Default: zeros(nbins, solute.natomspermol)

  • solvent_atom::VecOrMat{Float64}: Default: zeros(nbins, solvent.natomspermol)

  • rdf_count::Vector{Float64}: Default: zeros(nbins)

  • rdf_count_random::Vector{Float64}: Default: zeros(nbins)

  • sum_rdf_count::Vector{Float64}: Default: zeros(nbins)

  • sum_rdf_count_random::Vector{Float64}: Default: zeros(nbins)

  • rdf::Vector{Float64}: Default: zeros(nbins)

  • kb_rdf::Vector{Float64}: Default: zeros(nbins)

  • density::ComplexMixtures.Density: Default: Density()

  • volume::ComplexMixtures.Volume: Default: Volume(nbins)

  • options::Options

  • irefatom::Int64

  • lastframe_read::Int64

  • nframes_read::Int64

  • files::Vector{String}

  • weights::Vector{Float64}

The Result{Vector{Float64}} parametric type is necessary only for reading the JSON3 saved file.

source
ComplexMixtures.SelectionType
struct Selection

Structure that contains the information about the solute and solvent molecules.

  • natoms::Int64

  • nmols::Int64

  • natomspermol::Int64

  • index::Vector{Int64}

  • imol::Vector{Int64}

  • names::Vector{String}

source
ComplexMixtures.SolSummaryType

Internal structure or function, interface may change.

struct SolSummary

Structures to contain the details of a solute or solvent to store in the results of the MDDF calculation.

  • natoms::Int64

  • nmols::Int64

  • natomspermol::Int64

source
ComplexMixtures.TrajectoryType
Trajectory(filename::String, solute::Selection, solvent::Selection; format::String = "", chemfiles = false)

Trajectory constructor data type.

Defaults to reading with the Chemfiles infrastructure, except for DCD and PDB trajectory files, if the "PDBTraj" option is provided.

See memory issue (https://github.com/chemfiles/Chemfiles.jl/issues/44)

source
ComplexMixtures.UnitsType

Internal structure or function, interface may change.

struct Units

Unit conversions.

  • mole::Any: Default: 6.022140857e23

  • Angs3tocm3::Any: Default: 1.0e24

  • Angs3toL::Any: Default: 1.0e27

  • Angs3tocm3permol::Any: Default: mole / Angs3tocm3

  • Angs3toLpermol::Any: Default: mole / Angs3toL

  • SitesperAngs3tomolperL::Any: Default: Angs3toL / mole

source
ComplexMixtures.VolumeType
mutable struct Volume

Structures to contain the volumes obtained from calculations.

  • total::Float64

  • bulk::Float64

  • domain::Float64

  • shell::Vector{Float64}

source
Base.isapproxMethod
Base.isapprox(r1::T, r2::T; debug=false) where T <: CMTypes

Internal structure or function, interface may change.

Function to test if two runs offered similar results. Mostly used in the package testing routines.

source
Base.mergeMethod
merge(r::Vector{Result})

This function merges the results of MDDF calculations obtained by running the same analysis on multiple trajectories, or multiple parts of the same trajectory. It returns a Result structure of the same type, with all the functions and counters representing averages of the set provided weighted by the number of frames read in each Result set.

source
Base.writeMethod
write(R::ComplexMixtures.Result, filename::String, solute::Selection, solvent::Selection)

Function to write the final results to output files as simple tables that are human-readable and easy to analyze with other software

If the solute and solvent selections are provides, pass on the atom names.

source
Base.writeMethod
write(R::ComplexMixtures.Result, filename::String; 
+Help entries · ComplexMixtures.jl

Help entries

ComplexMixtures.ChemFileType
struct ChemFile{T<:(AbstractVector)} <: Trajectory

Structure to contain a trajectory as read by Chemfiles.jl

  • filename::String

  • format::AbstractString

  • stream::ComplexMixtures.Stream{<:Chemfiles.Trajectory}

  • nframes::Int64

  • sides::Vector{T} where T<:(AbstractVector)

  • solute::Selection

  • solvent::Selection

  • x_solute::Vector{T} where T<:(AbstractVector)

  • x_solvent::Vector{T} where T<:(AbstractVector)

  • natoms::Int64

source
ComplexMixtures.ChemFileMethod
ChemFile(filename::String, solute::Selection, solvent::Selection;format="" , T::Type = SVector{3,Float64})

Function open will set up the IO stream of the trajectory, fill up the number of frames field and additional parameters if required.

source
ComplexMixtures.DensityType
mutable struct Density

Structure to contain the density values obtained from the calculation.

  • solute::Float64: Default: 0.0

  • solvent::Float64: Default: 0.0

  • solvent_bulk::Float64: Default: 0.0

source
ComplexMixtures.MinimumDistanceType
struct MinimumDistance

Internal structure or function, interface may change.

Extended help

This structure contains the information, for each molecule, of if it is within the cutoff distance of the solute, the atom indexes of the associated minimum distance, the distance, and a label to mark if the reference atom of the molecule is within the cutoff distance of the solute.

The lists of minimum-distances are stored in arrays of type Vector{MinimumDistance}. The index of this vector corresponds to the index of the molecule in the original array.

  • within_cutoff::Bool

  • i::Int64

  • j::Int64

  • d::Float64

  • ref_atom_within_cutoff::Bool

  • d_ref_atom::Float64

source
ComplexMixtures.NamdDCDType
struct NamdDCD{T<:(AbstractVector)} <: Trajectory

Structure to contain the data of a trajectory in NAMD/DCD format.

  • filename::String

  • stream::ComplexMixtures.Stream{<:FortranFiles.FortranFile}

  • nframes::Int64

  • sides::Vector{T} where T<:(AbstractVector)

  • solute::Selection

  • solvent::Selection

  • x_solute::Vector{T} where T<:(AbstractVector)

  • x_solvent::Vector{T} where T<:(AbstractVector)

  • sides_in_dcd::Bool

  • lastatom::Int64

  • sides_read::Vector{Float64}

  • x_read::Vector{Float32}

  • y_read::Vector{Float32}

  • z_read::Vector{Float32}

source
ComplexMixtures.NamdDCDMethod
NamdDCD(filename::String, solute::Selection, solvent::Selection;T::Type = SVector{3,Float64})

This function initializes the structure above, returning the data and the vectors with appropriate lengths.

source
ComplexMixtures.OptionsType
struct Options

Structure that contains the detailed input options.

  • firstframe::Int64: Default: 1

  • lastframe::Int64: Default: -1

  • stride::Int64: Default: 1

  • irefatom::Int64: Default: -1

  • n_random_samples::Int64: Default: 10

  • binstep::Float64: Default: 0.02

  • dbulk::Float64: Default: 10.0

  • cutoff::Float64: Default: 10.0

  • usecutoff::Bool: Default: false

  • lcell::Int64: Default: 1

  • GC::Bool: Default: true

  • GC_threshold::Float64: Default: 0.1

  • seed::Int64: Default: 321

  • StableRNG::Bool: Default: false

  • nthreads::Int64: Default: 0

  • silent::Bool: Default: false

source
ComplexMixtures.OutputFilesType

Internal structure or function, interface may change.

mutable struct OutputFiles

Structure to contain the names of the output files.

  • output::String

  • solute_atoms::String

  • solvent_atoms::String

source
ComplexMixtures.OverviewType

Internal structure or function, interface may change.

mutable struct Overview

Structure that is used to dispatch the show of a overview.

  • R::Result

  • domain_molar_volume::Float64: Default: 0.0

  • density::ComplexMixtures.Density: Default: Density()

  • solvent_molar_volume::Float64: Default: 0.0

  • solvent_molar_volume_bulk::Float64: Default: 0.0

  • solute_molar_volume::Float64: Default: 0.0

source
ComplexMixtures.PDBTrajType
struct PDBTraj{T<:(AbstractVector)} <: Trajectory

Structure to contain PDB trajectories. Frames must be separated by "END", and with periodic cell sizes in the "CRYST1" field.

This structure and functions can be used as a template to implement the reading of other trajectory formats.

  • filename::String

  • stream::ComplexMixtures.Stream{<:IOStream}

  • nframes::Int64

  • sides::Vector{T} where T<:(AbstractVector)

  • solute::Selection

  • solvent::Selection

  • x_solute::Vector{T} where T<:(AbstractVector)

  • x_solvent::Vector{T} where T<:(AbstractVector)

source
ComplexMixtures.PDBTrajMethod
PDBTraj(pdbfile::String, solute::Selection, solvent::Selection;T::Type = SVector{3,Float64})

Function open will set up the IO stream of the trajectory, fill up the number of frames field and additional parameters if required

source
ComplexMixtures.ResultType
mutable struct Result{T<:VecOrMat{Float64}}

Structure to contain the results of the MDDF calculation.

  • nbins::Int64

  • dbulk::Float64

  • cutoff::Float64

  • d::Vector{Float64}: Default: zeros(nbins)

  • md_count::Vector{Float64}: Default: zeros(nbins)

  • md_count_random::Vector{Float64}: Default: zeros(nbins)

  • coordination_number::Vector{Float64}: Default: zeros(nbins)

  • coordination_number_random::Vector{Float64}: Default: zeros(nbins)

  • mddf::Vector{Float64}: Default: zeros(nbins)

  • kb::Vector{Float64}: Default: zeros(nbins)

  • autocorrelation::Bool

  • solvent::ComplexMixtures.SolSummary

  • solute::ComplexMixtures.SolSummary

  • solute_atom::VecOrMat{Float64}: Default: zeros(nbins, solute.natomspermol)

  • solvent_atom::VecOrMat{Float64}: Default: zeros(nbins, solvent.natomspermol)

  • rdf_count::Vector{Float64}: Default: zeros(nbins)

  • rdf_count_random::Vector{Float64}: Default: zeros(nbins)

  • sum_rdf_count::Vector{Float64}: Default: zeros(nbins)

  • sum_rdf_count_random::Vector{Float64}: Default: zeros(nbins)

  • rdf::Vector{Float64}: Default: zeros(nbins)

  • kb_rdf::Vector{Float64}: Default: zeros(nbins)

  • density::ComplexMixtures.Density: Default: Density()

  • volume::ComplexMixtures.Volume: Default: Volume(nbins)

  • options::Options

  • irefatom::Int64

  • lastframe_read::Int64

  • nframes_read::Int64

  • files::Vector{String}

  • weights::Vector{Float64}

The Result{Vector{Float64}} parametric type is necessary only for reading the JSON3 saved file.

source
ComplexMixtures.SelectionType
struct Selection

Structure that contains the information about the solute and solvent molecules.

  • natoms::Int64

  • nmols::Int64

  • natomspermol::Int64

  • index::Vector{Int64}

  • imol::Vector{Int64}

  • names::Vector{String}

source
ComplexMixtures.SolSummaryType

Internal structure or function, interface may change.

struct SolSummary

Structures to contain the details of a solute or solvent to store in the results of the MDDF calculation.

  • natoms::Int64

  • nmols::Int64

  • natomspermol::Int64

source
ComplexMixtures.TrajectoryType
Trajectory(filename::String, solute::Selection, solvent::Selection; format::String = "", chemfiles = false)

Trajectory constructor data type.

Defaults to reading with the Chemfiles infrastructure, except for DCD and PDB trajectory files, if the "PDBTraj" option is provided.

See memory issue (https://github.com/chemfiles/Chemfiles.jl/issues/44)

source
ComplexMixtures.UnitsType

Internal structure or function, interface may change.

struct Units

Unit conversions.

  • mole::Any: Default: 6.022140857e23

  • Angs3tocm3::Any: Default: 1.0e24

  • Angs3toL::Any: Default: 1.0e27

  • Angs3tocm3permol::Any: Default: mole / Angs3tocm3

  • Angs3toLpermol::Any: Default: mole / Angs3toL

  • SitesperAngs3tomolperL::Any: Default: Angs3toL / mole

source
ComplexMixtures.VolumeType
mutable struct Volume

Structures to contain the volumes obtained from calculations.

  • total::Float64

  • bulk::Float64

  • domain::Float64

  • shell::Vector{Float64}

source
Base.isapproxMethod
Base.isapprox(r1::T, r2::T; debug=false) where T <: CMTypes

Internal structure or function, interface may change.

Function to test if two runs offered similar results. Mostly used in the package testing routines.

source
Base.mergeMethod
merge(r::Vector{Result})

This function merges the results of MDDF calculations obtained by running the same analysis on multiple trajectories, or multiple parts of the same trajectory. It returns a Result structure of the same type, with all the functions and counters representing averages of the set provided weighted by the number of frames read in each Result set.

source
Base.writeMethod
write(R::ComplexMixtures.Result, filename::String, solute::Selection, solvent::Selection)

Function to write the final results to output files as simple tables that are human-readable and easy to analyze with other software

If the solute and solvent selections are provides, pass on the atom names.

source
Base.writeMethod
write(R::ComplexMixtures.Result, filename::String; 
       solute_names::Vector{String} = ["nothing"], 
-      solvent_names::Vector{String} = ["nothing"])

Optional passing of atom names.

source
ComplexMixtures.VMDselectMethod
VMDselect(inputfile::String, selection::String; vmd="vmd" )

Select atoms using vmd selection syntax, with vmd in background

Returns the list of index (one-based) and atom names

Function to return the selection from a input file (topology, coordinates, etc), by calling VMD in the background.

source
ComplexMixtures.contributionsMethod
contributions(s::Selection, atom_contributions::Matrix{Float64}, selection)

Extract the contribution of a given atom type selection from the solute or solvent atomic contributions to the MDDF.

s here is the solute or solvent selection (type ComplexMixtures.Selection) atom_contributions is the R.solute_atom or R.solvent_atom arrays of the Result structure, and the last argument is the selection of atoms from the solute to be considered, given as a list of indexes, list of atom names, vector of PDBTools.Atoms, or a PDBTools.Residue.

Extended help

For selections of one molecule, the function has an additional keyword option first_atom_is_ref that is false by default. If set to true, the index first atom of the selection is considered as a reference atom. For example if a solute has 100 atoms, but its first atom in the PDB file is number 901, the selection of indexes [1, 2, 3] will refer to atoms with indexes [901, 902, 903].

source
ComplexMixtures.VMDselectMethod
VMDselect(inputfile::String, selection::String; vmd="vmd" )

Select atoms using vmd selection syntax, with vmd in background

Returns the list of index (one-based) and atom names

Function to return the selection from a input file (topology, coordinates, etc), by calling VMD in the background.

source
ComplexMixtures.contributionsMethod
contributions(s::Selection, atom_contributions::Matrix{Float64}, selection)

Extract the contribution of a given atom type selection from the solute or solvent atomic contributions to the MDDF.

s here is the solute or solvent selection (type ComplexMixtures.Selection) atom_contributions is the R.solute_atom or R.solvent_atom arrays of the Result structure, and the last argument is the selection of atoms from the solute to be considered, given as a list of indexes, list of atom names, vector of PDBTools.Atoms, or a PDBTools.Residue.

Extended help

For selections of one molecule, the function has an additional keyword option first_atom_is_ref that is false by default. If set to true, the index first atom of the selection is considered as a reference atom. For example if a solute has 100 atoms, but its first atom in the PDB file is number 901, the selection of indexes [1, 2, 3] will refer to atoms with indexes [901, 902, 903].

source
ComplexMixtures.coordination_numberMethod
coordination_number(R::Result) = R.coordination_number
 coordination_number(R::Result, group_contributions::Vector{Float64})
 coordination_number(s::Selection, atom_contributions::Matrix{Float64}, R::Result, group)

Computes the coordination number of a given group of atoms from the solute or solvent atomic contributions to the MDDF. If no group is defined (first call above), the coordination number of the whole solute or solvent is returned.

If the group_contributions to the mddf are computed previously with the contributions function, the result can be used to compute the coordination number by calling coordination_number(R::Result, group_contributions).

Otherwise, the coordination number can be computed directly with the second call, where:

s is the solute or solvent selection (type ComplexMixtures.Selection)

atom_contributions is the R.solute_atom or R.solvent_atom arrays of the Result structure

R is the Result structure,

and the last argument is the selection of atoms from the solute to be considered, given as a list of indexes, list of atom names, or a selection following the syntax of PDBTools, or vector of PDBTools.Atoms, or a PDBTools.Residue

Examples

In the following example we compute the coordination number of the atoms of residue 50 (of the solute) with the solvent atoms of TMAO, as a function of the distance. Finally, we show the average number of TMAO molecules within 5 Angstroms of residue 50. The findlast(<(5), R.d) part of the code below returns the index of the last element of the R.d array that is smaller than 5 Angstroms.

Precomputing the group contributions Using the contributions function

using ComplexMixtures, PDBTools
 pdb = readPDB("test/data/NAMD/structure.pdb");
@@ -21,7 +21,7 @@
 # Compute the coordination number
 residue50_coordination = coordination_number(solute, R.solute_atom, R, group)
 # Output the average number of TMAO molecules within 5 Angstroms of residue 50
-residue50_coordination[findlast(<(5), R.d)]
source
ComplexMixtures.eulermatMethod
eulermat(beta, gamma, theta, deg::String)

Internal structure or function, interface may change.

This routine was added because it defines the rotation in the "human" way, an is thus used to set the position of the fixed molecules. deg can only be "degree", in which case the angles with be considered in degrees. If no deg argument is provided, radians are used.

That means: beta is a counterclockwise rotation around x axis. gamma is a counterclockwise rotation around y axis. theta is a counterclockwise rotation around z axis.

source
ComplexMixtures.finalresults!Method
finalresults!(R::Result, options::Options, trajectory::Trajectory)

Internal structure or function, interface may change.

Function that computes the final results of all the data computed by averaging according to the sampling of each type of data, and converts to common units.

Computes also the final distribution functions and KB integrals.

This function modified the values contained in the R data structure.

source
ComplexMixtures.grMethod
gr(R::Result) = gr(R.d,R.rdf_count,R.density.solvent_bulk,R.options.binstep)

If a Result structure is provided without further details, use the rdf count and the bulk solvent density.

source
ComplexMixtures.grMethod
gr(r::Vector{Float64}, count::Vector{Float64}, density::Float64, binstep::Float64)

Computes the radial distribution function from the count data and the density.

This is exactly a conventional g(r) if a single atom was chosen as the solute and solvent selections.

Returns both the g(r) and the kb(r)

source
ComplexMixtures.grid3DMethod
grid3D(solute,solute_atoms,mddf_result,output_file; dmin=1.5, ddax=5.0, step=0.5)

This function builds the grid of the 3D density function and fills an array of mutable structures of type Atom, containing the position of the atoms of grid, the closest atom to that position, and distance.

solute is a ComplexMixtuers.Selection, defining the solute. solute_atoms is the corresponding vector of PDBTools.Atoms, and mddf_result is the result of a mddf_result calculation with the correspondign solute.

dmin and dmax define the range of distance where the density grid will be built, and step defines how fine the grid must be. Be aware that fine grids involve usually a very large (hundreds of thousands points).

All parameters can be provides as keyword parameters.

Example

julia> using ComplexMixtures, PDBTools
+residue50_coordination[findlast(<(5), R.d)]
source
ComplexMixtures.eulermatMethod
eulermat(beta, gamma, theta, deg::String)

Internal structure or function, interface may change.

This routine was added because it defines the rotation in the "human" way, an is thus used to set the position of the fixed molecules. deg can only be "degree", in which case the angles with be considered in degrees. If no deg argument is provided, radians are used.

That means: beta is a counterclockwise rotation around x axis. gamma is a counterclockwise rotation around y axis. theta is a counterclockwise rotation around z axis.

source
ComplexMixtures.finalresults!Method
finalresults!(R::Result, options::Options, trajectory::Trajectory)

Internal structure or function, interface may change.

Function that computes the final results of all the data computed by averaging according to the sampling of each type of data, and converts to common units.

Computes also the final distribution functions and KB integrals.

This function modified the values contained in the R data structure.

source
ComplexMixtures.grMethod
gr(R::Result) = gr(R.d,R.rdf_count,R.density.solvent_bulk,R.options.binstep)

If a Result structure is provided without further details, use the rdf count and the bulk solvent density.

source
ComplexMixtures.grMethod
gr(r::Vector{Float64}, count::Vector{Float64}, density::Float64, binstep::Float64)

Computes the radial distribution function from the count data and the density.

This is exactly a conventional g(r) if a single atom was chosen as the solute and solvent selections.

Returns both the g(r) and the kb(r)

source
ComplexMixtures.grid3DMethod
grid3D(solute,solute_atoms,mddf_result,output_file; dmin=1.5, ddax=5.0, step=0.5)

This function builds the grid of the 3D density function and fills an array of mutable structures of type Atom, containing the position of the atoms of grid, the closest atom to that position, and distance.

solute is a ComplexMixtuers.Selection, defining the solute. solute_atoms is the corresponding vector of PDBTools.Atoms, and mddf_result is the result of a mddf_result calculation with the correspondign solute.

dmin and dmax define the range of distance where the density grid will be built, and step defines how fine the grid must be. Be aware that fine grids involve usually a very large (hundreds of thousands points).

All parameters can be provides as keyword parameters.

Example

julia> using ComplexMixtures, PDBTools
 
 julia> pdb = readPDB("./system.pdb");
 
@@ -32,12 +32,12 @@
 julia> solute = ComplexMixtures.Selection(protein,nmols=1);
 
 julia> grid = ComplexMixtures.grid3D(solute=solute, solute_atoms=protein, mddf_result=R, output_file="grid.pdb");
-

grid will contain a vector of Atoms with the information of the MDDF at each grid point, and the same data will be written in the grid.pdb file. This PDB file can be opened in VMD, for example, and contain in the beta field the contribution of each protein residue to the MDDF at each point in space relative to the protein, and in the occupancy field the distance to the protein. Examples of how this information can be visualized are provided in the user guide of ComplexMixtures.

source
ComplexMixtures.itypeMethod
itype(iatom::Int, natomspermol::Int)

Internal structure or function, interface may change.

Given the index of the atom in the vector of coordinates of the solute or the solvent, returns the type of the atom, that is, the index of this atom within the molecule (goes from 1 to natomspermol)

source
ComplexMixtures.loadMethod
load(filename::String)

Function to load the json saved results file into the Result data structure.

source
ComplexMixtures.mddfFunction
mddf(trajectory::Trajectory, options::Options)

Function that computes the minimum-distance distribution function, atomic contributions, and KB integrals, given the Trajectory structure of the simulation and, optionally, parameters given as a second argument of the Options type. This is the main function of the ComplexMixtures package.

Examples

julia> trajectory = Trajectory("./trajectory.dcd",solute,solvent);
+

grid will contain a vector of Atoms with the information of the MDDF at each grid point, and the same data will be written in the grid.pdb file. This PDB file can be opened in VMD, for example, and contain in the beta field the contribution of each protein residue to the MDDF at each point in space relative to the protein, and in the occupancy field the distance to the protein. Examples of how this information can be visualized are provided in the user guide of ComplexMixtures.

source
ComplexMixtures.itypeMethod
itype(iatom::Int, natomspermol::Int)

Internal structure or function, interface may change.

Given the index of the atom in the vector of coordinates of the solute or the solvent, returns the type of the atom, that is, the index of this atom within the molecule (goes from 1 to natomspermol)

source
ComplexMixtures.loadMethod
load(filename::String)

Function to load the json saved results file into the Result data structure.

source
ComplexMixtures.mddfFunction
mddf(trajectory::Trajectory, options::Options)

Function that computes the minimum-distance distribution function, atomic contributions, and KB integrals, given the Trajectory structure of the simulation and, optionally, parameters given as a second argument of the Options type. This is the main function of the ComplexMixtures package.

Examples

julia> trajectory = Trajectory("./trajectory.dcd",solute,solvent);
 
 julia> results = mddf(trajectory);

or, to set some custom optional parameter,

julia> options = Options(lastframe=1000);
 
-julia> results = mddf(trajectory,options);
source
ComplexMixtures.mddf_frame!Method
mddf_frame!(R::Result, system::AbstractPeriodicSystem, buff::Buffer, options::Options, RNG)

Internal structure or function, interface may change.

Computes the MDDF for a single frame, for autocorrelation of molecules. Modifies the data in the R (type Result) structure.

source
ComplexMixtures.minimum_distances!Method
minimum_distances!(system::CellListMap.PeriodicSystem, R::Result)

Internal structure or function, interface may change.

Function that computes the list of distances of solvent molecules to a solute molecule. It updates the lists of minimum distances.

source
ComplexMixtures.mol_indexMethod
mol_index(i_atom, natomspermol) = (i_atom-1) ÷ natomspermol + 1

Internal structure or function, interface may change.

Extended help

Sets the index of the molecule of an atom in the simples situation, in which all molecules have the same number of atoms.

source
ComplexMixtures.mol_rangeMethod
mol_range(imol, n_atoms_per_molecule)

Internal structure or function, interface may change.

Given the index and the number of atoms per molecule, returns the range of indices of of an array of coordinates that corresponds to the molecule.

source
ComplexMixtures.move!Method
move!(x::AbstractVector, newcm::AbstractVector,beta, gamma, theta)

Internal structure or function, interface may change.

Translates and rotates a molecule according to the desired input center of coordinates and Euler rotations modifyies the vector x.

source
ComplexMixtures.mddf_frame!Method
mddf_frame!(R::Result, system::AbstractPeriodicSystem, buff::Buffer, options::Options, RNG)

Internal structure or function, interface may change.

Computes the MDDF for a single frame, for autocorrelation of molecules. Modifies the data in the R (type Result) structure.

source
ComplexMixtures.minimum_distances!Method
minimum_distances!(system::CellListMap.PeriodicSystem, R::Result)

Internal structure or function, interface may change.

Function that computes the list of distances of solvent molecules to a solute molecule. It updates the lists of minimum distances.

source
ComplexMixtures.mol_indexMethod
mol_index(i_atom, natomspermol) = (i_atom-1) ÷ natomspermol + 1

Internal structure or function, interface may change.

Extended help

Sets the index of the molecule of an atom in the simples situation, in which all molecules have the same number of atoms.

source
ComplexMixtures.mol_rangeMethod
mol_range(imol, n_atoms_per_molecule)

Internal structure or function, interface may change.

Given the index and the number of atoms per molecule, returns the range of indices of of an array of coordinates that corresponds to the molecule.

source
ComplexMixtures.move!Method
move!(x::AbstractVector, newcm::AbstractVector,beta, gamma, theta)

Internal structure or function, interface may change.

Translates and rotates a molecule according to the desired input center of coordinates and Euler rotations modifyies the vector x.

source
ComplexMixtures.random_move!Method
random_move!(x_ref::AbstractVector{T}, 
              irefatom::Int,
              system::AbstractPeriodicSystem,
-             x_new::AbstractVector{T}, RNG) where {T<:SVector}

Internal structure or function, interface may change.

Function that generates a new random position for a molecule.

The new position is returned in x_new, a previously allocated array.

source
ComplexMixtures.randomize_solvent!Method
randomize_solvent!(system, buff, n_solvent_in_bulk, options, RNG)

Internal structure or function, interface may change.

Generate a random solvent distribution from the bulk molecules of a solvent

source
ComplexMixtures.setbinMethod
setbin(d,step)

Internal structure or function, interface may change.

Function that sets to which histogram bin a data point pertains simple, but important to keep consistency over all calls.

source
ComplexMixtures.setup_PeriodicSystemMethod
setup_PeriodicSystem(trajectory::Trajectory, options::Options)

Internal structure or function, interface may change.

Setup the periodic system from CellListMap, to compute minimimum distances. The system will be setup such that xpositions corresponds to one molecule of the solute, and ypositions contains all coordinates of all atoms of the solvent.

source
ComplexMixtures.shellradiusMethod
shellradius(i,step)

Internal structure or function, interface may change.

Compute the point in which the radius comprises half of the volume of the shell.

source
ComplexMixtures.sphericalshellvolumeMethod
sphericalshellvolume(i,step)

Internal structure or function, interface may change.

Computes the volume of the spherical shell defined within [(i-1)step,istep].

source
ComplexMixtures.sum!Method
sum!(R1::Result, R2::Result)

Internal structure or function, interface may change.

Sum the counts of two Results structures, adding the result to the first structure as in R1 = R1 + R2.

source
ComplexMixtures.titleMethod
title(R::Result, solute::Selection, solvent::Selection)
-title(R::Result, solute::Selection, solvent::Selection, nspawn::Int)

Internal structure or function, interface may change.

Print some information about the run.

source
ComplexMixtures.update_list!Method
update_list!(i, j, d2, iref_atom::Int, mol_index_i::F, isolute::Int, list::Vector{MinimumDistance{T}}) where {F<:Function, T}

Internal structure or function, interface may change.

Function that updates a list of minimum distances given the indexes of the atoms involved for one pair within cutoff, for autocorrelations (such that the identity of isolute is needed)

source
ComplexMixtures.update_list!Method
update_list!(i, j, d2, iref_atom::Int, mol_index_i::F, list::Vector{MinimumDistance{T}}) where {F<:Function, T}

Internal structure or function, interface may change.

Function that updates a list of minimum distances given the indexes of the atoms involved for one pair within cutoff.

source
ComplexMixtures.update_mdMethod
update_md(md1::MinimumDistance{T}, md2::MinimumDistance{T}) where {T}

Internal structure or function, interface may change.

Function that returns the updated minimum distance structure after comparing two structures associated with the same molecule.

source
ComplexMixtures.updatecounters!Method
updatecounters!(R::Result, system::AbstractPeriodicSystem)

Internal structure or function, interface may change.

Function that updates the minimum-distance counters in R

source
ComplexMixtures.viewmolMethod
viewmol(i::Int, x::Vector{T}, n::Int) where T

Internal structure or function, interface may change.

Returns a view of a coordinate vector corresponding to the atoms of a molecule with index i. n is the number of atoms of the molecule.

source
ComplexMixtures.which_typesMethod
which_types(s::Selection, indexes::Vector{Int})

Internal structure or function, interface may change.

Function that returns the list of the indexes of the types of the atoms in a selection. For example, if a selection corresponds to a solvent of water molecules: There are three types, 1, 2, and 3, corresponding to the three atoms of the water molecule. If the indexes provided are, for instance, 11, 12, and 13, corresponding to a water molecule, this function will return 1, 2 and 3.

This is used to get equivalent-atom contributions to the distribution functions. For example, the input indexes span all water molecules, the output of this function will be still the three indexes corresponding to the three types of atoms that exist in a water molecule.

It is not possible to compute the contribution of one individual water molecule if the distribution function was computed for all molecules. Thus, the necessity to identify the types of atoms involved in a selection.

source
ComplexMixtures.writexyzMethod
writexyz(x::Vector{T}, file::String) where T <: AbstractVector

Internal structure or function, interface may change.

Print test xyz file.

source
+ x_new::AbstractVector{T}, RNG) where {T<:SVector}

Internal structure or function, interface may change.

Function that generates a new random position for a molecule.

The new position is returned in x_new, a previously allocated array.

source
ComplexMixtures.randomize_solvent!Method
randomize_solvent!(system, buff, n_solvent_in_bulk, options, RNG)

Internal structure or function, interface may change.

Generate a random solvent distribution from the bulk molecules of a solvent

source
ComplexMixtures.setbinMethod
setbin(d,step)

Internal structure or function, interface may change.

Function that sets to which histogram bin a data point pertains simple, but important to keep consistency over all calls.

source
ComplexMixtures.setup_PeriodicSystemMethod
setup_PeriodicSystem(trajectory::Trajectory, options::Options)

Internal structure or function, interface may change.

Setup the periodic system from CellListMap, to compute minimimum distances. The system will be setup such that xpositions corresponds to one molecule of the solute, and ypositions contains all coordinates of all atoms of the solvent.

source
ComplexMixtures.shellradiusMethod
shellradius(i,step)

Internal structure or function, interface may change.

Compute the point in which the radius comprises half of the volume of the shell.

source
ComplexMixtures.sphericalshellvolumeMethod
sphericalshellvolume(i,step)

Internal structure or function, interface may change.

Computes the volume of the spherical shell defined within [(i-1)step,istep].

source
ComplexMixtures.sum!Method
sum!(R1::Result, R2::Result)

Internal structure or function, interface may change.

Sum the counts of two Results structures, adding the result to the first structure as in R1 = R1 + R2.

source
ComplexMixtures.titleMethod
title(R::Result, solute::Selection, solvent::Selection)
+title(R::Result, solute::Selection, solvent::Selection, nspawn::Int)

Internal structure or function, interface may change.

Print some information about the run.

source
ComplexMixtures.update_list!Method
update_list!(i, j, d2, iref_atom::Int, mol_index_i::F, isolute::Int, list::Vector{MinimumDistance{T}}) where {F<:Function, T}

Internal structure or function, interface may change.

Function that updates a list of minimum distances given the indexes of the atoms involved for one pair within cutoff, for autocorrelations (such that the identity of isolute is needed)

source
ComplexMixtures.update_list!Method
update_list!(i, j, d2, iref_atom::Int, mol_index_i::F, list::Vector{MinimumDistance{T}}) where {F<:Function, T}

Internal structure or function, interface may change.

Function that updates a list of minimum distances given the indexes of the atoms involved for one pair within cutoff.

source
ComplexMixtures.update_mdMethod
update_md(md1::MinimumDistance{T}, md2::MinimumDistance{T}) where {T}

Internal structure or function, interface may change.

Function that returns the updated minimum distance structure after comparing two structures associated with the same molecule.

source
ComplexMixtures.updatecounters!Method
updatecounters!(R::Result, system::AbstractPeriodicSystem)

Internal structure or function, interface may change.

Function that updates the minimum-distance counters in R

source
ComplexMixtures.viewmolMethod
viewmol(i::Int, x::Vector{T}, n::Int) where T

Internal structure or function, interface may change.

Returns a view of a coordinate vector corresponding to the atoms of a molecule with index i. n is the number of atoms of the molecule.

source
ComplexMixtures.which_typesMethod
which_types(s::Selection, indexes::Vector{Int})

Internal structure or function, interface may change.

Function that returns the list of the indexes of the types of the atoms in a selection. For example, if a selection corresponds to a solvent of water molecules: There are three types, 1, 2, and 3, corresponding to the three atoms of the water molecule. If the indexes provided are, for instance, 11, 12, and 13, corresponding to a water molecule, this function will return 1, 2 and 3.

This is used to get equivalent-atom contributions to the distribution functions. For example, the input indexes span all water molecules, the output of this function will be still the three indexes corresponding to the three types of atoms that exist in a water molecule.

It is not possible to compute the contribution of one individual water molecule if the distribution function was computed for all molecules. Thus, the necessity to identify the types of atoms involved in a selection.

source
ComplexMixtures.writexyzMethod
writexyz(x::Vector{T}, file::String) where T <: AbstractVector

Internal structure or function, interface may change.

Print test xyz file.

source
diff --git a/dev/index.html b/dev/index.html index 26c12bbe..133c8eaa 100644 --- a/dev/index.html +++ b/dev/index.html @@ -15,5 +15,5 @@

From differences in KB integrals among cossolvents, the Preferential Solvation parameter can be computed. This is an important parameter because it can be measured experimentally and is ultimately associated with the equilibrium thermodynamics of the solvation. In the following figure, we show that, for example, the preferential solvation of a protein in different folding states is dependent in a non-trivial way on the concentration of an ionic liquid in aqueous solutions.


-Kirkwood-Buff integrals of an ionic liquid solvating a protein in different conformational states.

-

In particular, the plot shows that besides being preferentially excluded from the protein surface at high concentrations in the native state, suggesting protein folding stabilization, the interactions with the protein in the denatured states are stronger, leading to denaturation at all concentrations.

References

See also

Seminar

Applications

+Preferential interaction parameters obtained for the solvation of a protein by ionic liquids.

+

In particular, the plot shows that besides being preferentially excluded from the protein surface at high concentrations in the native state, suggesting protein folding stabilization, the interactions with the protein in the denatured states are stronger, leading to denaturation at all concentrations.

References

See also

Seminar

Applications

diff --git a/dev/installation/index.html b/dev/installation/index.html index cd5042ec..137d3a3d 100644 --- a/dev/installation/index.html +++ b/dev/installation/index.html @@ -9,4 +9,4 @@ using Plots # etc ...

And the script can be run with julia -t auto script.jl (where -t auto allows for multi-threading), or included in julia with julia> include("./scritp.jl"), as described in the next section.

Tip

By loading the package with

using ComplexMixtures

the most common functions of the package become readily available by their direct name, for example mddf(...).

If you don't want to bring the functions into the scope of your script, use

import ComplexMixtures

Then, the functions of the package are called, for example, using ComplexMixtures.mddf(...). To avoid having to write ComplexMixtures all the time, define an accronym. For example:

import ComplexMixtures as CM
-CM.mddf(...)
+CM.mddf(...) diff --git a/dev/mddf/index.html b/dev/mddf/index.html index c21bac11..3ec545af 100644 --- a/dev/mddf/index.html +++ b/dev/mddf/index.html @@ -1,4 +1,4 @@ Computing the MDDF · ComplexMixtures.jl

Computing the Minimum-Distance Distribution Function

The main function of the ComplexMixtures package actually computes the MDDF between the solute and the solvent chosen.

It is run with the following command:

results = mddf(trajectory)  

The MDDF along with other results, like the corresponding KB integrals, are returned in the results data structure, which is described in the next section.

It is possible to tune several options of the calculation, by setting the Options data structure with user-defined values in advance. The most common parameters to be set by the user are probably dbulk and stride.

dbulk defines the distance from the solute above which the user believes that the reference solute molecule does not significantly anymore the structure of the solvent. The default value is 10 Angstroms, but for large solvent molecules this might not be enough. To increase dbulk, use:

options = Options(dbulk=15.)
 results = mddf(trajectory,options)

stride defines if some frames will be skip during the calculation (for speedup). For example, if stride=5, only one in five frames will be considered. Adjust stride with:

options = Options(stride=5)
-results = mddf(trajectory,options)

See the Options section for further details and other options to set.

+results = mddf(trajectory,options)

See the Options section for further details and other options to set.

diff --git a/dev/multiple/index.html b/dev/multiple/index.html index 8cffd77c..c1ce7a59 100644 --- a/dev/multiple/index.html +++ b/dev/multiple/index.html @@ -17,4 +17,4 @@ 0.5 0.25 0.25 -

It is not a bad idea to check if that is what you were expecting.

+

It is not a bad idea to check if that is what you were expecting.

diff --git a/dev/options/index.html b/dev/options/index.html index 9c853cb7..4fa19b92 100644 --- a/dev/options/index.html +++ b/dev/options/index.html @@ -1,3 +1,3 @@ Options · ComplexMixtures.jl

Options

There are some options to control what exactly is going to be computed to obtain the MDDF. These options can be defined by the user and passed to the mddf function, using, for example:

options = Options(lastframe=1000)
-results = mddf(trajectory,options)

Common options that the user might want to set:

firstframe: Integer, first frame of the trajectory to be considered.

lastframe: Integer, last frame of the trajectory to be considered.

stride: Integer, consider every stride frames, that is, if stride=5 only one in five frames will be considered.

binstep: Real, length of the bin step of the histograms, default = 0.02 Angstroms.

dbulk: Real, distance from which the solution is to be considered as a bulk solution, that is, where the presence of the solute does not affect the structure of the solution anymore. This parameter is important in particular for systems with a single solute molecule (a protein, for example), where the density of the solvent in the box is not the bulk density of the solvent, which must be computed independently. Default: 10 Angstroms.

cutoff: Real, the maximum distance to be considered in the construction of histograms. Default: 10 Angstroms.

usecutoff: true/false: If true, the cutoff distance might be different from dbulk and the density of the solvent in bulk will be estimated from the density within dbulk and cutoff. If false, the density of the solvent is estimated from the density outside dbulk by exclusion. Default: false.

Options that most users will probably never change:

irefatom: Integer, index of the reference atom in the solvent molecule used to compute the shell volumes and domain volumes in the Monte-Carlo volume estimates. The final rdf data is reported for this atom as well. By default, we choose the atom which is closer to the center of coordinates of the molecule, but any choice should be fine.

n_random_samples: Integer, how many samples of random molecules are generated for each solvent molecule to compute the shell volumes and random MDDF counts. Default: 10. Increase this only if you have short trajectory and want to obtain reproducible results for that short trajectory. For long trajectories (most desirable and common), this value can even be decreased to speed up the calculations.

seed: Seed for random number generator. If -1, the seed will be generated from the entropy of the system. If your results are dependent on the seed, is is probable that you do not have enough sampling. Mostly used for testing purposes. Two runs are only identical if ran with the same seed and in serial mode.

StableRNG (::Bool), defaults to false. Use a stable random number generator from the StableRNGs package, to produce identical runs on different architectures and Julia versions. Only used for testing.

nthreads: How many threads to use. By default, it will be the number of physical cores of the computer.

lcell: Integer, the cell length of the linked-cell method (actually the cell length is cutoff/lcell). Default: 1.

GC: Bool, force garbage collection, to avoid memory overflow. Default: true. That this might be required is probably a result of something that can vastly improved in memory management. This may slow down parallel runs significantly if the GC runs too often.

GC_threshold: Float64, minimum fraction of the total memory of the system required to force a GC run. That is, if GC_threshold=0.1, which is the default, every time the free memory becomes less or equal to 10% of the total memory available, a GC run occurs.

+results = mddf(trajectory,options)

Common options that the user might want to set:

firstframe: Integer, first frame of the trajectory to be considered.

lastframe: Integer, last frame of the trajectory to be considered.

stride: Integer, consider every stride frames, that is, if stride=5 only one in five frames will be considered.

binstep: Real, length of the bin step of the histograms, default = 0.02 Angstroms.

dbulk: Real, distance from which the solution is to be considered as a bulk solution, that is, where the presence of the solute does not affect the structure of the solution anymore. This parameter is important in particular for systems with a single solute molecule (a protein, for example), where the density of the solvent in the box is not the bulk density of the solvent, which must be computed independently. Default: 10 Angstroms.

cutoff: Real, the maximum distance to be considered in the construction of histograms. Default: 10 Angstroms.

usecutoff: true/false: If true, the cutoff distance might be different from dbulk and the density of the solvent in bulk will be estimated from the density within dbulk and cutoff. If false, the density of the solvent is estimated from the density outside dbulk by exclusion. Default: false.

Options that most users will probably never change:

irefatom: Integer, index of the reference atom in the solvent molecule used to compute the shell volumes and domain volumes in the Monte-Carlo volume estimates. The final rdf data is reported for this atom as well. By default, we choose the atom which is closer to the center of coordinates of the molecule, but any choice should be fine.

n_random_samples: Integer, how many samples of random molecules are generated for each solvent molecule to compute the shell volumes and random MDDF counts. Default: 10. Increase this only if you have short trajectory and want to obtain reproducible results for that short trajectory. For long trajectories (most desirable and common), this value can even be decreased to speed up the calculations.

seed: Seed for random number generator. If -1, the seed will be generated from the entropy of the system. If your results are dependent on the seed, is is probable that you do not have enough sampling. Mostly used for testing purposes. Two runs are only identical if ran with the same seed and in serial mode.

StableRNG (::Bool), defaults to false. Use a stable random number generator from the StableRNGs package, to produce identical runs on different architectures and Julia versions. Only used for testing.

nthreads: How many threads to use. By default, it will be the number of physical cores of the computer.

lcell: Integer, the cell length of the linked-cell method (actually the cell length is cutoff/lcell). Default: 1.

GC: Bool, force garbage collection, to avoid memory overflow. Default: true. That this might be required is probably a result of something that can vastly improved in memory management. This may slow down parallel runs significantly if the GC runs too often.

GC_threshold: Float64, minimum fraction of the total memory of the system required to force a GC run. That is, if GC_threshold=0.1, which is the default, every time the free memory becomes less or equal to 10% of the total memory available, a GC run occurs.

diff --git a/dev/parallel/index.html b/dev/parallel/index.html index 8abba4e4..7598055a 100644 --- a/dev/parallel/index.html +++ b/dev/parallel/index.html @@ -1,4 +1,4 @@ Parallel execution · ComplexMixtures.jl

Parallel execution

It is highly recommended to run MDDF calculations in parallel, using multiple processors of a single computer. To run the computation in parallel, initialize julia with the -t auto option:

julia -t auto

The computation will use a number of threads equal to the number of physical cores of the computer. The number of computation threads to be used can be set by the Options(nthreads=N) parameter, where N is an integer. Hyperthreading (using more threads than physical CPUs) usually does not provide a significant speedup, and can be detrimental in some cases.

To directly run a script in parallel, use:

julia -t auto example.jl
Note

The number of threads used for computation of the MDDF is the number of physical CPUs of the computer, which are obtained programmatically. Most times the use of hyper-threading is not beneficial. Adjust the number of threads with the Options(nthreads=N) parameter.

Warning

If the calculations get Killed by no apparent reason, that is probably because you are running out of memory because of the many parallel computations running. One way to alleviate this problem is to force garbage collection, using

options = Options(GC=true,GC_threshold=0.5)
 R = mddf(trajectory,options)
-

The GC_threshold=0.5 indicates that if the free memory is smaller than 50% of the total memory of the machine, a garbage-collection run will occur. The default parameters are GC=true and GC_threshold=0.1.

+

The GC_threshold=0.5 indicates that if the free memory is smaller than 50% of the total memory of the machine, a garbage-collection run will occur. The default parameters are GC=true and GC_threshold=0.1.

diff --git a/dev/python/index.html b/dev/python/index.html index b0f16d6e..96ae316a 100644 --- a/dev/python/index.html +++ b/dev/python/index.html @@ -68,4 +68,4 @@ plt.plot(results.d, aliph_contributions) plt.xlabel("distance / Angs") plt.ylabel("MDDF") -plt.savefig("group_contributions.png")
Note

The syntax here diverges from the Julia-only examples by requiring the lists of names to be converted to Julia arrays, which happens by using the cm.list(python_list) function calls.

+plt.savefig("group_contributions.png")
Note

The syntax here diverges from the Julia-only examples by requiring the lists of names to be converted to Julia arrays, which happens by using the cm.list(python_list) function calls.

diff --git a/dev/quickguide/index.html b/dev/quickguide/index.html index f0460fed..154f94e2 100644 --- a/dev/quickguide/index.html +++ b/dev/quickguide/index.html @@ -46,4 +46,4 @@

The Kirkwood-Buff integral corresponding to that distribution is provided in the results.kb vector, and can be also directly plotted with

plot(results.d,results.kb,xlabel="d / \AA",ylabel="MDDF") 

to obtain:

-

See the Atomic and group contributions section for a detailed account on how to obtain a molecular picture of the solvation by splitting the MDDF in the contributions of each type of atom of the solvent, each type of residue of the protein, etc.

Save the results

The results can be saved into a file (with JSON format) with:

save(results,"./results.json")

And these results can be loaded afterwards with:

load("./results.json")

Alternatively, a human-readable set of output files can be obtained to be analyzed in other software (or plotted with alternative tools), with

write(results,"./results.dat")
+

See the Atomic and group contributions section for a detailed account on how to obtain a molecular picture of the solvation by splitting the MDDF in the contributions of each type of atom of the solvent, each type of residue of the protein, etc.

Save the results

The results can be saved into a file (with JSON format) with:

save(results,"./results.json")

And these results can be loaded afterwards with:

load("./results.json")

Alternatively, a human-readable set of output files can be obtained to be analyzed in other software (or plotted with alternative tools), with

write(results,"./results.dat")
diff --git a/dev/references/index.html b/dev/references/index.html index 61930f2f..45f140a8 100644 --- a/dev/references/index.html +++ b/dev/references/index.html @@ -1,2 +1,2 @@ -References · ComplexMixtures.jl

References

Primary citations

If this package was useful to you, please cite the following papers:

  • L. Martínez, ComplexMixtures.jl: Investigating the structure of solutions of complex-shaped molecules from a solvent-shell perspective J. Mol. Liq. 117945, 2021. [Full Text]

  • L. Martínez, S. Shimizu, Molecular interpretation of preferential interactions in protein solvation: a solvent-shell perspective by means of minimum-distance distribution functions. J. Chem. Theor. Comp. 13, 6358–6372, 2017. [Full Text]

Applications and examples

  • A. F. Pereira, V. Piccoli, L. Martínez, Trifluoroethanol direct interactions with protein backbones destabilize alpha-helices. J. Mol. Liq. 365, 120209, 2022. [Full Text]

  • V. Piccoli, L. Martínez, Ionic liquid solvation of proteins in native and denatured states. J. Mol. Liq. 363, 119953, 2022. [Full Text]

  • V. Piccoli, L. Martínez, Correlated counterion effects in the solvation of proteins by ionic-liquids. J. Mol. Liq. 320, 114347, 2020. [Full Text]

  • I. P. de Oliveira, L. Martínez, The shift in urea orientation at protein surfaces at low pH is compatible with a direct mechanism of protein denaturation. Phys. Chem. Chem. Phys. 22, 354-367, 2020. [Full Text]

  • I. P. de Oliveira, L. Martínez, Molecular basis for competitive solvation of the Burkholderia cepacia lipase by sorbitol and urea. Phys. Chem. Chem. Phys. 18, 21797-21808, 2016. [Full Text]

See also

  • Packmol: A package for building initial configurations for molecular dynamics simulations.

  • CellListMap.jl: Efficient and customizable implementation of cell lists, which allows the computation of general properties dependent on distances of particles within a cutoff, for example short-range potentials, forces, neighbour lists, etc.

  • MDLovoFit: Automatic identification of mobile and rigid substructures in molecular dynamics simulations and fractional structural fluctuation analysis.

+References · ComplexMixtures.jl

References

Primary citations

If this package was useful to you, please cite the following papers:

  • L. Martínez, ComplexMixtures.jl: Investigating the structure of solutions of complex-shaped molecules from a solvent-shell perspective J. Mol. Liq. 117945, 2021. [Full Text]

  • L. Martínez, S. Shimizu, Molecular interpretation of preferential interactions in protein solvation: a solvent-shell perspective by means of minimum-distance distribution functions. J. Chem. Theor. Comp. 13, 6358–6372, 2017. [Full Text]

Applications and examples

  • A. F. Pereira, V. Piccoli, L. Martínez, Trifluoroethanol direct interactions with protein backbones destabilize alpha-helices. J. Mol. Liq. 365, 120209, 2022. [Full Text]

  • V. Piccoli, L. Martínez, Ionic liquid solvation of proteins in native and denatured states. J. Mol. Liq. 363, 119953, 2022. [Full Text]

  • V. Piccoli, L. Martínez, Correlated counterion effects in the solvation of proteins by ionic-liquids. J. Mol. Liq. 320, 114347, 2020. [Full Text]

  • I. P. de Oliveira, L. Martínez, The shift in urea orientation at protein surfaces at low pH is compatible with a direct mechanism of protein denaturation. Phys. Chem. Chem. Phys. 22, 354-367, 2020. [Full Text]

  • I. P. de Oliveira, L. Martínez, Molecular basis for competitive solvation of the Burkholderia cepacia lipase by sorbitol and urea. Phys. Chem. Chem. Phys. 18, 21797-21808, 2016. [Full Text]

See also

  • Packmol: A package for building initial configurations for molecular dynamics simulations.

  • CellListMap.jl: Efficient and customizable implementation of cell lists, which allows the computation of general properties dependent on distances of particles within a cutoff, for example short-range potentials, forces, neighbour lists, etc.

  • MDLovoFit: Automatic identification of mobile and rigid substructures in molecular dynamics simulations and fractional structural fluctuation analysis.

diff --git a/dev/results/index.html b/dev/results/index.html index c1034f63..549499b9 100644 --- a/dev/results/index.html +++ b/dev/results/index.html @@ -21,4 +21,4 @@ ⋮ 0.72186381783 1.13624162115

A typical plot of results.kb as a function of results.d will look like:

Thus, this plot was obtained with the following code:

using Plots
-plot(results.d,results.kb,xlabel="d/A",ylabel="mddf(d) / L/mol") 

Units

Warning

If the coordinates are not in Å, the calculation will proceed normally, but the units of the KB integrals, which has units of volume per mol, should be converted to conform the length unit provided.

Coordination number and other data

Obtaining the MDDF involves the computation of some intermediate properties that are frequently useful for additional solution structure analysis. In particular, the coordination numbers are computed. For example, the coordination number as a function from the distance to the solute can be retrieved from a Results data structure with:

coordination_number = results.coordination_number

and this data can be plotted against the distances by:

plot(result.d,results.coordination_number)

The coordination number of subgroups can also be obtained, as explained in the Coordination number section.

The complete data available is:

ParameterMeaningType of valueComment
dVector of distances of the histograms.Vector{Float64}To be used as the x coordinate on plotting any of the data.
md_countNon-normalized count of minimum distances at each d.Vector{Float64}This is the number of minimum distances found at each histogram bin, without normalization. Usually this is not interesting to analyze, because it is dependent on the bin size.
md_count_randomNumber of minimum distances found at each histogram bin for the random distribution.Vector{Float64}This is the normalization required to convert the md_count array into the minimum-distance distribution.
coordination_numberCumulative number of sites found for each histogram distance.Vector{Float64}This is the coordination number, that is, the number of sites found cumulative up to each distance, without any normalization.
coordination_number_randomCumulative site count for the random distribution.Vector{Float64}Usually not interesting for analysis.
mddfThe final distribution function.Vector{Float64}This is the MDDF computed (md_count normalized by md_count_random). It is the main result of the calculation.
kbThe final Kirkwood-Buff integral.Vector{Float64}This is the final KB integral, as a function of the integration distance from the solute. Computed as coordination_number - coordination_number_random
solute_atomAtomic contributions of the solute.Matrix{Float64}This is a matrix with nbins lines and solute.natomspermol columns, containing the atomic contributions of each solute atom to the complete MDDF.
solvent_atomAtomic contributions of the solvent.Matrix{Float64}This is a matrix with nbins lines and solvent.natomspermol columns, containing the atomic contributions of each solvent atom to the complete MDDF.
density.soluteDensity (concentration) of the solute in the complete simulation box.Float64In units of molecules/$\textrm{\AA}^3$
density.solventDensity (concentration) of the solvent in the complete simulation box.Float64In units of molecules/$\textrm{\AA}^3$
density.solvent_bulkDensity (concentration) of the solute in the bulk region.Float64In units of molecules/$\textrm{\AA}^3$
volumeVolume measures.VolumeContains the total volume of the simulation, the bulk volume, the volume of the solute domain and the shell volume of each bin of the histogram. These are computed by numerical integration from the random distributions.
filesList of files read.Vector{String}
weightsWeights of each file in the final counts.Vector{Float64}If the trajectories have different lengths or number of frames, the weights are adapted accordingly.

Other Result parameters available which are set at Options:

ParameterMeaningType of valueComment
nbinsNumber of bins of the histograms.Int
dbulkDistance from solute of bulk solution.Float64
cutoffMaximum distance to be considered for histograms.Float64
autocorrelationThe solute is the same as the solvent?BoolAutomatically set if solute == solvent.
soluteProperties of the soluteSolSummaryContains the number of atoms, number of atoms per molecule and number of molecules of the solute.
solventProperties of the solvent.SolSummaryContains the number of atoms, number of atoms per molecule and number of molecules of the solvent.
irefatomThis is a reference atom that is used to generate random rotations and translations internally.IntCounts of the distributions for this atom are performed automatically to obtain radial (or proximal) distribution functions. Can be used for testing purposes.
rdf_countThis is the md_count minimum distance count of irefatom.Vector{Float64}This corresponds to the conventional radial distribution function if the solute contains only one atom.
rdf_count_randomMinimum distance of irefatom count for the random distribution.Vector{Float64}
rdfDistribution function computed from the irefatom distribution. It is a conventional rdf if the solvent has only one atom.Vector{Float64}
kb_rdfKirkwood-Buff integral computed from the irefatom distribution.Vector{Float64}This must converge, at long distances, to the same value as kb, and can be used for testing.
optionsCalculation options.OptionsCarries (some redundant) options set by the user.
lastframe_readLast frame read from the trajectory.Int
n_frames_readNumber of frames read from the trajectory.IntCan differ from lastframe_read if stride != 1
+plot(results.d,results.kb,xlabel="d/A",ylabel="mddf(d) / L/mol")

Units

Warning

If the coordinates are not in Å, the calculation will proceed normally, but the units of the KB integrals, which has units of volume per mol, should be converted to conform the length unit provided.

Coordination number and other data

Obtaining the MDDF involves the computation of some intermediate properties that are frequently useful for additional solution structure analysis. In particular, the coordination numbers are computed. For example, the coordination number as a function from the distance to the solute can be retrieved from a Results data structure with:

coordination_number = results.coordination_number

and this data can be plotted against the distances by:

plot(result.d,results.coordination_number)

The coordination number of subgroups can also be obtained, as explained in the Coordination number section.

The complete data available is:

ParameterMeaningType of valueComment
dVector of distances of the histograms.Vector{Float64}To be used as the x coordinate on plotting any of the data.
md_countNon-normalized count of minimum distances at each d.Vector{Float64}This is the number of minimum distances found at each histogram bin, without normalization. Usually this is not interesting to analyze, because it is dependent on the bin size.
md_count_randomNumber of minimum distances found at each histogram bin for the random distribution.Vector{Float64}This is the normalization required to convert the md_count array into the minimum-distance distribution.
coordination_numberCumulative number of sites found for each histogram distance.Vector{Float64}This is the coordination number, that is, the number of sites found cumulative up to each distance, without any normalization.
coordination_number_randomCumulative site count for the random distribution.Vector{Float64}Usually not interesting for analysis.
mddfThe final distribution function.Vector{Float64}This is the MDDF computed (md_count normalized by md_count_random). It is the main result of the calculation.
kbThe final Kirkwood-Buff integral.Vector{Float64}This is the final KB integral, as a function of the integration distance from the solute. Computed as coordination_number - coordination_number_random
solute_atomAtomic contributions of the solute.Matrix{Float64}This is a matrix with nbins lines and solute.natomspermol columns, containing the atomic contributions of each solute atom to the complete MDDF.
solvent_atomAtomic contributions of the solvent.Matrix{Float64}This is a matrix with nbins lines and solvent.natomspermol columns, containing the atomic contributions of each solvent atom to the complete MDDF.
density.soluteDensity (concentration) of the solute in the complete simulation box.Float64In units of molecules/$\textrm{\AA}^3$
density.solventDensity (concentration) of the solvent in the complete simulation box.Float64In units of molecules/$\textrm{\AA}^3$
density.solvent_bulkDensity (concentration) of the solute in the bulk region.Float64In units of molecules/$\textrm{\AA}^3$
volumeVolume measures.VolumeContains the total volume of the simulation, the bulk volume, the volume of the solute domain and the shell volume of each bin of the histogram. These are computed by numerical integration from the random distributions.
filesList of files read.Vector{String}
weightsWeights of each file in the final counts.Vector{Float64}If the trajectories have different lengths or number of frames, the weights are adapted accordingly.

Other Result parameters available which are set at Options:

ParameterMeaningType of valueComment
nbinsNumber of bins of the histograms.Int
dbulkDistance from solute of bulk solution.Float64
cutoffMaximum distance to be considered for histograms.Float64
autocorrelationThe solute is the same as the solvent?BoolAutomatically set if solute == solvent.
soluteProperties of the soluteSolSummaryContains the number of atoms, number of atoms per molecule and number of molecules of the solute.
solventProperties of the solvent.SolSummaryContains the number of atoms, number of atoms per molecule and number of molecules of the solvent.
irefatomThis is a reference atom that is used to generate random rotations and translations internally.IntCounts of the distributions for this atom are performed automatically to obtain radial (or proximal) distribution functions. Can be used for testing purposes.
rdf_countThis is the md_count minimum distance count of irefatom.Vector{Float64}This corresponds to the conventional radial distribution function if the solute contains only one atom.
rdf_count_randomMinimum distance of irefatom count for the random distribution.Vector{Float64}
rdfDistribution function computed from the irefatom distribution. It is a conventional rdf if the solvent has only one atom.Vector{Float64}
kb_rdfKirkwood-Buff integral computed from the irefatom distribution.Vector{Float64}This must converge, at long distances, to the same value as kb, and can be used for testing.
optionsCalculation options.OptionsCarries (some redundant) options set by the user.
lastframe_readLast frame read from the trajectory.Int
n_frames_readNumber of frames read from the trajectory.IntCan differ from lastframe_read if stride != 1
diff --git a/dev/save/index.html b/dev/save/index.html index af318785..425c76c4 100644 --- a/dev/save/index.html +++ b/dev/save/index.html @@ -1,2 +1,2 @@ -Save and load · ComplexMixtures.jl

Save and load results

Three functions serve the purpose of saving and loading the results obtained with ComplexMixtures:

Save data to recover it later

save(results,"results.json")

where results is the output data structure of the mddf() calculation, and results.json is the output file to be created. The file is written in JSON format, thus is not naturally human-readable.

Load saved data

results = load("results.json")

The load function reads the output of the save function above, and restores the results data structure.

Write data in a human-readable format

If you Want the results to be written as simple ASCII tables such that you can read them with another analysis program, plotting graphic, or just want to inspect the data visually, use:

write(results,"results.dat")

Three files will be created by this function:

results.dat: Contains the main results, as the MDDF and KB-integral data.

results-ATOM_CONTRIB_SOLVENT.dat: contains the contribution of each atom type of the solvent to the MDDF.

results-ATOM_CONTRIB_SOLUTE.dat: contains the contribution of each atom type of the solute to the MDDF.

+Save and load · ComplexMixtures.jl

Save and load results

Three functions serve the purpose of saving and loading the results obtained with ComplexMixtures:

Save data to recover it later

save(results,"results.json")

where results is the output data structure of the mddf() calculation, and results.json is the output file to be created. The file is written in JSON format, thus is not naturally human-readable.

Load saved data

results = load("results.json")

The load function reads the output of the save function above, and restores the results data structure.

Write data in a human-readable format

If you Want the results to be written as simple ASCII tables such that you can read them with another analysis program, plotting graphic, or just want to inspect the data visually, use:

write(results,"results.dat")

Three files will be created by this function:

results.dat: Contains the main results, as the MDDF and KB-integral data.

results-ATOM_CONTRIB_SOLVENT.dat: contains the contribution of each atom type of the solvent to the MDDF.

results-ATOM_CONTRIB_SOLUTE.dat: contains the contribution of each atom type of the solute to the MDDF.

diff --git a/dev/search/index.html b/dev/search/index.html index 7f3bcc4e..0d18188e 100644 --- a/dev/search/index.html +++ b/dev/search/index.html @@ -1,2 +1,2 @@ -Search · ComplexMixtures.jl

Loading search...

    +Search · ComplexMixtures.jl

    Loading search...

      diff --git a/dev/search_index.js b/dev/search_index.js index a76bcc24..fc7a3f4d 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"references/#References","page":"References","title":"References","text":"","category":"section"},{"location":"references/#Primary-citations","page":"References","title":"Primary citations","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"If this package was useful to you, please cite the following papers:","category":"page"},{"location":"references/","page":"References","title":"References","text":"L. Martínez, ComplexMixtures.jl: Investigating the structure of solutions of complex-shaped molecules from a solvent-shell perspective J. Mol. Liq. 117945, 2021. [Full Text]\nL. Martínez, S. Shimizu, Molecular interpretation of preferential interactions in protein solvation: a solvent-shell perspective by means of minimum-distance distribution functions. J. Chem. Theor. Comp. 13, 6358–6372, 2017. [Full Text]","category":"page"},{"location":"references/#Applications-and-examples","page":"References","title":"Applications and examples","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"A. F. Pereira, V. Piccoli, L. Martínez, Trifluoroethanol direct interactions with protein backbones destabilize alpha-helices. J. Mol. Liq. 365, 120209, 2022. [Full Text]\nV. Piccoli, L. Martínez, Ionic liquid solvation of proteins in native and denatured states. J. Mol. Liq. 363, 119953, 2022. [Full Text]\nV. Piccoli, L. Martínez, Correlated counterion effects in the solvation of proteins by ionic-liquids. J. Mol. Liq. 320, 114347, 2020. [Full Text]\nI. P. de Oliveira, L. Martínez, The shift in urea orientation at protein surfaces at low pH is compatible with a direct mechanism of protein denaturation. Phys. Chem. Chem. Phys. 22, 354-367, 2020. [Full Text]\nI. P. de Oliveira, L. Martínez, Molecular basis for competitive solvation of the Burkholderia cepacia lipase by sorbitol and urea. Phys. Chem. Chem. Phys. 18, 21797-21808, 2016. [Full Text]","category":"page"},{"location":"references/#See-also","page":"References","title":"See also","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Packmol: A package for building initial configurations for molecular dynamics simulations.\nCellListMap.jl: Efficient and customizable implementation of cell lists, which allows the computation of general properties dependent on distances of particles within a cutoff, for example short-range potentials, forces, neighbour lists, etc.\nMDLovoFit: Automatic identification of mobile and rigid substructures in molecular dynamics simulations and fractional structural fluctuation analysis. ","category":"page"},{"location":"results/#results","page":"Results","title":"Results","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The results of a MDDF calculation are returned in a data structure which contains the MDDF, KB integrals, and atomic contributions. The following section will assume that the computation was performed by calling the mddf function with ","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"results = mddf(trajectory)","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"such that the results variable contain the Result data structure. By default, the histograms contain 500 bins (binstep=0.002 and cutoff=10.) such that all data-vectors will contain 500 lines.","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"To learn how to save and load saved data, read the next section.","category":"page"},{"location":"results/#The-Result-data-structure:-main-data","page":"Results","title":"The Result data structure: main data","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The most important data to be read from results are the distances, minimum-distance distribution function, and KB integrals. These data is stored in the following vectors:","category":"page"},{"location":"results/#Distances-of-the-histograms:-results.d","page":"Results","title":"Distances of the histograms: results.d","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The following vector will contain values ranging from 0. to cutoff, and the distance at each bin is the distance in that bin for which half of the volume of the bin is within d, and half of the volume is above d, if the volume was spherical: ","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"julia> results.d\n500-element Array{Float64,1}:\n 0.015874010519682\n 0.033019272488946275\n ⋮\n 9.970010030080179\n 9.99001000999998","category":"page"},{"location":"results/#Minimum-distance-distribution-function:-results.mddf","page":"Results","title":"Minimum-distance distribution function: results.mddf","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The results.mddf vector will contain the main result, which the minimum-distance distribution function. For a properly-sampled simulation, it will be zero at very short distances and converge to 1.0 for distances smaller than the cutoff:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"julia> results.mddf\n500-element Array{Float64,1}:\n 0.0\n 0.0\n ⋮\n 0.999052514965403\n 1.001030818286187\n","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"A typical plot of results.mddf as a function of results.d will look like:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"Thus, this plot was obtained with the following code:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"using Plots\nplot(results.d,results.mddf,xlabel=\"d/A\",ylabel=\"mddf(d) / L/mol\") ","category":"page"},{"location":"results/#Kirkwood-Buff-integral:-results.kb","page":"Results","title":"Kirkwood-Buff integral: results.kb","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The results.kb vector will contain the Kirkwood-Buff integral computed as a function of the minimum-distance to the solute. For properly sampled simulations, it is expected to converge at large distances. ","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"julia> results.kb\n500-element Array{Float64,1}:\n 0.0\n -0.3249356504752985\n -2.9804719721525\n ⋮\n 0.72186381783\n 1.13624162115","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"A typical plot of results.kb as a function of results.d will look like:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"Thus, this plot was obtained with the following code:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"using Plots\nplot(results.d,results.kb,xlabel=\"d/A\",ylabel=\"mddf(d) / L/mol\") ","category":"page"},{"location":"results/#Units","page":"Results","title":"Units","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The distance is assumed to be in Å, as this is the most common distance units in molecular simulations. The coordinates of the atoms are assumed be provided in Å. \nThe minimum-distance distribution function is unit-less, since it is the ratio of the density at each distance divided by an ideal-gas density.\nThe Kirkwood-Buff integrals are returned in cm³ mol⁻¹, if the coordinates were provided in Å.","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"warning: Warning\nIf the coordinates are not in Å, the calculation will proceed normally, but the units of the KB integrals, which has units of volume per mol, should be converted to conform the length unit provided. ","category":"page"},{"location":"results/#Coordination-number-and-other-data","page":"Results","title":"Coordination number and other data","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"Obtaining the MDDF involves the computation of some intermediate properties that are frequently useful for additional solution structure analysis. In particular, the coordination numbers are computed. For example, the coordination number as a function from the distance to the solute can be retrieved from a Results data structure with:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"coordination_number = results.coordination_number","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"and this data can be plotted against the distances by:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"plot(result.d,results.coordination_number)","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"The coordination number of subgroups can also be obtained, as explained in the Coordination number section.","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"The complete data available is:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"Parameter Meaning Type of value Comment\nd Vector of distances of the histograms. Vector{Float64} To be used as the x coordinate on plotting any of the data.\nmd_count Non-normalized count of minimum distances at each d. Vector{Float64} This is the number of minimum distances found at each histogram bin, without normalization. Usually this is not interesting to analyze, because it is dependent on the bin size.\nmd_count_random Number of minimum distances found at each histogram bin for the random distribution. Vector{Float64} This is the normalization required to convert the md_count array into the minimum-distance distribution.\ncoordination_number Cumulative number of sites found for each histogram distance. Vector{Float64} This is the coordination number, that is, the number of sites found cumulative up to each distance, without any normalization.\ncoordination_number_random Cumulative site count for the random distribution. Vector{Float64} Usually not interesting for analysis.\nmddf The final distribution function. Vector{Float64} This is the MDDF computed (md_count normalized by md_count_random). It is the main result of the calculation.\nkb The final Kirkwood-Buff integral. Vector{Float64} This is the final KB integral, as a function of the integration distance from the solute. Computed as coordination_number - coordination_number_random\nsolute_atom Atomic contributions of the solute. Matrix{Float64} This is a matrix with nbins lines and solute.natomspermol columns, containing the atomic contributions of each solute atom to the complete MDDF.\nsolvent_atom Atomic contributions of the solvent. Matrix{Float64} This is a matrix with nbins lines and solvent.natomspermol columns, containing the atomic contributions of each solvent atom to the complete MDDF.\ndensity.solute Density (concentration) of the solute in the complete simulation box. Float64 In units of molecules/textrmAA^3\ndensity.solvent Density (concentration) of the solvent in the complete simulation box. Float64 In units of molecules/textrmAA^3\ndensity.solvent_bulk Density (concentration) of the solute in the bulk region. Float64 In units of molecules/textrmAA^3\nvolume Volume measures. Volume Contains the total volume of the simulation, the bulk volume, the volume of the solute domain and the shell volume of each bin of the histogram. These are computed by numerical integration from the random distributions.\nfiles List of files read. Vector{String} \nweights Weights of each file in the final counts. Vector{Float64} If the trajectories have different lengths or number of frames, the weights are adapted accordingly.\n ","category":"page"},{"location":"results/#Other-Result-parameters-available-which-are-set-at-Options:","page":"Results","title":"Other Result parameters available which are set at Options:","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"Parameter Meaning Type of value Comment\nnbins Number of bins of the histograms. Int \ndbulk Distance from solute of bulk solution. Float64 \ncutoff Maximum distance to be considered for histograms. Float64 \nautocorrelation The solute is the same as the solvent? Bool Automatically set if solute == solvent.\nsolute Properties of the solute SolSummary Contains the number of atoms, number of atoms per molecule and number of molecules of the solute.\nsolvent Properties of the solvent. SolSummary Contains the number of atoms, number of atoms per molecule and number of molecules of the solvent.\nirefatom This is a reference atom that is used to generate random rotations and translations internally. Int Counts of the distributions for this atom are performed automatically to obtain radial (or proximal) distribution functions. Can be used for testing purposes.\nrdf_count This is the md_count minimum distance count of irefatom. Vector{Float64} This corresponds to the conventional radial distribution function if the solute contains only one atom.\nrdf_count_random Minimum distance of irefatom count for the random distribution. Vector{Float64} \nrdf Distribution function computed from the irefatom distribution. It is a conventional rdf if the solvent has only one atom. Vector{Float64} \nkb_rdf Kirkwood-Buff integral computed from the irefatom distribution. Vector{Float64} This must converge, at long distances, to the same value as kb, and can be used for testing.\noptions Calculation options. Options Carries (some redundant) options set by the user.\nlastframe_read Last frame read from the trajectory. Int \nn_frames_read Number of frames read from the trajectory. Int Can differ from lastframe_read if stride != 1\n ","category":"page"},{"location":"help/#Help-entries","page":"Help entries","title":"Help entries","text":"","category":"section"},{"location":"help/","page":"Help entries","title":"Help entries","text":"Modules=[ComplexMixtures]","category":"page"},{"location":"help/#ComplexMixtures.CMTypes","page":"Help entries","title":"ComplexMixtures.CMTypes","text":"Internal structure or function, interface may change.\n\nUnion of types to define an isaprox for testing.\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.ChemFile","page":"Help entries","title":"ComplexMixtures.ChemFile","text":"struct ChemFile{T<:(AbstractVector)} <: Trajectory\n\nStructure to contain a trajectory as read by Chemfiles.jl\n\nfilename::String\nformat::AbstractString\nstream::ComplexMixtures.Stream{<:Chemfiles.Trajectory}\nnframes::Int64\nsides::Vector{T} where T<:(AbstractVector)\nsolute::Selection\nsolvent::Selection\nx_solute::Vector{T} where T<:(AbstractVector)\nx_solvent::Vector{T} where T<:(AbstractVector)\nnatoms::Int64\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.ChemFile-Tuple{String, Selection, Selection}","page":"Help entries","title":"ComplexMixtures.ChemFile","text":"ChemFile(filename::String, solute::Selection, solvent::Selection;format=\"\" , T::Type = SVector{3,Float64})\n\nFunction open will set up the IO stream of the trajectory, fill up the number of frames field and additional parameters if required.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.Density","page":"Help entries","title":"ComplexMixtures.Density","text":"mutable struct Density\n\nStructure to contain the density values obtained from the calculation.\n\nsolute::Float64: Default: 0.0\nsolvent::Float64: Default: 0.0\nsolvent_bulk::Float64: Default: 0.0\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.MinimumDistance","page":"Help entries","title":"ComplexMixtures.MinimumDistance","text":"struct MinimumDistance\n\nInternal structure or function, interface may change.\n\nExtended help\n\nThis structure contains the information, for each molecule, of if it is within the cutoff distance of the solute, the atom indexes of the associated minimum distance, the distance, and a label to mark if the reference atom of the molecule is within the cutoff distance of the solute.\n\nThe lists of minimum-distances are stored in arrays of type Vector{MinimumDistance}. The index of this vector corresponds to the index of the molecule in the original array.\n\nwithin_cutoff::Bool\ni::Int64\nj::Int64\nd::Float64\nref_atom_within_cutoff::Bool\nd_ref_atom::Float64\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.NamdDCD","page":"Help entries","title":"ComplexMixtures.NamdDCD","text":"struct NamdDCD{T<:(AbstractVector)} <: Trajectory\n\nStructure to contain the data of a trajectory in NAMD/DCD format.\n\nfilename::String\nstream::ComplexMixtures.Stream{<:FortranFiles.FortranFile}\nnframes::Int64\nsides::Vector{T} where T<:(AbstractVector)\nsolute::Selection\nsolvent::Selection\nx_solute::Vector{T} where T<:(AbstractVector)\nx_solvent::Vector{T} where T<:(AbstractVector)\nsides_in_dcd::Bool\nlastatom::Int64\nsides_read::Vector{Float64}\nx_read::Vector{Float32}\ny_read::Vector{Float32}\nz_read::Vector{Float32}\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.NamdDCD-Tuple{String, Selection, Selection}","page":"Help entries","title":"ComplexMixtures.NamdDCD","text":"NamdDCD(filename::String, solute::Selection, solvent::Selection;T::Type = SVector{3,Float64})\n\nThis function initializes the structure above, returning the data and the vectors with appropriate lengths.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.Options","page":"Help entries","title":"ComplexMixtures.Options","text":"struct Options\n\nStructure that contains the detailed input options.\n\nfirstframe::Int64: Default: 1\nlastframe::Int64: Default: -1\nstride::Int64: Default: 1\nirefatom::Int64: Default: -1\nn_random_samples::Int64: Default: 10\nbinstep::Float64: Default: 0.02\ndbulk::Float64: Default: 10.0\ncutoff::Float64: Default: 10.0\nusecutoff::Bool: Default: false\nlcell::Int64: Default: 1\nGC::Bool: Default: true\nGC_threshold::Float64: Default: 0.1\nseed::Int64: Default: 321\nStableRNG::Bool: Default: false\nnthreads::Int64: Default: 0\nsilent::Bool: Default: false\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.OutputFiles","page":"Help entries","title":"ComplexMixtures.OutputFiles","text":"Internal structure or function, interface may change.\n\nmutable struct OutputFiles\n\nStructure to contain the names of the output files.\n\noutput::String\nsolute_atoms::String\nsolvent_atoms::String\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.Overview","page":"Help entries","title":"ComplexMixtures.Overview","text":"Internal structure or function, interface may change.\n\nmutable struct Overview\n\nStructure that is used to dispatch the show of a overview.\n\nR::Result\ndomain_molar_volume::Float64: Default: 0.0\ndensity::ComplexMixtures.Density: Default: Density()\nsolvent_molar_volume::Float64: Default: 0.0\nsolvent_molar_volume_bulk::Float64: Default: 0.0\nsolute_molar_volume::Float64: Default: 0.0\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.PDBTraj","page":"Help entries","title":"ComplexMixtures.PDBTraj","text":"struct PDBTraj{T<:(AbstractVector)} <: Trajectory\n\nStructure to contain PDB trajectories. Frames must be separated by \"END\", and with periodic cell sizes in the \"CRYST1\" field.\n\nThis structure and functions can be used as a template to implement the reading of other trajectory formats. \n\nfilename::String\nstream::ComplexMixtures.Stream{<:IOStream}\nnframes::Int64\nsides::Vector{T} where T<:(AbstractVector)\nsolute::Selection\nsolvent::Selection\nx_solute::Vector{T} where T<:(AbstractVector)\nx_solvent::Vector{T} where T<:(AbstractVector)\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.PDBTraj-Tuple{String, Selection, Selection}","page":"Help entries","title":"ComplexMixtures.PDBTraj","text":"PDBTraj(pdbfile::String, solute::Selection, solvent::Selection;T::Type = SVector{3,Float64})\n\nFunction open will set up the IO stream of the trajectory, fill up the number of frames field and additional parameters if required \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.Result","page":"Help entries","title":"ComplexMixtures.Result","text":"mutable struct Result{T<:VecOrMat{Float64}}\n\nStructure to contain the results of the MDDF calculation.\n\nnbins::Int64\ndbulk::Float64\ncutoff::Float64\nd::Vector{Float64}: Default: zeros(nbins)\nmd_count::Vector{Float64}: Default: zeros(nbins)\nmd_count_random::Vector{Float64}: Default: zeros(nbins)\ncoordination_number::Vector{Float64}: Default: zeros(nbins)\ncoordination_number_random::Vector{Float64}: Default: zeros(nbins)\nmddf::Vector{Float64}: Default: zeros(nbins)\nkb::Vector{Float64}: Default: zeros(nbins)\nautocorrelation::Bool\nsolvent::ComplexMixtures.SolSummary\nsolute::ComplexMixtures.SolSummary\nsolute_atom::VecOrMat{Float64}: Default: zeros(nbins, solute.natomspermol)\nsolvent_atom::VecOrMat{Float64}: Default: zeros(nbins, solvent.natomspermol)\nrdf_count::Vector{Float64}: Default: zeros(nbins)\nrdf_count_random::Vector{Float64}: Default: zeros(nbins)\nsum_rdf_count::Vector{Float64}: Default: zeros(nbins)\nsum_rdf_count_random::Vector{Float64}: Default: zeros(nbins)\nrdf::Vector{Float64}: Default: zeros(nbins)\nkb_rdf::Vector{Float64}: Default: zeros(nbins)\ndensity::ComplexMixtures.Density: Default: Density()\nvolume::ComplexMixtures.Volume: Default: Volume(nbins)\noptions::Options\nirefatom::Int64\nlastframe_read::Int64\nnframes_read::Int64\nfiles::Vector{String}\nweights::Vector{Float64}\n\nThe Result{Vector{Float64}} parametric type is necessary only for reading the JSON3 saved file. \n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.Selection","page":"Help entries","title":"ComplexMixtures.Selection","text":"struct Selection\n\nStructure that contains the information about the solute and solvent molecules.\n\nnatoms::Int64\nnmols::Int64\nnatomspermol::Int64\nindex::Vector{Int64}\nimol::Vector{Int64}\nnames::Vector{String}\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.SolSummary","page":"Help entries","title":"ComplexMixtures.SolSummary","text":"Internal structure or function, interface may change.\n\nstruct SolSummary\n\nStructures to contain the details of a solute or solvent to store in the results of the MDDF calculation.\n\nnatoms::Int64\nnmols::Int64\nnatomspermol::Int64\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.Trajectory","page":"Help entries","title":"ComplexMixtures.Trajectory","text":"Trajectory(filename::String, solute::Selection, solvent::Selection; format::String = \"\", chemfiles = false)\n\nTrajectory constructor data type. \n\nDefaults to reading with the Chemfiles infrastructure, except for DCD and PDB trajectory files, if the \"PDBTraj\" option is provided.\n\nSee memory issue (https://github.com/chemfiles/Chemfiles.jl/issues/44)\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.Units","page":"Help entries","title":"ComplexMixtures.Units","text":"Internal structure or function, interface may change.\n\nstruct Units\n\nUnit conversions.\n\nmole::Any: Default: 6.022140857e23\nAngs3tocm3::Any: Default: 1.0e24\nAngs3toL::Any: Default: 1.0e27\nAngs3tocm3permol::Any: Default: mole / Angs3tocm3\nAngs3toLpermol::Any: Default: mole / Angs3toL\nSitesperAngs3tomolperL::Any: Default: Angs3toL / mole\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.Volume","page":"Help entries","title":"ComplexMixtures.Volume","text":"mutable struct Volume\n\nStructures to contain the volumes obtained from calculations.\n\ntotal::Float64\nbulk::Float64\ndomain::Float64\nshell::Vector{Float64}\n\n\n\n\n\n","category":"type"},{"location":"help/#Base.isapprox-Union{Tuple{T}, Tuple{T, T}} where T<:Union{Options, ComplexMixtures.SolSummary, ComplexMixtures.Density, ComplexMixtures.Volume, Result}","page":"Help entries","title":"Base.isapprox","text":"Base.isapprox(r1::T, r2::T; debug=false) where T <: CMTypes\n\nInternal structure or function, interface may change.\n\nFunction to test if two runs offered similar results. Mostly used in the package testing routines.\n\n\n\n\n\n","category":"method"},{"location":"help/#Base.merge-Tuple{Vector{<:Result}}","page":"Help entries","title":"Base.merge","text":"merge(r::Vector{Result})\n\nThis function merges the results of MDDF calculations obtained by running the same analysis on multiple trajectories, or multiple parts of the same trajectory. It returns a Result structure of the same type, with all the functions and counters representing averages of the set provided weighted by the number of frames read in each Result set.\n\n\n\n\n\n","category":"method"},{"location":"help/#Base.write-Tuple{Result, String, Selection, Selection}","page":"Help entries","title":"Base.write","text":"write(R::ComplexMixtures.Result, filename::String, solute::Selection, solvent::Selection)\n\nFunction to write the final results to output files as simple tables that are human-readable and easy to analyze with other software\n\nIf the solute and solvent selections are provides, pass on the atom names.\n\n\n\n\n\n","category":"method"},{"location":"help/#Base.write-Tuple{Result, String}","page":"Help entries","title":"Base.write","text":"write(R::ComplexMixtures.Result, filename::String; \n solute_names::Vector{String} = [\"nothing\"], \n solvent_names::Vector{String} = [\"nothing\"])\n\nOptional passing of atom names.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.VMDselect-Tuple{String, String}","page":"Help entries","title":"ComplexMixtures.VMDselect","text":"VMDselect(inputfile::String, selection::String; vmd=\"vmd\" )\n\nSelect atoms using vmd selection syntax, with vmd in background\n\nReturns the list of index (one-based) and atom names\n\nFunction to return the selection from a input file (topology, coordinates, etc), by calling VMD in the background.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.contributions-Tuple{Selection, Matrix{Float64}, Vector{Int64}}","page":"Help entries","title":"ComplexMixtures.contributions","text":"contributions(s::Selection, atom_contributions::Matrix{Float64}, selection)\n\nExtract the contribution of a given atom type selection from the solute or solvent atomic contributions to the MDDF.\n\ns here is the solute or solvent selection (type ComplexMixtures.Selection) atom_contributions is the R.solute_atom or R.solvent_atom arrays of the Result structure, and the last argument is the selection of atoms from the solute to be considered, given as a list of indexes, list of atom names, vector of PDBTools.Atoms, or a PDBTools.Residue. \n\nExtended help\n\nFor selections of one molecule, the function has an additional keyword option first_atom_is_ref that is false by default. If set to true, the index first atom of the selection is considered as a reference atom. For example if a solute has 100 atoms, but its first atom in the PDB file is number 901, the selection of indexes [1, 2, 3] will refer to atoms with indexes [901, 902, 903].\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.coordination_number-Tuple{Selection, Matrix{Float64}, Result, Any}","page":"Help entries","title":"ComplexMixtures.coordination_number","text":"coordination_number(R::Result) = R.coordination_number\ncoordination_number(R::Result, group_contributions::Vector{Float64})\ncoordination_number(s::Selection, atom_contributions::Matrix{Float64}, R::Result, group)\n\nComputes the coordination number of a given group of atoms from the solute or solvent atomic contributions to the MDDF. If no group is defined (first call above), the coordination number of the whole solute or solvent is returned.\n\nIf the group_contributions to the mddf are computed previously with the contributions function, the result can be used to compute the coordination number by calling coordination_number(R::Result, group_contributions).\n\nOtherwise, the coordination number can be computed directly with the second call, where:\n\ns is the solute or solvent selection (type ComplexMixtures.Selection)\n\natom_contributions is the R.solute_atom or R.solvent_atom arrays of the Result structure\n\nR is the Result structure,\n\nand the last argument is the selection of atoms from the solute to be considered, given as a list of indexes, list of atom names, or a selection following the syntax of PDBTools, or vector of PDBTools.Atoms, or a PDBTools.Residue\n\nExamples\n\nIn the following example we compute the coordination number of the atoms of residue 50 (of the solute) with the solvent atoms of TMAO, as a function of the distance. Finally, we show the average number of TMAO molecules within 5 Angstroms of residue 50. The findlast(<(5), R.d) part of the code below returns the index of the last element of the R.d array that is smaller than 5 Angstroms.\n\nPrecomputing the group contributions Using the contributions function\n\nusing ComplexMixtures, PDBTools\npdb = readPDB(\"test/data/NAMD/structure.pdb\");\nR = load(\"test/data/NAMD/protein_tmao.json\");\nsolute = Selection(PDBTools.select(pdb, \"protein\"), nmols=1);\nresidue50 = PDBTools.select(pdb, \"residue 50\");\n# Compute the group contributions to the MDDF\nresidue50_contribution = contributions(solute, R.solute_atom, residue50);\n# Now compute the coordination number\nresidue50_coordination = coordination_number(R, residue50_contribution)\n# Output the average number of TMAO molecules within 5 Angstroms of residue 50\nresidue50_coordination[findlast(<(5), R.d)]\n\nWithout precomputing the group_contribution\n\nusing ComplexMixtures, PDBTools\npdb = readPDB(\"test/data/NAMD/structure.pdb\");\nR = load(\"test/data/NAMD/protein_tmao.json\");\nsolute = Selection(PDBTools.select(pdb, \"protein\"), nmols=1);\nresidue50 = PDBTools.select(pdb, \"residue 50\");\n# Compute the coordination number\nresidue50_coordination = coordination_number(solute, R.solute_atom, R, group)\n# Output the average number of TMAO molecules within 5 Angstroms of residue 50\nresidue50_coordination[findlast(<(5), R.d)]\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.eulermat-Tuple{Any, Any, Any, String}","page":"Help entries","title":"ComplexMixtures.eulermat","text":"eulermat(beta, gamma, theta, deg::String)\n\nInternal structure or function, interface may change.\n\nThis routine was added because it defines the rotation in the \"human\" way, an is thus used to set the position of the fixed molecules. deg can only be \"degree\", in which case the angles with be considered in degrees. If no deg argument is provided, radians are used.\n\nThat means: beta is a counterclockwise rotation around x axis. gamma is a counterclockwise rotation around y axis. theta is a counterclockwise rotation around z axis.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.finalresults!-Tuple{Result, Options, Trajectory}","page":"Help entries","title":"ComplexMixtures.finalresults!","text":"finalresults!(R::Result, options::Options, trajectory::Trajectory)\n\nInternal structure or function, interface may change.\n\nFunction that computes the final results of all the data computed by averaging according to the sampling of each type of data, and converts to common units.\n\nComputes also the final distribution functions and KB integrals.\n\nThis function modified the values contained in the R data structure.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.gr-Tuple{Result}","page":"Help entries","title":"ComplexMixtures.gr","text":"gr(R::Result) = gr(R.d,R.rdf_count,R.density.solvent_bulk,R.options.binstep)\n\nIf a Result structure is provided without further details, use the rdf count and the bulk solvent density.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.gr-Tuple{Vector{Float64}, Vector{Float64}, Float64, Float64}","page":"Help entries","title":"ComplexMixtures.gr","text":"gr(r::Vector{Float64}, count::Vector{Float64}, density::Float64, binstep::Float64)\n\nComputes the radial distribution function from the count data and the density.\n\nThis is exactly a conventional g(r) if a single atom was chosen as the solute and solvent selections.\n\nReturns both the g(r) and the kb(r)\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.grid3D-Tuple{}","page":"Help entries","title":"ComplexMixtures.grid3D","text":"grid3D(solute,solute_atoms,mddf_result,output_file; dmin=1.5, ddax=5.0, step=0.5)\n\nThis function builds the grid of the 3D density function and fills an array of mutable structures of type Atom, containing the position of the atoms of grid, the closest atom to that position, and distance. \n\nsolute is a ComplexMixtuers.Selection, defining the solute. solute_atoms is the corresponding vector of PDBTools.Atoms, and mddf_result is the result of a mddf_result calculation with the correspondign solute. \n\ndmin and dmax define the range of distance where the density grid will be built, and step defines how fine the grid must be. Be aware that fine grids involve usually a very large (hundreds of thousands points).\n\nAll parameters can be provides as keyword parameters.\n\nExample\n\njulia> using ComplexMixtures, PDBTools\n\njulia> pdb = readPDB(\"./system.pdb\");\n\njulia> R = ComplexMixtures.load(\"./results.json\");\n\njulia> protein = select(pdb,\"protein\");\n\njulia> solute = ComplexMixtures.Selection(protein,nmols=1);\n\njulia> grid = ComplexMixtures.grid3D(solute=solute, solute_atoms=protein, mddf_result=R, output_file=\"grid.pdb\");\n\n\ngrid will contain a vector of Atoms with the information of the MDDF at each grid point, and the same data will be written in the grid.pdb file. This PDB file can be opened in VMD, for example, and contain in the beta field the contribution of each protein residue to the MDDF at each point in space relative to the protein, and in the occupancy field the distance to the protein. Examples of how this information can be visualized are provided in the user guide of ComplexMixtures. \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.itype-Tuple{Int64, Int64}","page":"Help entries","title":"ComplexMixtures.itype","text":"itype(iatom::Int, natomspermol::Int)\n\nInternal structure or function, interface may change.\n\nGiven the index of the atom in the vector of coordinates of the solute or the solvent, returns the type of the atom, that is, the index of this atom within the molecule (goes from 1 to natomspermol)\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.load-Tuple{String}","page":"Help entries","title":"ComplexMixtures.load","text":"load(filename::String)\n\nFunction to load the json saved results file into the Result data structure.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.mddf","page":"Help entries","title":"ComplexMixtures.mddf","text":"mddf(trajectory::Trajectory, options::Options)\n\nFunction that computes the minimum-distance distribution function, atomic contributions, and KB integrals, given the Trajectory structure of the simulation and, optionally, parameters given as a second argument of the Options type. This is the main function of the ComplexMixtures package. \n\nExamples\n\njulia> trajectory = Trajectory(\"./trajectory.dcd\",solute,solvent);\n\njulia> results = mddf(trajectory);\n\nor, to set some custom optional parameter,\n\njulia> options = Options(lastframe=1000);\n\njulia> results = mddf(trajectory,options);\n\n\n\n\n\n","category":"function"},{"location":"help/#ComplexMixtures.mddf_frame!-Tuple{Result, CellListMap.PeriodicSystems.AbstractPeriodicSystem, ComplexMixtures.Buffer, Options, Any}","page":"Help entries","title":"ComplexMixtures.mddf_frame!","text":"mddf_frame!(R::Result, system::AbstractPeriodicSystem, buff::Buffer, options::Options, RNG)\n\nInternal structure or function, interface may change.\n\nComputes the MDDF for a single frame, for autocorrelation of molecules. Modifies the data in the R (type Result) structure.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.minimum_distances!-Tuple{CellListMap.PeriodicSystems.AbstractPeriodicSystem, Result, Int64}","page":"Help entries","title":"ComplexMixtures.minimum_distances!","text":"minimum_distances!(system::CellListMap.PeriodicSystem, R::Result)\n\nInternal structure or function, interface may change.\n\nFunction that computes the list of distances of solvent molecules to a solute molecule. It updates the lists of minimum distances. \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.mol_index-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.mol_index","text":"mol_index(i_atom, natomspermol) = (i_atom-1) ÷ natomspermol + 1\n\nInternal structure or function, interface may change.\n\nExtended help\n\nSets the index of the molecule of an atom in the simples situation, in which all molecules have the same number of atoms. \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.mol_range-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.mol_range","text":"mol_range(imol, n_atoms_per_molecule)\n\nInternal structure or function, interface may change.\n\nGiven the index and the number of atoms per molecule, returns the range of indices of of an array of coordinates that corresponds to the molecule.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.move!-Union{Tuple{T}, Tuple{AbstractVector{T}, T, Any, Any, Any}} where T<:(StaticArraysCore.SVector)","page":"Help entries","title":"ComplexMixtures.move!","text":"move!(x::AbstractVector, newcm::AbstractVector,beta, gamma, theta)\n\nInternal structure or function, interface may change.\n\nTranslates and rotates a molecule according to the desired input center of coordinates and Euler rotations modifyies the vector x.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.overview-Tuple{Result}","page":"Help entries","title":"ComplexMixtures.overview","text":"overview(R::Result)\n\nFunction that outputs the volumes and densities in the most natural units.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.random_move!-Tuple{AbstractVector{<:StaticArraysCore.SVector{3}}, Int64, CellListMap.PeriodicSystems.AbstractPeriodicSystem, Any}","page":"Help entries","title":"ComplexMixtures.random_move!","text":"random_move!(x_ref::AbstractVector{T}, \n irefatom::Int,\n system::AbstractPeriodicSystem,\n x_new::AbstractVector{T}, RNG) where {T<:SVector}\n\nInternal structure or function, interface may change.\n\nFunction that generates a new random position for a molecule.\n\nThe new position is returned in x_new, a previously allocated array.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.randomize_solvent!-Tuple{CellListMap.PeriodicSystems.AbstractPeriodicSystem, ComplexMixtures.Buffer, Int64, Result, Any}","page":"Help entries","title":"ComplexMixtures.randomize_solvent!","text":"randomize_solvent!(system, buff, n_solvent_in_bulk, options, RNG)\n\nInternal structure or function, interface may change.\n\nGenerate a random solvent distribution from the bulk molecules of a solvent\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.save-Tuple{Result, String}","page":"Help entries","title":"ComplexMixtures.save","text":"save(R::Result, filename::String)\n\nFunction to write the result data structure to a json file.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.setbin-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.setbin","text":"setbin(d,step)\n\nInternal structure or function, interface may change.\n\nFunction that sets to which histogram bin a data point pertains simple, but important to keep consistency over all calls.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.setup_PeriodicSystem-Tuple{Trajectory, Options}","page":"Help entries","title":"ComplexMixtures.setup_PeriodicSystem","text":"setup_PeriodicSystem(trajectory::Trajectory, options::Options)\n\nInternal structure or function, interface may change.\n\nSetup the periodic system from CellListMap, to compute minimimum distances. The system will be setup such that xpositions corresponds to one molecule of the solute, and ypositions contains all coordinates of all atoms of the solvent. \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.shellradius-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.shellradius","text":"shellradius(i,step)\n\nInternal structure or function, interface may change.\n\nCompute the point in which the radius comprises half of the volume of the shell.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.sphereradiusfromshellvolume-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.sphereradiusfromshellvolume","text":"sphereradiusfromshellvolume(volume,step)\n\nInternal structure or function, interface may change.\n\nComputes the radius that corresponds to a spherical shell of a given volume.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.sphericalshellvolume-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.sphericalshellvolume","text":"sphericalshellvolume(i,step)\n\nInternal structure or function, interface may change.\n\nComputes the volume of the spherical shell defined within [(i-1)step,istep].\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.sum!-Tuple{Result, Result}","page":"Help entries","title":"ComplexMixtures.sum!","text":"sum!(R1::Result, R2::Result)\n\nInternal structure or function, interface may change.\n\nSum the counts of two Results structures, adding the result to the first structure as in R1 = R1 + R2.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.title-Tuple{Result, Selection, Selection}","page":"Help entries","title":"ComplexMixtures.title","text":"title(R::Result, solute::Selection, solvent::Selection)\ntitle(R::Result, solute::Selection, solvent::Selection, nspawn::Int)\n\nInternal structure or function, interface may change.\n\nPrint some information about the run.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.update_list!-Tuple{Any, Any, Any, Any, Any, Any, Vector{ComplexMixtures.MinimumDistance}}","page":"Help entries","title":"ComplexMixtures.update_list!","text":"update_list!(i, j, d2, iref_atom::Int, mol_index_i::F, isolute::Int, list::Vector{MinimumDistance{T}}) where {F<:Function, T}\n\nInternal structure or function, interface may change.\n\nFunction that updates a list of minimum distances given the indexes of the atoms involved for one pair within cutoff, for autocorrelations (such that the identity of isolute is needed)\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.update_list!-Tuple{Any, Any, Any, Any, Any, Vector{ComplexMixtures.MinimumDistance}}","page":"Help entries","title":"ComplexMixtures.update_list!","text":"update_list!(i, j, d2, iref_atom::Int, mol_index_i::F, list::Vector{MinimumDistance{T}}) where {F<:Function, T}\n\nInternal structure or function, interface may change.\n\nFunction that updates a list of minimum distances given the indexes of the atoms involved for one pair within cutoff.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.update_md-Tuple{ComplexMixtures.MinimumDistance, ComplexMixtures.MinimumDistance}","page":"Help entries","title":"ComplexMixtures.update_md","text":"update_md(md1::MinimumDistance{T}, md2::MinimumDistance{T}) where {T}\n\nInternal structure or function, interface may change.\n\nFunction that returns the updated minimum distance structure after comparing two structures associated with the same molecule.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.updatecounters!-Tuple{Result, CellListMap.PeriodicSystems.AbstractPeriodicSystem}","page":"Help entries","title":"ComplexMixtures.updatecounters!","text":"updatecounters!(R::Result, system::AbstractPeriodicSystem)\n\nInternal structure or function, interface may change.\n\nFunction that updates the minimum-distance counters in R\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.viewmol-Union{Tuple{T}, Tuple{Int64, Vector{T}, Int64}} where T","page":"Help entries","title":"ComplexMixtures.viewmol","text":"viewmol(i::Int, x::Vector{T}, n::Int) where T\n\nInternal structure or function, interface may change.\n\nReturns a view of a coordinate vector corresponding to the atoms of a molecule with index i. n is the number of atoms of the molecule.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.which_types-Tuple{Selection, Vector{Int64}}","page":"Help entries","title":"ComplexMixtures.which_types","text":"which_types(s::Selection, indexes::Vector{Int})\n\nInternal structure or function, interface may change.\n\nFunction that returns the list of the indexes of the types of the atoms in a selection. For example, if a selection corresponds to a solvent of water molecules: There are three types, 1, 2, and 3, corresponding to the three atoms of the water molecule. If the indexes provided are, for instance, 11, 12, and 13, corresponding to a water molecule, this function will return 1, 2 and 3.\n\nThis is used to get equivalent-atom contributions to the distribution functions. For example, the input indexes span all water molecules, the output of this function will be still the three indexes corresponding to the three types of atoms that exist in a water molecule. \n\nIt is not possible to compute the contribution of one individual water molecule if the distribution function was computed for all molecules. Thus, the necessity to identify the types of atoms involved in a selection. \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.writexyz-Union{Tuple{T}, Tuple{Vector{T}, String}} where T<:(AbstractVector)","page":"Help entries","title":"ComplexMixtures.writexyz","text":"writexyz(x::Vector{T}, file::String) where T <: AbstractVector\n\nInternal structure or function, interface may change.\n\nPrint test xyz file.\n\n\n\n\n\n","category":"method"},{"location":"mddf/#Computing-the-Minimum-Distance-Distribution-Function","page":"Computing the MDDF","title":"Computing the Minimum-Distance Distribution Function","text":"","category":"section"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"The main function of the ComplexMixtures package actually computes the MDDF between the solute and the solvent chosen. ","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"It is run with the following command:","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"results = mddf(trajectory) ","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"The MDDF along with other results, like the corresponding KB integrals, are returned in the results data structure, which is described in the next section.","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"It is possible to tune several options of the calculation, by setting the Options data structure with user-defined values in advance. The most common parameters to be set by the user are probably dbulk and stride. ","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"dbulk defines the distance from the solute above which the user believes that the reference solute molecule does not significantly anymore the structure of the solvent. The default value is 10 Angstroms, but for large solvent molecules this might not be enough. To increase dbulk, use: ","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"options = Options(dbulk=15.)\nresults = mddf(trajectory,options)","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"stride defines if some frames will be skip during the calculation (for speedup). For example, if stride=5, only one in five frames will be considered. Adjust stride with: ","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"options = Options(stride=5)\nresults = mddf(trajectory,options)","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"See the Options section for further details and other options to set.","category":"page"},{"location":"installation/#Installation","page":"Installation","title":"Installation","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"note: Note\nThis is a package written in Julia. We invite you to experiment with the language, but if you want to just call this package from Python, read the From Python section of the manual. Understanding all the features of the package requires reading the manual as whole. The syntaxes of using this package from Julia or Python are almost identical, and the motivation for using Python should be mostly the familiarity with further analsys tools, as the plotting packages. ","category":"page"},{"location":"installation/#Install-Julia","page":"Installation","title":"Install Julia","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"First you need to install the Julia language in your platform, from: http://julialang.org. Julia version 1.6 or greater is required. Using the juliaup tool is also a highly recommended way of installing and keeping Julia up to date.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"tip: Tip\nNew to Julia? Julia is a modern high-level yet performant programming language. Some tips and a nice workflow for using it effectively can be found here. For this specific package, following a the step-by-step examples provided here after installing Julia should be enough. ","category":"page"},{"location":"installation/#Install-the-packages","page":"Installation","title":"Install the packages","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"Within Julia, to install the packages required for running the examples here you need to do:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"julia> import Pkg\n\njulia> Pkg.add([\"ComplexMixtures\",\"Plots\",\"PDBTools\"])","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"Please read the recommended workflow below, for further information and to be sure to have a smoother experience.","category":"page"},{"location":"installation/#Recommended-workflow-for-reproducibility","page":"Installation","title":"Recommended workflow for reproducibility","text":"","category":"section"},{"location":"installation/#Create-an-environment","page":"Installation","title":"Create an environment","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"Once Julia is installed, we recommend to create an environment that will contain all the packages you may use for your analyses, including ComplexMixtures, in such a way that your results can always be reproduced and you don't get any version incompatibility.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"We illustrate this by creating the \"MyNewPaper\" environment, which will be hosted in a simple directory,","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"mkdir /home/user/Documents/MyNewPaper","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"Then, start Julia and activate the environment that will be hosted there:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"julia> import Pkg; Pkg.activate(\"/home/user/Documents/MyNewPaper\")\n Activating new project at `~/Documents/MyNewPaper`","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"and add to this environment the packages that your analyses will require:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"julia> Pkg.add([\"ComplexMixtures\",\"PDBTools\",\"Plots\"])","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"That's it. Close Julia. Note that this created the files Manifest.toml and Project.toml in the MyNewPaper directory, which contain the information of packages and exact package versions you are using now on in this environment. Saving these files may be relevant for the future exact reproduction of your analyses. ","category":"page"},{"location":"installation/#Run-your-analysis-scripts-in-that-environment","page":"Installation","title":"Run your analysis scripts in that environment","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"Now, your analysis scripts, described in the next section in details, will look like: ","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"import Pkg; Pkg.activate(\"/home/user/Documents/MyNewPaper\")\n\nusing ComplexMixtures\nusing PDBTools\nusing Plots\n\n# etc ... ","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"And the script can be run with julia -t auto script.jl (where -t auto allows for multi-threading), or included in julia with julia> include(\"./scritp.jl\"), as described in the next section.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"tip: Tip\nBy loading the package with using ComplexMixturesthe most common functions of the package become readily available by their direct name, for example mddf(...).If you don't want to bring the functions into the scope of your script, useimport ComplexMixturesThen, the functions of the package are called, for example, using ComplexMixtures.mddf(...). To avoid having to write ComplexMixtures all the time, define an accronym. For example:import ComplexMixtures as CM\nCM.mddf(...)","category":"page"},{"location":"contrib/#contributions","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"One of the interesting features of Minimum-Distance distributions is that they can be naturally decomposed into the atomic or group contributions. Simply put, if a MDDF has a peak at a hydrogen-bonding distance, it is natural to decompose that peak into the contributions of each type of solute or solvent atom to that peak. ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"To obtain the atomic contributions of an atom or group of atoms, the contributions function is provided. For example, in a system composed of a protein and water, we would have defined the solute and solvent using:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"using PDBTools, ComplexMixtures\natoms = readPDB(\"system.pdb\")\nprotein = select(atoms,\"protein\")\nwater = select(atoms,\"water\")\nsolute = Selection(protein,nmols=1)\nsolvent = Selection(water,natomspermol=3)","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The MDDF calculation is executed with:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"trajectory = Trajectory(\"trajectory.dcd\",solute,solvent)\nresults = mddf(trajectory)","category":"page"},{"location":"contrib/#Atomic-contributions-in-the-result-data-structure","page":"Atomic and group contributions","title":"Atomic contributions in the result data structure","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The results data structure contains the decomposition of the MDDF into the contributions of every type of atom of the solute and the solvent. These data is available at the results.solute_atom and results.solvent_atom arrays: ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"julia> results.solute_atom\n50×1463 Array{Float64,2}:\n 0.0 0.0 0.0 … 0.0 0.0 0.0\n 0.0 0.0 0.0 … 0.0 0.0 0.0\n ...\n 0.0 0.14245 0.0 … 0.0 0.0 0.0\n 0.0 0.0 0.0 … 0.0 0.0 0.0\n\njulia> results.solvent_atom \n50×3 Array{Float64,2}:\n 0.0 0.0 0.0 \n 0.0 0.0 0.0 \n ...\n 0.26087 0.26087 0.173913\n 0.25641 0.0854701 0.170940","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Here, 50 is the number of bins of the histogram, whose distances are available at the results.d vector.","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"It is expected that for a protein most of the atoms do not contribute to the MDDF, and that all values are zero at very short distances, smaller than the radii of the atoms.","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The three columns of the results.solvent_atom array correspond to the thee atoms of the water molecule in this example. The sequence of atoms correspond to that of the PDB file, but can be retrieved with:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"julia> solvent.names\n3-element Array{String,1}:\n \"OH2\"\n \"H1\"\n \"H2\"","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Therefore, if the first column of the results.solvent_atom vector is plotted as a function of the distances, one gets the contributions to the MDDF of the Oxygen atom of water. For example, here we plot the total MDDF and the Oxygen contributions: ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"using Plots\nplot(results.d,results.mddf,label=\"Total MDDF\",linewidth=2)\nplot!(results.d,results.solvent_atom[:,1],label=\"OH2\",linewidth=2)\nplot!(xlabel=\"Distance / Å\",ylabel=\"MDDF\")","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"page"},{"location":"contrib/#Selecting-groups-by-atom-names-or-indexes","page":"Atomic and group contributions","title":"Selecting groups by atom names or indexes","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"To plot the contributions of the hydrogen atoms of water to the total MDDF, we have to select the two atoms, named H1 and H2. The contributions function provides several practical ways of doing that, with or without the use of PDBTools. ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The contributions function receives three parameters: ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The solute or solvent data structure, created with Selection. \nThe array of atomic contributions (here results.solute_atom or results.solvent_atom), corresponding to the selection in 1.\nA selection of a group of atoms within the molecule of interest, provided as described below. ","category":"page"},{"location":"contrib/#Selecting-by-indexes-within-the-molecule","page":"Atomic and group contributions","title":"Selecting by indexes within the molecule","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"To select simply by the index of the atoms of the molecules, just provide a list of indexes to the contributions function. For example, to select the hydrogen atoms, which are the second and third atoms of the water molecule, use:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"julia> indexes = [ 2, 3 ]\njulia> h_contributions = contributions(solvent,R.solvent_atom,indexes)\n500-element Array{Float64,1}:\n 0.0\n 0.0\n ⋮\n 0.7742706465861815\n 0.8084139794974875","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Plotting both the oxygen (index = 1) and hydrogen contributions results in:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"page"},{"location":"contrib/#Selecting-by-atom-name","page":"Atomic and group contributions","title":"Selecting by atom name","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The exact same plot above could be obtained by providing lists of atom names instead of indexes to the contributions function:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"oxygen = [\"OH2\"]\no_contributions = contributions(solvent,R.solvent_atom,oxygen) \nhydrogens = [\"H1\",\"H2\"]\nh_contributions = contributions(solvent,R.solvent_atom,hydrogens)","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The above plot can be obtained with:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"using Plots\nplot(results.d,results.mddf,label=\"Total MDDF\",linewidth=2)\nplot!(results.d,o_contributions,label=\"OH2\",linewidth=2)\nplot!(results.d,h_contributions,label=\"Hydrogen atoms\",linewidth=2)\nplot!(xlabel=\"Distance / Å\",ylabel=\"MDDF\")","category":"page"},{"location":"contrib/#General-selections-using-PDBTools","page":"Atomic and group contributions","title":"General selections using PDBTools","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"More interesting and general is to select atoms of a complex molecule, like a protein, using residue names, types, etc. Here we illustrate how this is done by providing selection strings to contributions to obtain the contributions to the MDDF of different types of residues of a protein to the total MDDF. ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"For example, if we want to split the contributions of the charged and neutral residues to the total MDDF distribution, we could use to following code. Here, solute refers to the protein.","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"charged_residues = PDBTools.select(atoms,\"charged\")\ncharged_contributions = contributions(solute,R.solute_atom,charged_residues)\n\nneutral_residues = PDBTools.select(atoms,\"neutral\")\nneutral_contributions = contributions(solute,R.solute_atom,neutral_residues)","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The charged and neutral outputs are vectors containing the contributions of these residues to the total MDDF. The corresponding plot is: ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"plot(results.d,results.mddf,label=\"Total MDDF\",linewidth=2)\nplot!(results.d,charged_contributions,label=\"Charged residues\",linewidth=2)\nplot!(results.d,neutral_contributions,label=\"Neutral residues\",linewidth=2)\nplot!(xlabel=\"Distance / Å\",ylabel=\"MDDF\")","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Resulting in:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Note here how charged residues contribute strongly to the peak at hydrogen-bonding distances, but much less in general. Of course all selection options could be used, to obtain the contributions of specific types of residues, atoms, the backbone, the side-chains, etc. ","category":"page"},{"location":"parallel/#Parallel-execution","page":"Parallel execution","title":"Parallel execution","text":"","category":"section"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"It is highly recommended to run MDDF calculations in parallel, using multiple processors of a single computer. To run the computation in parallel, initialize julia with the -t auto option:","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"julia -t auto","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"The computation will use a number of threads equal to the number of physical cores of the computer. The number of computation threads to be used can be set by the Options(nthreads=N) parameter, where N is an integer. Hyperthreading (using more threads than physical CPUs) usually does not provide a significant speedup, and can be detrimental in some cases. ","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"To directly run a script in parallel, use:","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"julia -t auto example.jl","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"note: Note\nThe number of threads used for computation of the MDDF is the number of physical CPUs of the computer, which are obtained programmatically. Most times the use of hyper-threading is not beneficial. Adjust the number of threads with the Options(nthreads=N) parameter.","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"warning: Warning\nIf the calculations get Killed by no apparent reason, that is probably because you are running out of memory because of the many parallel computations running. One way to alleviate this problem is to force garbage collection, usingoptions = Options(GC=true,GC_threshold=0.5)\nR = mddf(trajectory,options)\nThe GC_threshold=0.5 indicates that if the free memory is smaller than 50% of the total memory of the machine, a garbage-collection run will occur. The default parameters are GC=true and GC_threshold=0.1. ","category":"page"},{"location":"multiple/#Working-with-multiple-trajectories","page":"Multiple trajectories","title":"Working with multiple trajectories","text":"","category":"section"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"Very commonly, one has multiple trajectories of the same system, and we want to obtain the average results of all trajectories. We provide a simple scheme to average the results of multiple MDDF calculations:","category":"page"},{"location":"multiple/#Create-a-vector-of-result-data-structures,-without-initialization","page":"Multiple trajectories","title":"Create a vector of result data structures, without initialization","text":"","category":"section"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"Let us assume that we have three Gromacs trajectories, with file names traj1.xtc, traj2.xtc, traj3.xtc. First let us create a list with these file names:","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"trajectory_files = [ \"traj1.xtc\" , \"traj2.xtc\" , \"traj3.xtc\" ]","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"And define an empty vector of Result structures:","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"results = Result[]","category":"page"},{"location":"multiple/#Run-the-calculations-in-a-loop","page":"Multiple trajectories","title":"Run the calculations in a loop","text":"","category":"section"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"The calculation on the multiple trajectories is then performed in a simple loop, such as","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"atoms = PDBTools.readPDB(\"./system.pdb\")\nsolute = Selection(atoms,\"protein\",nmols=1)\nsolvent = Selection(atoms,\"resname TMAO\",,natomspermol=14)\nfor file in trajectory_files\n trajectory = Trajectory(file,solute,solvent)\n # compute the MDDF data and push the result to the results array\n push!(results, mddf(trajectory))\nend","category":"page"},{"location":"multiple/#Merge-the-results-of-several-trajectories,-with-proper-weights","page":"Multiple trajectories","title":"Merge the results of several trajectories, with proper weights","text":"","category":"section"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"Of course, the resulting results vector will contain at each position the results of each calculation. To merge these results in a single result data structure, use:","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"R = merge(results)","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"The R structure generated contains the averaged results of all calculations, with weights proportional to the number of frames of each trajectory. That is, if the first trajectory had 2000 frames, and the second and third trajectories have 1000 frames each, the first trajectory will have a weight of 0.5 on the final results. The merge function can be used to merge previously merged results with new results as well.","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"tip: Tip\nThe names of the files and and weights are stored in the R.files and R.weights vectors of the results structure:julia> R.files\n3-element Array{String,1}:\n \"./traj1.xtc\"\n \"./traj2.xtc\"\n \"./traj3.xtc\"\n\njulia> R.weights\n2-element Array{Float64,1}:\n 0.5\n 0.25\n 0.25\nIt is not a bad idea to check if that is what you were expecting.","category":"page"},{"location":"save/#save","page":"Save and load","title":"Save and load results","text":"","category":"section"},{"location":"save/","page":"Save and load","title":"Save and load","text":"Three functions serve the purpose of saving and loading the results obtained with ComplexMixtures:","category":"page"},{"location":"save/#Save-data-to-recover-it-later","page":"Save and load","title":"Save data to recover it later","text":"","category":"section"},{"location":"save/","page":"Save and load","title":"Save and load","text":"save(results,\"results.json\")","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"where results is the output data structure of the mddf() calculation, and results.json is the output file to be created. The file is written in JSON format, thus is not naturally human-readable.","category":"page"},{"location":"save/#Load-saved-data","page":"Save and load","title":"Load saved data","text":"","category":"section"},{"location":"save/","page":"Save and load","title":"Save and load","text":"results = load(\"results.json\")","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"The load function reads the output of the save function above, and restores the results data structure.","category":"page"},{"location":"save/#Write-data-in-a-human-readable-format","page":"Save and load","title":"Write data in a human-readable format","text":"","category":"section"},{"location":"save/","page":"Save and load","title":"Save and load","text":"If you Want the results to be written as simple ASCII tables such that you can read them with another analysis program, plotting graphic, or just want to inspect the data visually, use:","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"write(results,\"results.dat\")","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"Three files will be created by this function:","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"results.dat: Contains the main results, as the MDDF and KB-integral data.","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"results-ATOM_CONTRIB_SOLVENT.dat: contains the contribution of each atom type of the solvent to the MDDF.","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"results-ATOM_CONTRIB_SOLUTE.dat: contains the contribution of each atom type of the solute to the MDDF.","category":"page"},{"location":"trajectory/#trajectories","page":"Loading the trajectory","title":"Loading trajectories","text":"","category":"section"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"To initialize a trajectory file for computation, use the command","category":"page"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"trajectory = Trajectory(\"trajectory.xtc\",solute,solvent)","category":"page"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"where solute and solvent are defined with the Selection function described before. This function opens the stream for reading frames, which are read once a time when the coordinates are required for computing the MDDF.","category":"page"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"The Trajectory function uses Chemfiles in background, and thus the most common trajectory formats are supported, as the ones produced with NAMD, Gromacs, LAMMPS, Amber, etc. ","category":"page"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"tip: Tip\nThe format of the trajectory file is automatically determined by Chemfiles from the extension of the file. However, it can be provided by the user with the format keyword, for example:trajectory = Trajectory(\"trajectory.xtc\",solute,solvent,format=\"xtc\")","category":"page"},{"location":"quickguide/#Quick-Guide","page":"Quick Guide","title":"Quick Guide","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Of course, follow the installation instructions first. A complete working example is shown below, and in the section that follows each command is described in detail.","category":"page"},{"location":"quickguide/#Complete-example","page":"Quick Guide","title":"Complete example","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Here we show the input file required for the study of the solvation of a protein by the TMAO solvent, which is a molecule 4 atoms. The protein is assumed to be at infinite dilution in the simulation. The trajectory of the simulation is in DCD format in this example, which is the default output of NAMD and CHARMM simulation packages.","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"# Activate environment (see the Installation -> Recommended Workflow manual section)\nimport Pkg; Pkg.activate(\"/home/user/MyNewPaper\")\n\n# Load packages\nusing PDBTools\nusing ComplexMixtures \nusing Plots\n\n# Load PDB file of the system\natoms = readPDB(\"./system.pdb\")\n\n# Select the protein and the TMAO molecules\nprotein = select(atoms,\"protein\")\ntmao = select(atoms,\"resname TMAO\")\n\n# Setup solute and solvent structures\nsolute = Selection(protein,nmols=1)\nsolvent = Selection(tmao,natomspermol=14)\n\n# Setup the Trajectory structure\ntrajectory = Trajectory(\"./trajectory.dcd\",solute,solvent)\n\n# Run the calculation and get results\nresults = mddf(trajectory)\n\n# Save the results to recover them later if required\nsave(results,\"./results.json\")\n\n# Plot the some of the most important results \nplot(results.d,results.mddf,xlabel=\"d\",ylabel=\"MDDF\") # plot the MDDF\nsavefig(\"./mddf.pdf\")\nplot(results.d,results.kb,xlabel=\"d\",ylabel=\"KB\") # plot the KB \nsavefig(\"./kb.pdf\")","category":"page"},{"location":"quickguide/#Running-the-example","page":"Quick Guide","title":"Running the example","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Given that this code is saved into a file named example.jl, it can be run within the Julia REPL with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"julia> include(\"example.jl\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"or directly with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"julia -t auto example.jl","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"where -t auto will launch julia with multi-threading. It is highly recommended to use multi-threading!","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"note: Note\nJulia compiles the code the first time it is run in each section. Thus, running script from the command line with, for example, julia -t auto example.jl may appear slow, particularly if you are modifying the script interactively. Ideally, do not restart Julia, just repeatedly include your script in the same Julia section. The second time the script is loaded will be much faster. For example:julia> @time include(\"./example.jl\") \n# ... some output\n27.554095 seconds (72.13 M allocations: 4.623 GiB, 4.37% gc time, 11.96% compilation time)\njulia> @time include(\"./example.jl\")\n# ... some output\n0.703780 seconds (3.24 M allocations: 897.260 MiB, 12.22% gc time)The first time the script was called it took ~30s, which included compilation of the code and loading of the packages. The second time the script was included it took 0.7s. Thus, for interactive modification of the script, don't restart Julia.This has been much improved in Julia 1.9, particularly if a stable environment is used, as suggested.","category":"page"},{"location":"quickguide/#Detailed-description-of-the-example","page":"Quick Guide","title":"Detailed description of the example","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Start julia and load the ComplexMixtures package, using:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"using ComplexMixtures","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"And here we will use the PDBTools package to obtain the selections of the solute and solvent molecules: ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"using PDBTools","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"(see Set solute and solvent for details).","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The fastest way to understand how to use this package is through an example. ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Let us consider a system of three components: a protein, water, a cossolvent: TMAO (trimetylamine-N-oxyde), which is a common osmolyte known to stabilize protein structures. A picture of this system is shown below, with the protein in blue, water, and TMAO molecules. The system was constructed with Packmol and the figure was produced with VMD.","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"
      \n\n
      ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"We want to study the interactions of the protein with TMAO in this example. The computation of the MDDF is performed by defining the solute and solvent selections, and running the calculation on the trajectory.","category":"page"},{"location":"quickguide/#Define-the-protein-as-the-solute","page":"Quick Guide","title":"Define the protein as the solute","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"To define the protein as the solute, we will use the PDBTools package, which provides a handy selection syntax. First, read the PDB file using ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"atoms = readPDB(\"./system.pdb\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Then, let us select the protein atoms (here we are using the PDBTools.select function):","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"protein = select(atoms,\"protein\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"And, finally, let us use the Selection function to setup the structure required by the MDDF calculation:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"solute = Selection(protein,nmols=1)","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"note: Note\nIt is necessary to indicate how many molecules (in this case, nmols=1, so that ComplexMixtures knows that the solute is to be considered as single structure. In this case there is no ambiguity, but if the solute was a micelle, for example, this option would let ComplexMixtures know that one wants to consider the micelle as a single structure.","category":"page"},{"location":"quickguide/#Define-TMAO-the-solvent-to-be-considered","page":"Quick Guide","title":"Define TMAO the solvent to be considered","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Equivalently, the solvent is set up with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"tmao = select(atoms,\"resname TMAO\")\nsolvent = Selection(tmao,natomspermol=14)\n","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"note: Note\nHere we opted to provide the number of atoms of a TMAO molecules (with the natomspermol keyword). This is generally more practical for small molecules than to provide the number of molecules.","category":"page"},{"location":"quickguide/#Set-the-Trajectory-structure","page":"Quick Guide","title":"Set the Trajectory structure","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The solute and solvent data structures are then fed into the Trajectory data structure, together with the trajectory file name, with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"trajectory = Trajectory(\"trajectory.dcd\",solute,solvent)","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"In the case, the trajectory is of NAMD \"dcd\" format. All formats supported by Chemfiles are automatically recognized. ","category":"page"},{"location":"quickguide/#Finally,-run-the-computation-and-get-the-results:","page":"Quick Guide","title":"Finally, run the computation and get the results:","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"If default options are used (as the bin size of the histograms, read all frames without skipping any), just run the mddf with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"results = mddf(trajectory)\n","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Some optional parameters for the computation are available in the Options section.","category":"page"},{"location":"quickguide/#The-results-data-structure-obtained","page":"Quick Guide","title":"The results data structure obtained","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The results data structure contains all the results of the MDDF calculation, including:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"results.d : Vector containing the distances to the solute. ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"results.mddf : Vector containing the minimum-distance distribution function at each distance.","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"That means, for example, that ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"plot(results.d,results.mddf,xlabel=\"d / \\AA\",ylabel=\"MDDF\") \n","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"results in the expected plot of the MDDF of TMAO as a function of the distance to the protein:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"
      \n\n
      ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The Kirkwood-Buff integral corresponding to that distribution is provided in the results.kb vector, and can be also directly plotted with ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"plot(results.d,results.kb,xlabel=\"d / \\AA\",ylabel=\"MDDF\") ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"to obtain:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"
      \n\n
      ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"See the Atomic and group contributions section for a detailed account on how to obtain a molecular picture of the solvation by splitting the MDDF in the contributions of each type of atom of the solvent, each type of residue of the protein, etc.","category":"page"},{"location":"quickguide/#Save-the-results","page":"Quick Guide","title":"Save the results","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The results can be saved into a file (with JSON format) with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"save(results,\"./results.json\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"And these results can be loaded afterwards with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"load(\"./results.json\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Alternatively, a human-readable set of output files can be obtained to be analyzed in other software (or plotted with alternative tools), with","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"write(results,\"./results.dat\")","category":"page"},{"location":"selection/#selections","page":"Set solute and solvent","title":"Set the solute and solvent selections","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"The solute and solvent are defined in ComplexMixtures as lists (vectors) of the indexes of the atoms of the system. The solute and solvent information is stored in the Selection structure. For example, if the solute is a molecule formed by the first 5 atoms of the system, it would be defined as: ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"indexes = [ 1, 2, 3, 4, 5 ]\nsolute = Selection(indexes,nmols=1)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"note: Note\nWe need to inform the Selection function about the number of atoms of each molecule (using natomspermol=3, for example), or the number of molecules (using nmols=1000, for example), such that the atoms belonging to each molecule can be determined without ambiguity. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"The atom names can be also provided such that some of the output files contain more information on the atomic contributions. In this case the syntax is:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"indexes = [ 1, 2, 3, 4, 5 ]\nnames = [ \"H1\", \"H2\", \"H3\", \"H4\", \"C\" ]\nsolute = Selection(indexes,names,nmols=1)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"warning: Warning\nThe indexing in ComplexMixtures is 1-based. That means that the first atom of your structure file is in position 1 of the coordinates. Please be careful if using any selection tool to be sure that your selection is correct.","category":"page"},{"location":"selection/#Using-PDBTools","page":"Set solute and solvent","title":"Using PDBTools","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"PDBTools is a package we developed to read and write PDB files, which provides a simple selection tool. It is installed as a dependency of ComplexMixtures. Given a PDB file of the simulated system, the solute can be defined as, for example,","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"using PDBTools\natoms = PDBTools.readPDB(\"system.pdb\")\nprotein = PDBTools.select(atoms,\"protein\")\nsolute = Selection(protein,nmols=1)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"If the solvent is, for instance, water, the indexes of the water molecules can be obtained with:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"water = PDBTools.select(atoms,\"water\")\nsolvent = Selection(water,natomspermol=3)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"or, alternatively, a more compact syntax can be used, for example:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"water = PDBTools.select(\"system.pdb\",\"resname TIP3P\")\nsolvent = Selection(water,natomspermol=3)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"or even providing just the names of the input file and selection, which will run PDBTools in background:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"solvent = Selection(\"sytem.pdb\",\"water\",water,natomspermol=3)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"warning: Warning\nThe selection syntax of PDBTools is somewhat limited. Verify if the selections correspond to the the desired sets of atoms every time.","category":"page"},{"location":"selection/#Using-VMD","page":"Set solute and solvent","title":"Using VMD","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"VMD is a very popular and powerful package for visualization of simulations. It contains a very versatile library to read topologies and trajectory files, and a powerful selection syntax. We provide here a wrapper to VMD which allows using its capabilities. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"For example, the solute can be defined with: ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"indexes, names = VMDselect(\"./system.gro\",\"protein\",vmd=\"/usr/bin/vmd\")\nsolute = Selection(indexes,names,nmols=1)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"The main advantage here is that all the file types that VMD supports are supported. But VMD needs to be installed and is run in background, and it takes a few seconds. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"warning: Warning\nVMD uses 0-based indexing and VMDselect adjusts that. However, if a selection is performed by index, as with index 1, VMD will select the second atom, and the output will be [2]. Selections by type, name, segment, residue name, etc, won't be a problem.","category":"page"},{"location":"tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"A set of examples of analyses that can be performed with ComplexMixtures is given in this site. A brief the description of the possible results is provided here. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Some tools are provided to analyze the results:","category":"page"},{"location":"tools/#coordination_number","page":"Tools","title":"Coordination numbers","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"The function","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"coordination_number(R::Result, group_contributions::Vector{Float64})","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"computes the coordination number of a given group of atoms from the solute or solvent atomic contributions to the MDDF. Here, R is the result of the mddf calculation, and group_contributions is the output of the contributions function for the desired set of atoms.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"If no group is defined, the coordination number of the complete solute is returned, which is equivalent to the R.coordination_number field of the Result data structure:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"coordination_number(R::Result) == R.coordination_number","category":"page"},{"location":"tools/#Example","page":"Tools","title":"Example","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"In the following example we compute the coordination number of the atoms of residue 50 (which belongs to the solute - a protein) with the solvent atoms of TMAO, as a function of the distance. The plot produced will show side by side the residue contribution to the MDDF and the corresponding coordination number.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"using ComplexMixtures, PDBTools\nusing Plots, EasyFit\npdb = readPDB(\"test/data/NAMD/structure.pdb\")\nR = load(\"test/data/NAMD/protein_tmao.json\")\nsolute = Selection(PDBTools.select(pdb, \"protein\"), nmols=1)\nresidue50 = PDBTools.select(pdb, \"residue 50\")\n# Compute the group contribution to the MDDF\nresidue50_contribution = contributions(solute, R.solute_atom, residue50)\n# Now compute the coordination number\nresidue50_coordination = coordination_number(R, residue50_contribution)\n# Plot with twin y-axis\nplot(R.d, movavg(residue50_contribution,n=10).x,\n xaxis=\"distance / Å\", \n yaxis=\"MDDF contribution\", \n linewidth=2, label=nothing, color=1\n)\nplot!(twinx(),R.d, residue50_coordination, \n yaxis=\"Coordination number\", \n linewidth=2, label=nothing, color=2\n)\nplot!(title=\"Residue 50\", framestyle=:box, subplot=1)","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"With appropriate input data, this code produces:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"
      \n\n
      ","category":"page"},{"location":"tools/#Computing-a-2D-density-map-around-a-macromolecule","page":"Tools","title":"Computing a 2D density map around a macromolecule","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"One nice way to visualize the accumulation or depletion of a solvent around a macromolecule (a protein, for example), is to obtain a 2D map of the density as a function of the distance from its surface. For example, in the figure below the density of a solute (here, Glycerol), in the neighborhood of a protein is shown:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"
      \n\n
      ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Here, one can see that Glycerol accumulates on Asp76 and on the proximity of hydrogen-bonding residues (Serine residues mostly). This figure was obtained by extracting from atomic contributions of the protein the contribution of each residue to the MDDF. Using PDBTools, this can be done with, for example: ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"residues = collect(eachresidue(protein))\nresidue_contributions = zeros(length(R.d),length(residues))\nfor (i,residue) in pairs(residues)\n c = contributions(solute,R.solute_atom,residue) \n residue_contributions[:,i] .= c\nend","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The above produces a matrix with a number of columns equal to the number of residues and a number of rows equal to the number of MDDF points. That matrix can be plotted as a contour map with adequate plotting software. A complete running example is provided here, producing the figure above. ","category":"page"},{"location":"tools/#Computing-a-3D-density-map-around-a-macromolecule","page":"Tools","title":"Computing a 3D density map around a macromolecule","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"Three-dimensional representations of the distribution functions can also be obtained from the MDDF results. These 3D representations are obtained from the fact that the MDDFs can be decomposed into the contributions of each solute atom, and that each point in space is closest to a single solute atom as well. Thus, each point in space can be associated to one solute atom, and the contribution of that atom to the MDDF at the corresponding distance can be obtained. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"For example, the distribution function of a hydrogen-bonding liquid solvating a protein will display a characteristic peak at about 1.8Å. The MDDF at that distance can be decomposed into the contributions of all atoms of the protein which were found to form hydrogen bonds to the solvent. A 3D representation of these contributions can be obtained by computing, around a static protein (solute) structure, which are the regions in space which are closer to each atom of the protein. The position in space is then marked with the atom of the protein to which that region \"belongs\" and with the contribution of that atom to the MDDF at each distance within that region. A special function to compute this 3D distribution is provided here: grid3D. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"This is better illustrated by a graphical representation. In the figure below we see a 3D representation of the MDDF of Glycerol around a protein, computed from a simulation of this protein in a mixture of water and Glycerol. A complete set of files and a script to reproduce this example is available here. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"
      \n\n
      ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"In the figure on the left, the points in space around the protein are selected with the following properties: distance from the protein smaller than 2.0Å and relative contribution to the MDDF at the corresponding distance of at least 10% of the maximum contribution. Thus, we are selecting the regions of the protein corresponding to the most stable hydrogen-bonding interactions. The color of the points is the contribution to the MDDF, from blue to red. Thus, the most reddish-points corresponds to the regions where the most stable hydrogen bonds were formed. We have marked two regions here, on opposite sides of the protein, with arrows.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Clicking on those points we obtain which are the atoms of the protein contributing to the MDDF at that region. In particular, the arrow on the right points to the strongest red region, which corresponds to an Aspartic acid. These residues are shown explicitly under the density (represented as a transparent surface) on the figure in the center. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The figure on the right displays, overlapped with the hydrogen-bonding residues, the most important contributions to the second peak of the distribution, corresponding to distances from the protein between 2.0 and 3.5Å. Notably, the regions involved are different from the ones forming hydrogen bonds, indicating that non-specific interactions with the protein (and not a second solvation shell) are responsible for the second peak. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"An example input file which produces the files required for producing these images is:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"using ComplexMixtures, PDBTools\n\n# PDB file of the system simulated\npdb = readPDB(\"../Data/system.pdb\")\n\n# Load results of a ComplexMixtures run\nR = load(\"../Data/results_glyc50.json\") \n\n# Inform which is the solute\nprotein = select(pdb,\"protein\")\nsolute = Selection(protein,nmols=1)\n\n# Compute the 3D density grid and output it to the PDB file\ngrid = grid3D(\n solute=solute,\n solute_atoms=protein,\n mddf_result=R,\n output_file=\"grid.pdb\"\n)","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The call to grid3D in the last command will write an output a PDB file with the grid points, which loaded in a visualization software side-by-side with the protein structure, allows the production of the images shown. The grid.pdb file contains a regular PDB format, but the atoms are grid points. The identity of the atoms correspond to the identity of the protein atom contributing to the MDDF at that point (the closest protein atom). The temperature-factor column (beta) contains the relative contribution of that atom to the MDDF at the corresponding distance, and the occupancy field contains the distance itself.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The output grid variable contains the same information of the PDB file, which can be analyzed with the tools of PDBTools if the user wants to.","category":"page"},{"location":"tools/#Computing-radial-distribution-functions","page":"Tools","title":"Computing radial distribution functions","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"The distributions returned by the mddf function (the mddf and rdf vectors), are normalized by the random reference state or using a site count based on the numerical integration of the volume corresponding to each minimum-distance to the solute. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"If, however, the solute is defined by a single atom (as the oxygen atom of water, for example), the numerical integration of the volume can be replaced by a simple analytical spherical shell volume, reducing noise. The ComplexMixtures.gr function returns the radial distribution function and the KB integral computed from the results, using this volume estimate: ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"g, kb = ComplexMixtures.gr(R)","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"By default, the single-reference count (rdf_count) of the Result structure will be used to compute the radial distribution function. The function can be called with explicit control of all input parameters: ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"g, kb = ComplexMixtures.gr(r,count,density,binstep)","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"where:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Parameter Definition Result structure output data to provide\nr Vector of distances The d vector\ncount Number of site counts at each r The rdf or mddf vectors\ndensity Bulk density The density.solvent_bulk or density.solvent densities.\nbinstep The histogram step The options.binstep\n ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Example:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"...\nR = mddf(trajectory,options)\ng, kb = ComplexMixtures.gr(R.d,R.rdf_count,R.density.solvent_bulk,R.options.binstep)","category":"page"},{"location":"tools/#Overview-of-the-solvent-and-solute-properties","page":"Tools","title":"Overview of the solvent and solute properties","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"The output to the REPL of the Result structure provides an overview of the properties of the solution. The data can be retrieved into a data structure using the overview function. Examples: ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"...\njulia> results = mddf(trajectory)\n\njulia> results\n\n-------------------------------------------------------------------------------\n\n MDDF Overview: \n\n Solvent properties: \n ------------------- \n\n Simulation concentration: 1.5209006318095133 mol L⁻¹\n Molar volume: 657.5051512801567 cm³ mol⁻¹\n\n Concentration in bulk: 1.4918842545752287 mol L⁻¹\n Molar volume in bulk: 670.2932864484995 cm³ mol⁻¹ \n\n Solute properties: \n ------------------ \n\n Simulation Concentration: 1.5209006318095133 mol L⁻¹\n Estimated solute partial molar volume: 657.5051512801567 cm³ mol⁻¹\n\n Using dbulk = 20.0Å: \n Molar volume of the solute domain: 30292.570006549242 cm³ mol⁻¹\n\n Auto-correlation: true\n\n Trajectory files and weights: \n ./vinicius.xtc - w = 1.0\n\n Long range MDDF mean (expected 1.0): 1.1090804621839963 +/- 0.04298849642932878\n Long range RDF mean (expected 1.0): 1.15912932236198 +/- 0.05735018864444404\n\n-------------------------------------------------------------------------------","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"In this case, since solute and solvent are equivalent and the system is homogeneous, the molar volumes and concentrations are similar. This is not the case if the molecules are different or if the solute is at infinite dilution (in which case the bulk solvent density might be different from the solvent density in the simulation). ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"To retrieve the data of the overview structure use, for example:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"julia> overview = overview(results);\n\njulia> overview.solute_molar_volume\n657.5051512801567","category":"page"},{"location":"examples/#examples","page":"Full Example","title":"Example","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"note: Note\nAt this repository various examples are available illustrating the execution and possibilities of the package. Here we discuss one of these examples in detail.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The following examples consider a system composed a protein solvated by a mixture of water and glycerol, built with Packmol. The simulations were performed with NAMD with periodic boundary conditions and a NPT ensemble at room temperature and pressure. Molecular pictures were produced with VMD and plots were produced with Julia's Plots library.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Image of the system of the example: a protein solvated by a mixture of glycreol (green) and water, at a concentration of 50%vv. ","category":"page"},{"location":"examples/#How-to-run-this-example","page":"Full Example","title":"How to run this example","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Download and install Julia\nInstall the required packages. Within Julia, do:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"julia> import Pkg\n\njulia> Pkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"Formatting\"])","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Get the files:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"git clone https://github.com/m3g/ComplexMixturesExamples","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The files associated to the following examples are distributed at this page. ","category":"page"},{"location":"examples/#Data","page":"Full Example","title":"Data","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The Data directory contains the a pdb file of the system (system.pdb) and a sample from the trajectory (glyc50.dcd), with a few frames. It also contains the result of running the mddf calculation on the complete trajectory, results_glyc50.json. This last file was produced by ComplexMixtures, as indicated in the following examples. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The sample trajectory is provided so that the first example can be run, yet do not expect that the results are the same, as the sampling is much lower in this case. The complete trajectory can be retrieved from this link (3GB file). ","category":"page"},{"location":"examples/#Minimum-Distance-Distribuion-function","page":"Full Example","title":"Minimum-Distance Distribuion function","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Here we compute the minimum-distance distribution function, the Kirkwood-Buff integral, and the atomic contributions of the solvent to the density.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"This example illustrates the regular usage of ComplexMixtures, to compute the minimum distance distribution function, KB-integrals and group contributions. ","category":"page"},{"location":"examples/#How-to-run-this-example-2","page":"Full Example","title":"How to run this example","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"cd ComplexMixturesExamples/Protein_in_Glycerol/MDDF\njulia -t auto mddf.jl","category":"page"},{"location":"examples/#Detailed-explanation-of-the-example:","page":"Full Example","title":"Detailed explanation of the example:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Loading the packages required for computing the MDDF. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"using PDBTools\nusing ComplexMixtures","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Load the pdb file of the system using PDBTools:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"atoms = readPDB(\"../Data/system.pdb\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Create arrays of atoms with the protein and Glycerol atoms, using the select function of the PDBTools package:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"protein = select(atoms,\"protein\")\nglyc = select(atoms,\"resname GLYC\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Setup solute and solvent structures, required for computing the MDDF, with Selection function of the ComplexMixtures package:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"solute = Selection(protein,nmols=1)\nsolvent = Selection(glyc,natomspermol=14)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Read and setup the Trajectory structure required for the computations:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"trajectory = Trajectory(\"../Data/glyc50_complete.dcd\",solute,solvent)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Run the calculation and get results:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"results = mddf(trajectory)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"note: Note\nTo change the options of the calculation, set the Options structure accordingly and pass it as a parameter to mddf. For example:options = Options(cutoff=10.)\nmddf(trajectory,options)The complete set of options available is described here.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Save the reults to recover them later if required","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"save(results,\"./glyc50.json\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The trajectory that was loaded was for a toy-example. The complete trajectory is available here, but it is a 3GB file. The same procedure above was performed with that file and produced the results_Glyc50.json file, which is available in the Data directory here. We will continue with this file instead. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Load the actual results obtained with the complete simulation:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"results = load(\"../Data/results_glyc50.json\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Results are loaded, and now we can plot the data obtained.","category":"page"},{"location":"examples/#Produce-plots","page":"Full Example","title":"Produce plots","text":"","category":"section"},{"location":"examples/#MDDF-and-Kirkwood-Buff-integrals","page":"Full Example","title":"MDDF and Kirkwood-Buff integrals","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Load some packages that we will use to produce the plots:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"using Plots, Plots.PlotMeasures, LaTeXStrings","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Some default options that make the plots prettier:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"default(\n fontfamily=\"Computer Modern\",\n linewidth=2, framestyle=:box, label=nothing, grid=false\n)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"First, we will plot the MDDF and the corresponding Kirkwood-Buff integral, which are available in the results.mddf and results.kb fields of the results data set. The distances are available in the results.d vector. We also plot here an horizontal line and save the figure as a pdf file. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"plot(layout=(1,2))\nplot!(results.d,results.mddf,xlabel=L\"r/\\AA\",ylabel=\"mddf\",subplot=1)\nhline!([1],linestyle=:dash,linecolor=:gray,subplot=1)\nplot!(\n results.d,results.kb/1000, #to L/mol\n xlabel=L\"r/\\AA\",ylabel=L\"G_{us}/\\mathrm{L~mol^{-1}}\",\n subplot=2\n)\nplot!(size=(800,300),margin=4mm)\nsavefig(\"./mddf.pdf\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"This will produce the following plot:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/#Atomic-contributions-to-the-MDDF","page":"Full Example","title":"Atomic contributions to the MDDF","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Selecting the atoms corresponding to the hydroxyl groups, and of the aliphatic carbons of Glycerol. Here we list the types of the atoms as specified by the force-field.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"hydroxyls = [\"O1\",\"O2\",\"O3\",\"H1\",\"H2\",\"H3\"]\naliphatic = [\"C1\",\"C2\",\"HA\",\"HB\",\"HC\",\"HD\"]","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The contributions function of ComplexMixtures will extract from the result the contributions of each set of atoms to the total MDDF:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"hydr_contributions = contributions(solvent,results.solvent_atom,hydroxyls)\naliph_contributions = contributions(solvent,results.solvent_atom,aliphatic)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"And, finally, here we plot these group contributions on top of the total MDDF:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"plot(results.d,results.mddf,xlabel=L\"r/\\AA\",ylabel=\"mddf\",size=(600,400))\nplot!(results.d,hydr_contributions,label=\"Hydroxils\")\nplot!(results.d,aliph_contributions,label=\"Aliphatic chain\")\nhline!([1],linestyle=:dash,linecolor=:gray)\nsavefig(\"./mddf_atom_contrib.pdf\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"This will produce the following figure:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Note how hydroxyl clearly are the sole contribution to the peak at ~1.9 Angstroms, corresponding to hydrogen-bonding interactions. The aliphatic groups contribute importantly to the shoulder at larger distances, which correspond to non-specific interactions. ","category":"page"},{"location":"examples/#D-residue-contribution-density-map","page":"Full Example","title":"2D residue contribution density map","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"In this example we compute the density map of Glycerol in the vicinity of a set of residues of a protein, from the minimum-distance distribution function. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The MDDF can be decomposed in the contributions of each atom of the solute or of the solvent. Here, we sum up te contributions of all the atoms of each residue of the solute, which is a protein, and plot a density map with the final information. The output figure obtained is:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/#How-to-run-this-example:","page":"Full Example","title":"How to run this example:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"cd ComplexMixturesExamples/Protein_in_Glycerol/Density2D\njulia density2D.jl","category":"page"},{"location":"examples/#Detailed-explanation-of-the-example:-2","page":"Full Example","title":"Detailed explanation of the example:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Here, we use the contourf function of the Plots package of Julia. A detailed explanation of the input file density2D.jl is provide below: ","category":"page"},{"location":"examples/#Loading-packages-that-will-be-used:","page":"Full Example","title":"Loading packages that will be used:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"using Plots\nusing LaTeXStrings\nusing Formatting\nusing ComplexMixtures, PDBTools","category":"page"},{"location":"examples/#Some-default-options-so-the-plot-looks-nice","page":"Full Example","title":"Some default options so the plot looks nice","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"plot_font = \"Computer Modern\"\ndefault(\n fontfamily=plot_font,\n linewidth=2, framestyle=:box, label=nothing\n)","category":"page"},{"location":"examples/#Read-the-PDB-file-(using-PDBTools)","page":"Full Example","title":"Read the PDB file (using PDBTools)","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"pdb = readPDB(\"./system.pdb\")","category":"page"},{"location":"examples/#Load-results-of-the-ComplexMixtures-run","page":"Full Example","title":"Load results of the ComplexMixtures run","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"R = load(\"./results_glyc50.json\") ","category":"page"},{"location":"examples/#Define-which-are-the-solute-molecules-(the-protein)","page":"Full Example","title":"Define which are the solute molecules (the protein)","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"protein = select(pdb,\"protein\")\nsolute = Selection(protein,nmols=1)","category":"page"},{"location":"examples/#Define-which-are-the-solvent-molecules-(Glycerol-here)","page":"Full Example","title":"Define which are the solvent molecules (Glycerol here)","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"glycerol = select(pdb,\"resname GLYC\")\nsolvent = Selection(glycerol,natomspermol=14)","category":"page"},{"location":"examples/#Retrive-the-resiude-contribution-data","page":"Full Example","title":"Retrive the resiude contribution data","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Collect which are the protein residues ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"residues = collect(eachresidue(protein))","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Set a matrix that will store the results, with a number of lines corresponding to the length of the MDDF histogram, and with a number of columns corresponding to the number of residues:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"rescontrib = zeros(length(R.mddf),length(residues))","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Now, collect the contribution of each residue as a column of the above matrix. The notation pairs(residues) returns tuples containg the index ires and the corresponding residue. The .= symbol sets each element of the corresponding column of the rescontrib matrix to the output of contributions (by broadcasting). ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"for (ires,residue) in pairs(residues)\n rescontrib[:,ires] .= contributions(solute,R.solute_atom,residue)\nend","category":"page"},{"location":"examples/#Plot-only-for-distances-within-1.5-and-3.5:","page":"Full Example","title":"Plot only for distances within 1.5 and 3.5:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Here, we will plot only the contributions from residue 70 to residue 110, and from distances ranging from 1.5 to 3.5 which is where most of the action occurs:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"irange=70:110\nidmin = findfirst( d -> d > 1.5, R.d)\nidmax = findfirst( d -> d > 3.5, R.d)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"To obtain pretty labels for the residues in the x-axis, we retrieve the one-letter residue names and concatenate them with the residue number converted to strings:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"labels = PDBTools.oneletter.(resname.(residues)).*format.(resnum.(residues))","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"And, finally, we produce the plot, with a series of options that make this particular contour plot look nice:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"contourf(\n irange, # x\n R.d[idmin:idmax], # y\n rescontrib[idmin:idmax,irange], # z\n xlabel=\"Residue\", ylabel=L\"r/\\AA\",\n xticks=(irange,labels[irange]), xrotation=60,\n xtickfont=font(6,plot_font),\n color=cgrad(:tempo), linewidth=0.1, linecolor=:black,\n colorbar=:none, levels=5,\n size=(500,280)\n)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The final figure is saved as a pdf file:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"savefig(\"./density2D.pdf\")","category":"page"},{"location":"examples/#D-residue-contribution-density-map-2","page":"Full Example","title":"3D residue contribution density map","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"In this example we compute three-dimensional representations of the density map of Glycerol in the vicinity of a set of residues of a protein, from the minimum-distance distribution function. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Here, the MDDF is decomposed at each distance according to the contributions of each solute (the protein) residue. The grid is created such that, at each point in space around the protein, it is possible to identify: ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Which atom is the closest atom of the solute to that point.\nWhich is the contribution of that atom (or residue) to the distribution function.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Therefore, by filtering the 3D density map at each distance one can visualize over the solute structure which are the regions that mostly interact with the solvent of choice at each distance. Typical images of such a density are:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"In the figure on the left, the points in space around the protein are selected with the following properties: distance from the protein smaller than 2.0Å and relative contribution to the MDDF at the corresponding distance of at least 10% of the maximum contribution. Thus, we are selecting the regions of the protein corresponding to the most stable hydrogen-bonding interactions. The color of the points is the contribution to the MDDF, from blue to red. Thus, the most reddish-points corresponds to the regions where the most stable hydrogen bonds were formed. We have marked two regions here, on opposite sides of the protein, with arrows.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Clicking on those points we obtain which are the atoms of the protein contributing to the MDDF at that region. In particular, the arrow on the right points to the strongest red region, which corresponds to an Aspartic acid. These residues are shown explicitly under the density (represented as a transparent surface) on the figure in the center.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The figure on the right displays, overlapped with the hydrogen-bonding residues, the most important contributions to the second peak of the distribution, corresponding to distances from the protein between 2.0 and 3.5Å. Notably, the regions involved are different from the ones forming hydrogen bonds, indicating that non-specific interactions with the protein (and not a second solvation shell) are responsible for the second peak. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"A short tutorial video showing how to open the input and output PDB files in VMD and produce images of the density is available here: ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/#How-to-run-this-example:-2","page":"Full Example","title":"How to run this example:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"cd ComplexMixturesExamples/Protein_in_Glycerol/Density3D\njulia density3D.jl","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Alternatively, open Julia and copy/paste or the commands in density3D.jl or use include(\"./density3D.jl\"). These options will allow you to remain on the Julia section with access to the grid data structure that was generated and corresponds to the output grid.pdb file. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"This will create (actually overwrite) the grid.pdb file. Here we provide a previously setup VMD session that contains the data with the visualization choices used to generate the figure above. Load it with:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"vmd -e grid.vmd","category":"page"},{"location":"examples/#Detailed-explanation-of-the-example:-3","page":"Full Example","title":"Detailed explanation of the example:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Initially we load the ComplexMixtures and PDBTools packages:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"using ComplexMixtures, PDBTools","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"With the readPDB function of PDBTools, we read the PDB file of the system simulated:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"pdb = readPDB(\"../Data/system.pdb\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"and using ComplexMixtures, we load the results from the calculation of the MDDF of Glycerol around the protein, which was computed previously:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"R = load(\"../Data/results_glyc50.json\") ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The solute here is the protein, and we need to setup the structures that define which atoms and type of solute it is. First, we select from the atoms of the pdb file of the system, those belonging to the protein, using select from PDBTools:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"protein = select(pdb,\"protein\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"and then we define the solute structure that is actually used in ComplexMixtures, by passing those atoms and specifying that the solute is a single molecule to the Selection function of ComplexMixtures:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"solute = Selection(protein,nmols=1)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The 3D grid representing the density around the protein is computed with the grid3D function provided by ComplexMixtures. It receives the solute structure (of type Selection), the list of solute atoms (of type PDBTools.Atoms, as the protein selection above), the name of the output file and some optional parameters to define the grid. Here we compute the grid only between 1.5 and 3.5Å, characterizing the first and second solvation shells. The grid has by default a step of 0.5Å. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"grid = grid3D(\n solute=solute,\n solute_atoms=protein,\n mddf_result=R,\n output_file=\"grid.pdb\",\n dmin=1.5,\n dmax=3.5\n)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The command above will generate the grid, save it to grid.pdb and let it available in the grid.pdb array of atoms, for further inspection, if desired. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"By changing dmin, dmax, and step, one controls the grid size and resolution. This may generate very large output files.","category":"page"},{"location":"options/#options","page":"Options","title":"Options","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"There are some options to control what exactly is going to be computed to obtain the MDDF. These options can be defined by the user and passed to the mddf function, using, for example: ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"options = Options(lastframe=1000)\nresults = mddf(trajectory,options)","category":"page"},{"location":"options/#Common-options-that-the-user-might-want-to-set:","page":"Options","title":"Common options that the user might want to set:","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"firstframe: Integer, first frame of the trajectory to be considered.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"lastframe: Integer, last frame of the trajectory to be considered.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"stride: Integer, consider every stride frames, that is, if stride=5 only one in five frames will be considered.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"binstep: Real, length of the bin step of the histograms, default = 0.02 Angstroms.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"dbulk: Real, distance from which the solution is to be considered as a bulk solution, that is, where the presence of the solute does not affect the structure of the solution anymore. This parameter is important in particular for systems with a single solute molecule (a protein, for example), where the density of the solvent in the box is not the bulk density of the solvent, which must be computed independently. Default: 10 Angstroms. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"cutoff: Real, the maximum distance to be considered in the construction of histograms. Default: 10 Angstroms. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"usecutoff: true/false: If true, the cutoff distance might be different from dbulk and the density of the solvent in bulk will be estimated from the density within dbulk and cutoff. If false, the density of the solvent is estimated from the density outside dbulk by exclusion. Default: false. ","category":"page"},{"location":"options/#Options-that-most-users-will-probably-never-change:","page":"Options","title":"Options that most users will probably never change:","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"irefatom: Integer, index of the reference atom in the solvent molecule used to compute the shell volumes and domain volumes in the Monte-Carlo volume estimates. The final rdf data is reported for this atom as well. By default, we choose the atom which is closer to the center of coordinates of the molecule, but any choice should be fine. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"n_random_samples: Integer, how many samples of random molecules are generated for each solvent molecule to compute the shell volumes and random MDDF counts. Default: 10. Increase this only if you have short trajectory and want to obtain reproducible results for that short trajectory. For long trajectories (most desirable and common), this value can even be decreased to speed up the calculations. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"seed: Seed for random number generator. If -1, the seed will be generated from the entropy of the system. If your results are dependent on the seed, is is probable that you do not have enough sampling. Mostly used for testing purposes. Two runs are only identical if ran with the same seed and in serial mode. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"StableRNG (::Bool), defaults to false. Use a stable random number generator from the StableRNGs package, to produce identical runs on different architectures and Julia versions. Only used for testing. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"nthreads: How many threads to use. By default, it will be the number of physical cores of the computer.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"lcell: Integer, the cell length of the linked-cell method (actually the cell length is cutoff/lcell). Default: 1. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"GC: Bool, force garbage collection, to avoid memory overflow. Default: true. That this might be required is probably a result of something that can vastly improved in memory management. This may slow down parallel runs significantly if the GC runs too often.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"GC_threshold: Float64, minimum fraction of the total memory of the system required to force a GC run. That is, if GC_threshold=0.1, which is the default, every time the free memory becomes less or equal to 10% of the total memory available, a GC run occurs. ","category":"page"},{"location":"python/#python","page":"From Python","title":"From Python","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"note: Note\nMost features of the package are available through this Python interface. However, some flexibility may be reduced and, also, the tunning of the plot appearance is left to the user, as it is expected that he/she is fluent with some tools within Python if chosing this interface.Python 3 or greater is required.Please report issues, incompatibilities, or any other difficulty in using the package and its interface.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"The following examples consider a system composed a protein solvated by a mixture of water and glycerol, built with Packmol. The simulations were performed with NAMD with periodic boundary conditions and a NPT ensemble at room temperature and pressure. Molecular pictures were produced with VMD.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"
      \n\n
      ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"Image of the system of the example: a protein solvated by a mixture of glycreol (green) and water, at a concentration of 50%vv. The complete example is available at this repository.","category":"page"},{"location":"python/#Loading-the-ComplexMixtures.py-file","page":"From Python","title":"Loading the ComplexMixtures.py file","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"The Python interface of ComplexMixtures is implemented in the ComplexMixtures.py file. Just download it from the link and save it in a known path.","category":"page"},{"location":"python/#Installing-juliacall","page":"From Python","title":"Installing juliacall","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"juliacall is a package that allows calling Julia programs from Python. Install it with","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"pip install juliacall","category":"page"},{"location":"python/#Installing-Julia-and-underlying-packages","page":"From Python","title":"Installing Julia and underlying packages","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"Once juliacall is installed, from within Python, execute:","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"import ComplexMixtures","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"here we assume that the ComplexMixtures.py file is in the same directory where you launched Python.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"note: Note\nOn the first time you execute this command, the Julia executable and the required Julia packages (ComplexMixtures and PDBTools) will be downloaded and installed. At the end of the process quit Python (not really required, but we prefer to separate the installation from the use of the module). ","category":"page"},{"location":"python/#How-to-run-this-example","page":"From Python","title":"How to run this example","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"The Data directory contains the a pdb file of the system (system.pdb) and a sample from the trajectory (glyc50.dcd), with a few frames. It also contains the result of running the mddf calculation on the complete trajectory, results_glyc50.json. This last file was produced by ComplexMixtures, as indicated in the following examples. ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"The sample trajectory is provided so that the first example can be run, yet do not expect that the results are the same, as the sampling is much lower in this case. The complete trajectory can be retrieved from this link (3GB file). ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"We assume that you navigated to the directory of the example, and copied the Python module file to it: ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"git clone https://github.com/m3g/ComplexMixturesExamples\ncd ComplexMixturesExamples/Protein_in_Glycerol/MDDF\ncp /path/to/ComplexMixtures.py ./\nexport JULIA_NUM_THREADS=8","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"The last line will allow Julia to execute multi-threaded, which will improve a lot the performance on most machines. Set the number of threads to the number of cores of your computer.","category":"page"},{"location":"python/#Minimum-Distance-Distribuion-function","page":"From Python","title":"Minimum-Distance Distribuion function","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"Note that the example here follows an identical syntax to the Julia example, except that we qualify the name of the loaded module and implicitly load the PDBTools package.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"The script to compute the MDDFs as associated data from within python is, then:","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"import ComplexMixtures as cm\n\n# Load the pdb file of the system using `PDBTools`:\natoms = cm.readPDB(\"../Data/system.pdb\")\n\n# Create arrays of atoms with the protein and Glycerol atoms, \n# using the `select` function of the `PDBTools` package:\nprotein = cm.select(atoms,\"protein\")\nglyc = cm.select(atoms,\"resname GLYC\")\n\n# Setup solute and solvent structures, required for computing the MDDF, \n# with `Selection` function of the `ComplexMixtures` package:\nsolute = cm.Selection(protein,nmols=1)\nsolvent = cm.Selection(glyc,natomspermol=14)\n\n# Read and setup the Trajectory structure required for the computations:\ntrajectory = cm.Trajectory(\"../Data/glyc50_complete.dcd\",solute,solvent)\n\n# Run the calculation and get results:\nresults = cm.mddf(trajectory)\n\n# Save the reults to recover them later if required\ncm.save(results,\"./glyc50.json\")","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"note: Note\nTo change the options of the calculation, set the Options structure accordingly and pass it as a parameter to mddf. For example:options = cm.Options(cutoff=10.)\nresults = cm.mddf(trajectory,options)The complete set of options available is described here.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"The trajectory that was loaded was for a toy-example. The complete trajectory is available here, but it is a 3GB file. The same procedure above was performed with that file and produced the results_Glyc50.json file, which is available in the Data directory here. We will continue with this file instead. ","category":"page"},{"location":"python/#Produce-plots","page":"From Python","title":"Produce plots","text":"","category":"section"},{"location":"python/#MDDF-and-Kirkwood-Buff-integrals","page":"From Python","title":"MDDF and Kirkwood-Buff integrals","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"import ComplexMixtures as cm\nimport matplotlib.pyplot as plt\n\n# Load the actual results obtained with the complete simulation:\nresults = cm.load(\"../Data/results_glyc50.json\")\n\n# Plot MDDF and KB\nfig, axs = plt.subplots(2)\naxs[0].plot(results.d, results.mddf)\naxs[0].set(ylabel=\"MDDF\")\n\n# Plot KB integral\naxs[1].plot(results.d, results.kb)\naxs[1].set(xlabel=\"distance / Angs\", ylabel=\"MDDF\")\n\nplt.savefig(\"mddf_kb.png\")","category":"page"},{"location":"python/#Atomic-contributions-to-the-MDDF","page":"From Python","title":"Atomic contributions to the MDDF","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"Selecting the atoms corresponding to the hydroxyl groups, and of the aliphatic carbons of Glycerol. Here we list the types of the atoms as specified by the force-field. ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"import ComplexMixtures as cm\nimport matplotlib.pyplot as plt\n\natoms = cm.readPDB(\"../Data/system.pdb\")\nprotein = cm.select(atoms,\"protein\")\nglyc = cm.select(atoms,\"resname GLYC\")\nsolute = cm.Selection(protein,nmols=1)\nsolvent = cm.Selection(glyc,natomspermol=14)\n\n# load results\nresults = cm.load(\"../Data/results_glyc50.json\")\n\n# Select atoms by name\nhydroxyls = cm.list([\"O1\",\"O2\",\"O3\",\"H1\",\"H2\",\"H3\"])\naliphatic = cm.list([\"C1\",\"C2\",\"HA\",\"HB\",\"HC\",\"HD\"])\n\n# Extract the contributions of the groups above\nhydr_contributions = cm.contributions(solvent,results.solvent_atom,hydroxyls)\naliph_contributions = cm.contributions(solvent,results.solvent_atom,aliphatic)\n\n# Plot\nplt.plot(results.d, results.mddf)\nplt.plot(results.d, hydr_contributions)\nplt.plot(results.d, aliph_contributions)\nplt.xlabel(\"distance / Angs\")\nplt.ylabel(\"MDDF\")\nplt.savefig(\"group_contributions.png\")","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"note: Note\nThe syntax here diverges from the Julia-only examples by requiring the lists of names to be converted to Julia arrays, which happens by using the cm.list(python_list) function calls.","category":"page"},{"location":"#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"ComplexMixtures.jl is a package to study the solute and solvent interactions of mixtures of molecules of complex shape. Conventional radial distribution functions are not appropriate to represent the structure of a solvent around a solute with many atoms, and a variable, non-spherical shape. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Typical solutes of complex shape are proteins, nucleic acids, and polymers in general. Smaller molecules like lipids, carbohydrates, etc, are also complex enough such that representing the structure of the solution of those molecules with distribution functions is not trivial.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Minimum-Distance Distribution Functions (MDDFs) are a very general and practical way to represent solute-solvent interactions for molecules with arbitrarily complex sizes and geometries. Briefly, instead of computing the density distribution function of a particular atom or the center-of-mass of the molecules, one computes the distribution function of the minimum-distance between any solute and solvent atoms. This provides a size and shape-independent distribution which is very natural to interpret in terms of molecular interactions. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Additionally, the MDDFs can be decomposed into contributions of each type of atom (or groups of atoms) of the solute and solvent molecules, such that the profiles of the distributions can be interpreted in terms of the chemical nature of the species involved in the interactions at each distance. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Finally, as with radial distribution functions, MDDFs can be used to compute Kirkwood-Buff integrals to connect the accumulation or depletion of the solvents components to thermodynamic properties, like protein structural stability, solubility, and others.","category":"page"},{"location":"#Features","page":"Introduction","title":"Features","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Check out our examples repository, featuring the analysis of solvation structures for proteins, polymers, membrane, and complex solutions! The examples are also described in our featured article.","category":"page"},{"location":"#.-Minimum-distance-distribution-functions:-understanding-solvation-at-a-molecular-level","page":"Introduction","title":"1. Minimum-distance distribution functions: understanding solvation at a molecular level","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"This figure illustrates one of the main features of minimum-distance distribution functions, by showing the distribution of DMF molecules at the surface of an polyacrylamide molecule. The direct interactions are evident by the peak at hydrogen-bonding distances and, additionally, the contribution of each group of atoms of the DMF can be clearly distinguished by decomposing the total MDDF into atomic or chemical group contributions. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"
      \n\n
      \nMinimum distance distribution function and its decomposition into the chemical\ngroups of the solvent (top) and solute (bottom) molecules.

      \n
      ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Decomposition of the total MDDF into the contributions of the solute atoms (in this case, a protein) is also possible. Any chemical group decomposition is possible. Here, we decompose the MDDF into the contribution of each protein residue. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"
      \n\n
      \nDensity map of a solvent in the vicinity of each protein residue. \n
      ","category":"page"},{"location":"#.-Thermodynamic-interpretation-through-Kirkwood-Buff-theory","page":"Introduction","title":"2. Thermodynamic interpretation through Kirkwood-Buff theory","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Minimum-distance distribution functions can be used to compute Kirkwood-Buff integrals, and thus, thermodynamic parameters associated to solvation. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Kirkwood-Buff integrals carry the information of the total accumulation or depletion of each solvent around a solute. For example, the figure below displays the KB integrals of an ionic liquid solvating different conformational states of a protein [link]. The figure illustrates that the solvation structures are dependent on the protein folding state. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"
      \n\n
      \nKirkwood-Buff integrals of an ionic liquid solvating a protein in different conformational states.

      \n
      ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"From differences in KB integrals among cossolvents, the Preferential Solvation parameter can be computed. This is an important parameter because it can be measured experimentally and is ultimately associated with the equilibrium thermodynamics of the solvation. In the following figure, we show that, for example, the preferential solvation of a protein in different folding states is dependent in a non-trivial way on the concentration of an ionic liquid in aqueous solutions. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"
      \n\n
      \nKirkwood-Buff integrals of an ionic liquid solvating a protein in different conformational states.

      \n
      ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"In particular, the plot shows that besides being preferentially excluded from the protein surface at high concentrations in the native state, suggesting protein folding stabilization, the interactions with the protein in the denatured states are stronger, leading to denaturation at all concentrations. ","category":"page"},{"location":"#References","page":"Introduction","title":"References","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"L. Martínez, ComplexMixtures.jl: Investigating the structure of solutions of complex-shaped molecules from a solvent-shell perspective. J. Mol. Liq. 117945, 2021. [Full Text]\nL. Martínez, S. Shimizu, Molecular interpretation of preferential interactions in protein solvation: a solvent-shell perspective by means of minimum-distance distribution functions. J. Chem. Theor. Comp. 13, 6358–6372, 2017. [Full Text]","category":"page"},{"location":"#See-also","page":"Introduction","title":"See also","text":"","category":"section"},{"location":"#Seminar","page":"Introduction","title":"Seminar","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Presentation about ComplexMixtures.jl and protein-solvent interactions: https://youtu.be/umSRjsITzyA","category":"page"},{"location":"#Applications","page":"Introduction","title":"Applications","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"A. F. Pereira, V. Piccoli, L. Martínez, Trifluoroethanol direct interactions with protein backbones destabilize alpha-helices. J. Mol. Liq. 365, 120209, 2022. [Full Text]\nV. Piccoli, L. Martínez, Ionic liquid solvation of proteins in native and denatured states. J. Mol. Liq. 363, 119953, 2022. [Full Text]\nV. Piccoli, L. Martínez, Correlated counterion effects in the solvation of proteins by ionic-liquids. J. Mol. Liq. 320, 114347, 2020. [Full Text]\nI. P. de Oliveira, L. Martínez, The shift in urea orientation at protein surfaces at low pH is compatible with a direct mechanism of protein denaturation. Phys. Chem. Chem. Phys. 22, 354-367, 2020. [Full Text]\nI. P. de Oliveira, L. Martínez, Molecular basis for competitive solvation of the Burkholderia cepacia lipase by sorbitol and urea. Phys. Chem. Chem. Phys. 18, 21797-21808, 2016. [Full Text]","category":"page"}] +[{"location":"references/#References","page":"References","title":"References","text":"","category":"section"},{"location":"references/#Primary-citations","page":"References","title":"Primary citations","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"If this package was useful to you, please cite the following papers:","category":"page"},{"location":"references/","page":"References","title":"References","text":"L. Martínez, ComplexMixtures.jl: Investigating the structure of solutions of complex-shaped molecules from a solvent-shell perspective J. Mol. Liq. 117945, 2021. [Full Text]\nL. Martínez, S. Shimizu, Molecular interpretation of preferential interactions in protein solvation: a solvent-shell perspective by means of minimum-distance distribution functions. J. Chem. Theor. Comp. 13, 6358–6372, 2017. [Full Text]","category":"page"},{"location":"references/#Applications-and-examples","page":"References","title":"Applications and examples","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"A. F. Pereira, V. Piccoli, L. Martínez, Trifluoroethanol direct interactions with protein backbones destabilize alpha-helices. J. Mol. Liq. 365, 120209, 2022. [Full Text]\nV. Piccoli, L. Martínez, Ionic liquid solvation of proteins in native and denatured states. J. Mol. Liq. 363, 119953, 2022. [Full Text]\nV. Piccoli, L. Martínez, Correlated counterion effects in the solvation of proteins by ionic-liquids. J. Mol. Liq. 320, 114347, 2020. [Full Text]\nI. P. de Oliveira, L. Martínez, The shift in urea orientation at protein surfaces at low pH is compatible with a direct mechanism of protein denaturation. Phys. Chem. Chem. Phys. 22, 354-367, 2020. [Full Text]\nI. P. de Oliveira, L. Martínez, Molecular basis for competitive solvation of the Burkholderia cepacia lipase by sorbitol and urea. Phys. Chem. Chem. Phys. 18, 21797-21808, 2016. [Full Text]","category":"page"},{"location":"references/#See-also","page":"References","title":"See also","text":"","category":"section"},{"location":"references/","page":"References","title":"References","text":"Packmol: A package for building initial configurations for molecular dynamics simulations.\nCellListMap.jl: Efficient and customizable implementation of cell lists, which allows the computation of general properties dependent on distances of particles within a cutoff, for example short-range potentials, forces, neighbour lists, etc.\nMDLovoFit: Automatic identification of mobile and rigid substructures in molecular dynamics simulations and fractional structural fluctuation analysis. ","category":"page"},{"location":"results/#results","page":"Results","title":"Results","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The results of a MDDF calculation are returned in a data structure which contains the MDDF, KB integrals, and atomic contributions. The following section will assume that the computation was performed by calling the mddf function with ","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"results = mddf(trajectory)","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"such that the results variable contain the Result data structure. By default, the histograms contain 500 bins (binstep=0.002 and cutoff=10.) such that all data-vectors will contain 500 lines.","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"To learn how to save and load saved data, read the next section.","category":"page"},{"location":"results/#The-Result-data-structure:-main-data","page":"Results","title":"The Result data structure: main data","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The most important data to be read from results are the distances, minimum-distance distribution function, and KB integrals. These data is stored in the following vectors:","category":"page"},{"location":"results/#Distances-of-the-histograms:-results.d","page":"Results","title":"Distances of the histograms: results.d","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The following vector will contain values ranging from 0. to cutoff, and the distance at each bin is the distance in that bin for which half of the volume of the bin is within d, and half of the volume is above d, if the volume was spherical: ","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"julia> results.d\n500-element Array{Float64,1}:\n 0.015874010519682\n 0.033019272488946275\n ⋮\n 9.970010030080179\n 9.99001000999998","category":"page"},{"location":"results/#Minimum-distance-distribution-function:-results.mddf","page":"Results","title":"Minimum-distance distribution function: results.mddf","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The results.mddf vector will contain the main result, which the minimum-distance distribution function. For a properly-sampled simulation, it will be zero at very short distances and converge to 1.0 for distances smaller than the cutoff:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"julia> results.mddf\n500-element Array{Float64,1}:\n 0.0\n 0.0\n ⋮\n 0.999052514965403\n 1.001030818286187\n","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"A typical plot of results.mddf as a function of results.d will look like:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"Thus, this plot was obtained with the following code:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"using Plots\nplot(results.d,results.mddf,xlabel=\"d/A\",ylabel=\"mddf(d) / L/mol\") ","category":"page"},{"location":"results/#Kirkwood-Buff-integral:-results.kb","page":"Results","title":"Kirkwood-Buff integral: results.kb","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The results.kb vector will contain the Kirkwood-Buff integral computed as a function of the minimum-distance to the solute. For properly sampled simulations, it is expected to converge at large distances. ","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"julia> results.kb\n500-element Array{Float64,1}:\n 0.0\n -0.3249356504752985\n -2.9804719721525\n ⋮\n 0.72186381783\n 1.13624162115","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"A typical plot of results.kb as a function of results.d will look like:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"Thus, this plot was obtained with the following code:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"using Plots\nplot(results.d,results.kb,xlabel=\"d/A\",ylabel=\"mddf(d) / L/mol\") ","category":"page"},{"location":"results/#Units","page":"Results","title":"Units","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"The distance is assumed to be in Å, as this is the most common distance units in molecular simulations. The coordinates of the atoms are assumed be provided in Å. \nThe minimum-distance distribution function is unit-less, since it is the ratio of the density at each distance divided by an ideal-gas density.\nThe Kirkwood-Buff integrals are returned in cm³ mol⁻¹, if the coordinates were provided in Å.","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"warning: Warning\nIf the coordinates are not in Å, the calculation will proceed normally, but the units of the KB integrals, which has units of volume per mol, should be converted to conform the length unit provided. ","category":"page"},{"location":"results/#Coordination-number-and-other-data","page":"Results","title":"Coordination number and other data","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"Obtaining the MDDF involves the computation of some intermediate properties that are frequently useful for additional solution structure analysis. In particular, the coordination numbers are computed. For example, the coordination number as a function from the distance to the solute can be retrieved from a Results data structure with:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"coordination_number = results.coordination_number","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"and this data can be plotted against the distances by:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"plot(result.d,results.coordination_number)","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"The coordination number of subgroups can also be obtained, as explained in the Coordination number section.","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"The complete data available is:","category":"page"},{"location":"results/","page":"Results","title":"Results","text":"Parameter Meaning Type of value Comment\nd Vector of distances of the histograms. Vector{Float64} To be used as the x coordinate on plotting any of the data.\nmd_count Non-normalized count of minimum distances at each d. Vector{Float64} This is the number of minimum distances found at each histogram bin, without normalization. Usually this is not interesting to analyze, because it is dependent on the bin size.\nmd_count_random Number of minimum distances found at each histogram bin for the random distribution. Vector{Float64} This is the normalization required to convert the md_count array into the minimum-distance distribution.\ncoordination_number Cumulative number of sites found for each histogram distance. Vector{Float64} This is the coordination number, that is, the number of sites found cumulative up to each distance, without any normalization.\ncoordination_number_random Cumulative site count for the random distribution. Vector{Float64} Usually not interesting for analysis.\nmddf The final distribution function. Vector{Float64} This is the MDDF computed (md_count normalized by md_count_random). It is the main result of the calculation.\nkb The final Kirkwood-Buff integral. Vector{Float64} This is the final KB integral, as a function of the integration distance from the solute. Computed as coordination_number - coordination_number_random\nsolute_atom Atomic contributions of the solute. Matrix{Float64} This is a matrix with nbins lines and solute.natomspermol columns, containing the atomic contributions of each solute atom to the complete MDDF.\nsolvent_atom Atomic contributions of the solvent. Matrix{Float64} This is a matrix with nbins lines and solvent.natomspermol columns, containing the atomic contributions of each solvent atom to the complete MDDF.\ndensity.solute Density (concentration) of the solute in the complete simulation box. Float64 In units of molecules/textrmAA^3\ndensity.solvent Density (concentration) of the solvent in the complete simulation box. Float64 In units of molecules/textrmAA^3\ndensity.solvent_bulk Density (concentration) of the solute in the bulk region. Float64 In units of molecules/textrmAA^3\nvolume Volume measures. Volume Contains the total volume of the simulation, the bulk volume, the volume of the solute domain and the shell volume of each bin of the histogram. These are computed by numerical integration from the random distributions.\nfiles List of files read. Vector{String} \nweights Weights of each file in the final counts. Vector{Float64} If the trajectories have different lengths or number of frames, the weights are adapted accordingly.\n ","category":"page"},{"location":"results/#Other-Result-parameters-available-which-are-set-at-Options:","page":"Results","title":"Other Result parameters available which are set at Options:","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"Parameter Meaning Type of value Comment\nnbins Number of bins of the histograms. Int \ndbulk Distance from solute of bulk solution. Float64 \ncutoff Maximum distance to be considered for histograms. Float64 \nautocorrelation The solute is the same as the solvent? Bool Automatically set if solute == solvent.\nsolute Properties of the solute SolSummary Contains the number of atoms, number of atoms per molecule and number of molecules of the solute.\nsolvent Properties of the solvent. SolSummary Contains the number of atoms, number of atoms per molecule and number of molecules of the solvent.\nirefatom This is a reference atom that is used to generate random rotations and translations internally. Int Counts of the distributions for this atom are performed automatically to obtain radial (or proximal) distribution functions. Can be used for testing purposes.\nrdf_count This is the md_count minimum distance count of irefatom. Vector{Float64} This corresponds to the conventional radial distribution function if the solute contains only one atom.\nrdf_count_random Minimum distance of irefatom count for the random distribution. Vector{Float64} \nrdf Distribution function computed from the irefatom distribution. It is a conventional rdf if the solvent has only one atom. Vector{Float64} \nkb_rdf Kirkwood-Buff integral computed from the irefatom distribution. Vector{Float64} This must converge, at long distances, to the same value as kb, and can be used for testing.\noptions Calculation options. Options Carries (some redundant) options set by the user.\nlastframe_read Last frame read from the trajectory. Int \nn_frames_read Number of frames read from the trajectory. Int Can differ from lastframe_read if stride != 1\n ","category":"page"},{"location":"help/#Help-entries","page":"Help entries","title":"Help entries","text":"","category":"section"},{"location":"help/","page":"Help entries","title":"Help entries","text":"Modules=[ComplexMixtures]","category":"page"},{"location":"help/#ComplexMixtures.CMTypes","page":"Help entries","title":"ComplexMixtures.CMTypes","text":"Internal structure or function, interface may change.\n\nUnion of types to define an isaprox for testing.\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.ChemFile","page":"Help entries","title":"ComplexMixtures.ChemFile","text":"struct ChemFile{T<:(AbstractVector)} <: Trajectory\n\nStructure to contain a trajectory as read by Chemfiles.jl\n\nfilename::String\nformat::AbstractString\nstream::ComplexMixtures.Stream{<:Chemfiles.Trajectory}\nnframes::Int64\nsides::Vector{T} where T<:(AbstractVector)\nsolute::Selection\nsolvent::Selection\nx_solute::Vector{T} where T<:(AbstractVector)\nx_solvent::Vector{T} where T<:(AbstractVector)\nnatoms::Int64\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.ChemFile-Tuple{String, Selection, Selection}","page":"Help entries","title":"ComplexMixtures.ChemFile","text":"ChemFile(filename::String, solute::Selection, solvent::Selection;format=\"\" , T::Type = SVector{3,Float64})\n\nFunction open will set up the IO stream of the trajectory, fill up the number of frames field and additional parameters if required.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.Density","page":"Help entries","title":"ComplexMixtures.Density","text":"mutable struct Density\n\nStructure to contain the density values obtained from the calculation.\n\nsolute::Float64: Default: 0.0\nsolvent::Float64: Default: 0.0\nsolvent_bulk::Float64: Default: 0.0\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.MinimumDistance","page":"Help entries","title":"ComplexMixtures.MinimumDistance","text":"struct MinimumDistance\n\nInternal structure or function, interface may change.\n\nExtended help\n\nThis structure contains the information, for each molecule, of if it is within the cutoff distance of the solute, the atom indexes of the associated minimum distance, the distance, and a label to mark if the reference atom of the molecule is within the cutoff distance of the solute.\n\nThe lists of minimum-distances are stored in arrays of type Vector{MinimumDistance}. The index of this vector corresponds to the index of the molecule in the original array.\n\nwithin_cutoff::Bool\ni::Int64\nj::Int64\nd::Float64\nref_atom_within_cutoff::Bool\nd_ref_atom::Float64\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.NamdDCD","page":"Help entries","title":"ComplexMixtures.NamdDCD","text":"struct NamdDCD{T<:(AbstractVector)} <: Trajectory\n\nStructure to contain the data of a trajectory in NAMD/DCD format.\n\nfilename::String\nstream::ComplexMixtures.Stream{<:FortranFiles.FortranFile}\nnframes::Int64\nsides::Vector{T} where T<:(AbstractVector)\nsolute::Selection\nsolvent::Selection\nx_solute::Vector{T} where T<:(AbstractVector)\nx_solvent::Vector{T} where T<:(AbstractVector)\nsides_in_dcd::Bool\nlastatom::Int64\nsides_read::Vector{Float64}\nx_read::Vector{Float32}\ny_read::Vector{Float32}\nz_read::Vector{Float32}\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.NamdDCD-Tuple{String, Selection, Selection}","page":"Help entries","title":"ComplexMixtures.NamdDCD","text":"NamdDCD(filename::String, solute::Selection, solvent::Selection;T::Type = SVector{3,Float64})\n\nThis function initializes the structure above, returning the data and the vectors with appropriate lengths.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.Options","page":"Help entries","title":"ComplexMixtures.Options","text":"struct Options\n\nStructure that contains the detailed input options.\n\nfirstframe::Int64: Default: 1\nlastframe::Int64: Default: -1\nstride::Int64: Default: 1\nirefatom::Int64: Default: -1\nn_random_samples::Int64: Default: 10\nbinstep::Float64: Default: 0.02\ndbulk::Float64: Default: 10.0\ncutoff::Float64: Default: 10.0\nusecutoff::Bool: Default: false\nlcell::Int64: Default: 1\nGC::Bool: Default: true\nGC_threshold::Float64: Default: 0.1\nseed::Int64: Default: 321\nStableRNG::Bool: Default: false\nnthreads::Int64: Default: 0\nsilent::Bool: Default: false\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.OutputFiles","page":"Help entries","title":"ComplexMixtures.OutputFiles","text":"Internal structure or function, interface may change.\n\nmutable struct OutputFiles\n\nStructure to contain the names of the output files.\n\noutput::String\nsolute_atoms::String\nsolvent_atoms::String\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.Overview","page":"Help entries","title":"ComplexMixtures.Overview","text":"Internal structure or function, interface may change.\n\nmutable struct Overview\n\nStructure that is used to dispatch the show of a overview.\n\nR::Result\ndomain_molar_volume::Float64: Default: 0.0\ndensity::ComplexMixtures.Density: Default: Density()\nsolvent_molar_volume::Float64: Default: 0.0\nsolvent_molar_volume_bulk::Float64: Default: 0.0\nsolute_molar_volume::Float64: Default: 0.0\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.PDBTraj","page":"Help entries","title":"ComplexMixtures.PDBTraj","text":"struct PDBTraj{T<:(AbstractVector)} <: Trajectory\n\nStructure to contain PDB trajectories. Frames must be separated by \"END\", and with periodic cell sizes in the \"CRYST1\" field.\n\nThis structure and functions can be used as a template to implement the reading of other trajectory formats. \n\nfilename::String\nstream::ComplexMixtures.Stream{<:IOStream}\nnframes::Int64\nsides::Vector{T} where T<:(AbstractVector)\nsolute::Selection\nsolvent::Selection\nx_solute::Vector{T} where T<:(AbstractVector)\nx_solvent::Vector{T} where T<:(AbstractVector)\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.PDBTraj-Tuple{String, Selection, Selection}","page":"Help entries","title":"ComplexMixtures.PDBTraj","text":"PDBTraj(pdbfile::String, solute::Selection, solvent::Selection;T::Type = SVector{3,Float64})\n\nFunction open will set up the IO stream of the trajectory, fill up the number of frames field and additional parameters if required \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.Result","page":"Help entries","title":"ComplexMixtures.Result","text":"mutable struct Result{T<:VecOrMat{Float64}}\n\nStructure to contain the results of the MDDF calculation.\n\nnbins::Int64\ndbulk::Float64\ncutoff::Float64\nd::Vector{Float64}: Default: zeros(nbins)\nmd_count::Vector{Float64}: Default: zeros(nbins)\nmd_count_random::Vector{Float64}: Default: zeros(nbins)\ncoordination_number::Vector{Float64}: Default: zeros(nbins)\ncoordination_number_random::Vector{Float64}: Default: zeros(nbins)\nmddf::Vector{Float64}: Default: zeros(nbins)\nkb::Vector{Float64}: Default: zeros(nbins)\nautocorrelation::Bool\nsolvent::ComplexMixtures.SolSummary\nsolute::ComplexMixtures.SolSummary\nsolute_atom::VecOrMat{Float64}: Default: zeros(nbins, solute.natomspermol)\nsolvent_atom::VecOrMat{Float64}: Default: zeros(nbins, solvent.natomspermol)\nrdf_count::Vector{Float64}: Default: zeros(nbins)\nrdf_count_random::Vector{Float64}: Default: zeros(nbins)\nsum_rdf_count::Vector{Float64}: Default: zeros(nbins)\nsum_rdf_count_random::Vector{Float64}: Default: zeros(nbins)\nrdf::Vector{Float64}: Default: zeros(nbins)\nkb_rdf::Vector{Float64}: Default: zeros(nbins)\ndensity::ComplexMixtures.Density: Default: Density()\nvolume::ComplexMixtures.Volume: Default: Volume(nbins)\noptions::Options\nirefatom::Int64\nlastframe_read::Int64\nnframes_read::Int64\nfiles::Vector{String}\nweights::Vector{Float64}\n\nThe Result{Vector{Float64}} parametric type is necessary only for reading the JSON3 saved file. \n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.Selection","page":"Help entries","title":"ComplexMixtures.Selection","text":"struct Selection\n\nStructure that contains the information about the solute and solvent molecules.\n\nnatoms::Int64\nnmols::Int64\nnatomspermol::Int64\nindex::Vector{Int64}\nimol::Vector{Int64}\nnames::Vector{String}\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.SolSummary","page":"Help entries","title":"ComplexMixtures.SolSummary","text":"Internal structure or function, interface may change.\n\nstruct SolSummary\n\nStructures to contain the details of a solute or solvent to store in the results of the MDDF calculation.\n\nnatoms::Int64\nnmols::Int64\nnatomspermol::Int64\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.Trajectory","page":"Help entries","title":"ComplexMixtures.Trajectory","text":"Trajectory(filename::String, solute::Selection, solvent::Selection; format::String = \"\", chemfiles = false)\n\nTrajectory constructor data type. \n\nDefaults to reading with the Chemfiles infrastructure, except for DCD and PDB trajectory files, if the \"PDBTraj\" option is provided.\n\nSee memory issue (https://github.com/chemfiles/Chemfiles.jl/issues/44)\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.Units","page":"Help entries","title":"ComplexMixtures.Units","text":"Internal structure or function, interface may change.\n\nstruct Units\n\nUnit conversions.\n\nmole::Any: Default: 6.022140857e23\nAngs3tocm3::Any: Default: 1.0e24\nAngs3toL::Any: Default: 1.0e27\nAngs3tocm3permol::Any: Default: mole / Angs3tocm3\nAngs3toLpermol::Any: Default: mole / Angs3toL\nSitesperAngs3tomolperL::Any: Default: Angs3toL / mole\n\n\n\n\n\n","category":"type"},{"location":"help/#ComplexMixtures.Volume","page":"Help entries","title":"ComplexMixtures.Volume","text":"mutable struct Volume\n\nStructures to contain the volumes obtained from calculations.\n\ntotal::Float64\nbulk::Float64\ndomain::Float64\nshell::Vector{Float64}\n\n\n\n\n\n","category":"type"},{"location":"help/#Base.isapprox-Union{Tuple{T}, Tuple{T, T}} where T<:Union{Options, ComplexMixtures.SolSummary, ComplexMixtures.Density, ComplexMixtures.Volume, Result}","page":"Help entries","title":"Base.isapprox","text":"Base.isapprox(r1::T, r2::T; debug=false) where T <: CMTypes\n\nInternal structure or function, interface may change.\n\nFunction to test if two runs offered similar results. Mostly used in the package testing routines.\n\n\n\n\n\n","category":"method"},{"location":"help/#Base.merge-Tuple{Vector{<:Result}}","page":"Help entries","title":"Base.merge","text":"merge(r::Vector{Result})\n\nThis function merges the results of MDDF calculations obtained by running the same analysis on multiple trajectories, or multiple parts of the same trajectory. It returns a Result structure of the same type, with all the functions and counters representing averages of the set provided weighted by the number of frames read in each Result set.\n\n\n\n\n\n","category":"method"},{"location":"help/#Base.write-Tuple{Result, String, Selection, Selection}","page":"Help entries","title":"Base.write","text":"write(R::ComplexMixtures.Result, filename::String, solute::Selection, solvent::Selection)\n\nFunction to write the final results to output files as simple tables that are human-readable and easy to analyze with other software\n\nIf the solute and solvent selections are provides, pass on the atom names.\n\n\n\n\n\n","category":"method"},{"location":"help/#Base.write-Tuple{Result, String}","page":"Help entries","title":"Base.write","text":"write(R::ComplexMixtures.Result, filename::String; \n solute_names::Vector{String} = [\"nothing\"], \n solvent_names::Vector{String} = [\"nothing\"])\n\nOptional passing of atom names.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.VMDselect-Tuple{String, String}","page":"Help entries","title":"ComplexMixtures.VMDselect","text":"VMDselect(inputfile::String, selection::String; vmd=\"vmd\" )\n\nSelect atoms using vmd selection syntax, with vmd in background\n\nReturns the list of index (one-based) and atom names\n\nFunction to return the selection from a input file (topology, coordinates, etc), by calling VMD in the background.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.contributions-Tuple{Selection, Matrix{Float64}, Vector{Int64}}","page":"Help entries","title":"ComplexMixtures.contributions","text":"contributions(s::Selection, atom_contributions::Matrix{Float64}, selection)\n\nExtract the contribution of a given atom type selection from the solute or solvent atomic contributions to the MDDF.\n\ns here is the solute or solvent selection (type ComplexMixtures.Selection) atom_contributions is the R.solute_atom or R.solvent_atom arrays of the Result structure, and the last argument is the selection of atoms from the solute to be considered, given as a list of indexes, list of atom names, vector of PDBTools.Atoms, or a PDBTools.Residue. \n\nExtended help\n\nFor selections of one molecule, the function has an additional keyword option first_atom_is_ref that is false by default. If set to true, the index first atom of the selection is considered as a reference atom. For example if a solute has 100 atoms, but its first atom in the PDB file is number 901, the selection of indexes [1, 2, 3] will refer to atoms with indexes [901, 902, 903].\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.coordination_number-Tuple{Selection, Matrix{Float64}, Result, Any}","page":"Help entries","title":"ComplexMixtures.coordination_number","text":"coordination_number(R::Result) = R.coordination_number\ncoordination_number(R::Result, group_contributions::Vector{Float64})\ncoordination_number(s::Selection, atom_contributions::Matrix{Float64}, R::Result, group)\n\nComputes the coordination number of a given group of atoms from the solute or solvent atomic contributions to the MDDF. If no group is defined (first call above), the coordination number of the whole solute or solvent is returned.\n\nIf the group_contributions to the mddf are computed previously with the contributions function, the result can be used to compute the coordination number by calling coordination_number(R::Result, group_contributions).\n\nOtherwise, the coordination number can be computed directly with the second call, where:\n\ns is the solute or solvent selection (type ComplexMixtures.Selection)\n\natom_contributions is the R.solute_atom or R.solvent_atom arrays of the Result structure\n\nR is the Result structure,\n\nand the last argument is the selection of atoms from the solute to be considered, given as a list of indexes, list of atom names, or a selection following the syntax of PDBTools, or vector of PDBTools.Atoms, or a PDBTools.Residue\n\nExamples\n\nIn the following example we compute the coordination number of the atoms of residue 50 (of the solute) with the solvent atoms of TMAO, as a function of the distance. Finally, we show the average number of TMAO molecules within 5 Angstroms of residue 50. The findlast(<(5), R.d) part of the code below returns the index of the last element of the R.d array that is smaller than 5 Angstroms.\n\nPrecomputing the group contributions Using the contributions function\n\nusing ComplexMixtures, PDBTools\npdb = readPDB(\"test/data/NAMD/structure.pdb\");\nR = load(\"test/data/NAMD/protein_tmao.json\");\nsolute = Selection(PDBTools.select(pdb, \"protein\"), nmols=1);\nresidue50 = PDBTools.select(pdb, \"residue 50\");\n# Compute the group contributions to the MDDF\nresidue50_contribution = contributions(solute, R.solute_atom, residue50);\n# Now compute the coordination number\nresidue50_coordination = coordination_number(R, residue50_contribution)\n# Output the average number of TMAO molecules within 5 Angstroms of residue 50\nresidue50_coordination[findlast(<(5), R.d)]\n\nWithout precomputing the group_contribution\n\nusing ComplexMixtures, PDBTools\npdb = readPDB(\"test/data/NAMD/structure.pdb\");\nR = load(\"test/data/NAMD/protein_tmao.json\");\nsolute = Selection(PDBTools.select(pdb, \"protein\"), nmols=1);\nresidue50 = PDBTools.select(pdb, \"residue 50\");\n# Compute the coordination number\nresidue50_coordination = coordination_number(solute, R.solute_atom, R, group)\n# Output the average number of TMAO molecules within 5 Angstroms of residue 50\nresidue50_coordination[findlast(<(5), R.d)]\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.eulermat-Tuple{Any, Any, Any, String}","page":"Help entries","title":"ComplexMixtures.eulermat","text":"eulermat(beta, gamma, theta, deg::String)\n\nInternal structure or function, interface may change.\n\nThis routine was added because it defines the rotation in the \"human\" way, an is thus used to set the position of the fixed molecules. deg can only be \"degree\", in which case the angles with be considered in degrees. If no deg argument is provided, radians are used.\n\nThat means: beta is a counterclockwise rotation around x axis. gamma is a counterclockwise rotation around y axis. theta is a counterclockwise rotation around z axis.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.finalresults!-Tuple{Result, Options, Trajectory}","page":"Help entries","title":"ComplexMixtures.finalresults!","text":"finalresults!(R::Result, options::Options, trajectory::Trajectory)\n\nInternal structure or function, interface may change.\n\nFunction that computes the final results of all the data computed by averaging according to the sampling of each type of data, and converts to common units.\n\nComputes also the final distribution functions and KB integrals.\n\nThis function modified the values contained in the R data structure.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.gr-Tuple{Result}","page":"Help entries","title":"ComplexMixtures.gr","text":"gr(R::Result) = gr(R.d,R.rdf_count,R.density.solvent_bulk,R.options.binstep)\n\nIf a Result structure is provided without further details, use the rdf count and the bulk solvent density.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.gr-Tuple{Vector{Float64}, Vector{Float64}, Float64, Float64}","page":"Help entries","title":"ComplexMixtures.gr","text":"gr(r::Vector{Float64}, count::Vector{Float64}, density::Float64, binstep::Float64)\n\nComputes the radial distribution function from the count data and the density.\n\nThis is exactly a conventional g(r) if a single atom was chosen as the solute and solvent selections.\n\nReturns both the g(r) and the kb(r)\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.grid3D-Tuple{}","page":"Help entries","title":"ComplexMixtures.grid3D","text":"grid3D(solute,solute_atoms,mddf_result,output_file; dmin=1.5, ddax=5.0, step=0.5)\n\nThis function builds the grid of the 3D density function and fills an array of mutable structures of type Atom, containing the position of the atoms of grid, the closest atom to that position, and distance. \n\nsolute is a ComplexMixtuers.Selection, defining the solute. solute_atoms is the corresponding vector of PDBTools.Atoms, and mddf_result is the result of a mddf_result calculation with the correspondign solute. \n\ndmin and dmax define the range of distance where the density grid will be built, and step defines how fine the grid must be. Be aware that fine grids involve usually a very large (hundreds of thousands points).\n\nAll parameters can be provides as keyword parameters.\n\nExample\n\njulia> using ComplexMixtures, PDBTools\n\njulia> pdb = readPDB(\"./system.pdb\");\n\njulia> R = ComplexMixtures.load(\"./results.json\");\n\njulia> protein = select(pdb,\"protein\");\n\njulia> solute = ComplexMixtures.Selection(protein,nmols=1);\n\njulia> grid = ComplexMixtures.grid3D(solute=solute, solute_atoms=protein, mddf_result=R, output_file=\"grid.pdb\");\n\n\ngrid will contain a vector of Atoms with the information of the MDDF at each grid point, and the same data will be written in the grid.pdb file. This PDB file can be opened in VMD, for example, and contain in the beta field the contribution of each protein residue to the MDDF at each point in space relative to the protein, and in the occupancy field the distance to the protein. Examples of how this information can be visualized are provided in the user guide of ComplexMixtures. \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.itype-Tuple{Int64, Int64}","page":"Help entries","title":"ComplexMixtures.itype","text":"itype(iatom::Int, natomspermol::Int)\n\nInternal structure or function, interface may change.\n\nGiven the index of the atom in the vector of coordinates of the solute or the solvent, returns the type of the atom, that is, the index of this atom within the molecule (goes from 1 to natomspermol)\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.load-Tuple{String}","page":"Help entries","title":"ComplexMixtures.load","text":"load(filename::String)\n\nFunction to load the json saved results file into the Result data structure.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.mddf","page":"Help entries","title":"ComplexMixtures.mddf","text":"mddf(trajectory::Trajectory, options::Options)\n\nFunction that computes the minimum-distance distribution function, atomic contributions, and KB integrals, given the Trajectory structure of the simulation and, optionally, parameters given as a second argument of the Options type. This is the main function of the ComplexMixtures package. \n\nExamples\n\njulia> trajectory = Trajectory(\"./trajectory.dcd\",solute,solvent);\n\njulia> results = mddf(trajectory);\n\nor, to set some custom optional parameter,\n\njulia> options = Options(lastframe=1000);\n\njulia> results = mddf(trajectory,options);\n\n\n\n\n\n","category":"function"},{"location":"help/#ComplexMixtures.mddf_frame!-Tuple{Result, CellListMap.PeriodicSystems.AbstractPeriodicSystem, ComplexMixtures.Buffer, Options, Any}","page":"Help entries","title":"ComplexMixtures.mddf_frame!","text":"mddf_frame!(R::Result, system::AbstractPeriodicSystem, buff::Buffer, options::Options, RNG)\n\nInternal structure or function, interface may change.\n\nComputes the MDDF for a single frame, for autocorrelation of molecules. Modifies the data in the R (type Result) structure.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.minimum_distances!-Tuple{CellListMap.PeriodicSystems.AbstractPeriodicSystem, Result, Int64}","page":"Help entries","title":"ComplexMixtures.minimum_distances!","text":"minimum_distances!(system::CellListMap.PeriodicSystem, R::Result)\n\nInternal structure or function, interface may change.\n\nFunction that computes the list of distances of solvent molecules to a solute molecule. It updates the lists of minimum distances. \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.mol_index-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.mol_index","text":"mol_index(i_atom, natomspermol) = (i_atom-1) ÷ natomspermol + 1\n\nInternal structure or function, interface may change.\n\nExtended help\n\nSets the index of the molecule of an atom in the simples situation, in which all molecules have the same number of atoms. \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.mol_range-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.mol_range","text":"mol_range(imol, n_atoms_per_molecule)\n\nInternal structure or function, interface may change.\n\nGiven the index and the number of atoms per molecule, returns the range of indices of of an array of coordinates that corresponds to the molecule.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.move!-Union{Tuple{T}, Tuple{AbstractVector{T}, T, Any, Any, Any}} where T<:(StaticArraysCore.SVector)","page":"Help entries","title":"ComplexMixtures.move!","text":"move!(x::AbstractVector, newcm::AbstractVector,beta, gamma, theta)\n\nInternal structure or function, interface may change.\n\nTranslates and rotates a molecule according to the desired input center of coordinates and Euler rotations modifyies the vector x.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.overview-Tuple{Result}","page":"Help entries","title":"ComplexMixtures.overview","text":"overview(R::Result)\n\nFunction that outputs the volumes and densities in the most natural units.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.random_move!-Tuple{AbstractVector{<:StaticArraysCore.SVector{3}}, Int64, CellListMap.PeriodicSystems.AbstractPeriodicSystem, Any}","page":"Help entries","title":"ComplexMixtures.random_move!","text":"random_move!(x_ref::AbstractVector{T}, \n irefatom::Int,\n system::AbstractPeriodicSystem,\n x_new::AbstractVector{T}, RNG) where {T<:SVector}\n\nInternal structure or function, interface may change.\n\nFunction that generates a new random position for a molecule.\n\nThe new position is returned in x_new, a previously allocated array.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.randomize_solvent!-Tuple{CellListMap.PeriodicSystems.AbstractPeriodicSystem, ComplexMixtures.Buffer, Int64, Result, Any}","page":"Help entries","title":"ComplexMixtures.randomize_solvent!","text":"randomize_solvent!(system, buff, n_solvent_in_bulk, options, RNG)\n\nInternal structure or function, interface may change.\n\nGenerate a random solvent distribution from the bulk molecules of a solvent\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.save-Tuple{Result, String}","page":"Help entries","title":"ComplexMixtures.save","text":"save(R::Result, filename::String)\n\nFunction to write the result data structure to a json file.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.setbin-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.setbin","text":"setbin(d,step)\n\nInternal structure or function, interface may change.\n\nFunction that sets to which histogram bin a data point pertains simple, but important to keep consistency over all calls.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.setup_PeriodicSystem-Tuple{Trajectory, Options}","page":"Help entries","title":"ComplexMixtures.setup_PeriodicSystem","text":"setup_PeriodicSystem(trajectory::Trajectory, options::Options)\n\nInternal structure or function, interface may change.\n\nSetup the periodic system from CellListMap, to compute minimimum distances. The system will be setup such that xpositions corresponds to one molecule of the solute, and ypositions contains all coordinates of all atoms of the solvent. \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.shellradius-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.shellradius","text":"shellradius(i,step)\n\nInternal structure or function, interface may change.\n\nCompute the point in which the radius comprises half of the volume of the shell.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.sphereradiusfromshellvolume-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.sphereradiusfromshellvolume","text":"sphereradiusfromshellvolume(volume,step)\n\nInternal structure or function, interface may change.\n\nComputes the radius that corresponds to a spherical shell of a given volume.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.sphericalshellvolume-Tuple{Any, Any}","page":"Help entries","title":"ComplexMixtures.sphericalshellvolume","text":"sphericalshellvolume(i,step)\n\nInternal structure or function, interface may change.\n\nComputes the volume of the spherical shell defined within [(i-1)step,istep].\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.sum!-Tuple{Result, Result}","page":"Help entries","title":"ComplexMixtures.sum!","text":"sum!(R1::Result, R2::Result)\n\nInternal structure or function, interface may change.\n\nSum the counts of two Results structures, adding the result to the first structure as in R1 = R1 + R2.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.title-Tuple{Result, Selection, Selection}","page":"Help entries","title":"ComplexMixtures.title","text":"title(R::Result, solute::Selection, solvent::Selection)\ntitle(R::Result, solute::Selection, solvent::Selection, nspawn::Int)\n\nInternal structure or function, interface may change.\n\nPrint some information about the run.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.update_list!-Tuple{Any, Any, Any, Any, Any, Any, Vector{ComplexMixtures.MinimumDistance}}","page":"Help entries","title":"ComplexMixtures.update_list!","text":"update_list!(i, j, d2, iref_atom::Int, mol_index_i::F, isolute::Int, list::Vector{MinimumDistance{T}}) where {F<:Function, T}\n\nInternal structure or function, interface may change.\n\nFunction that updates a list of minimum distances given the indexes of the atoms involved for one pair within cutoff, for autocorrelations (such that the identity of isolute is needed)\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.update_list!-Tuple{Any, Any, Any, Any, Any, Vector{ComplexMixtures.MinimumDistance}}","page":"Help entries","title":"ComplexMixtures.update_list!","text":"update_list!(i, j, d2, iref_atom::Int, mol_index_i::F, list::Vector{MinimumDistance{T}}) where {F<:Function, T}\n\nInternal structure or function, interface may change.\n\nFunction that updates a list of minimum distances given the indexes of the atoms involved for one pair within cutoff.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.update_md-Tuple{ComplexMixtures.MinimumDistance, ComplexMixtures.MinimumDistance}","page":"Help entries","title":"ComplexMixtures.update_md","text":"update_md(md1::MinimumDistance{T}, md2::MinimumDistance{T}) where {T}\n\nInternal structure or function, interface may change.\n\nFunction that returns the updated minimum distance structure after comparing two structures associated with the same molecule.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.updatecounters!-Tuple{Result, CellListMap.PeriodicSystems.AbstractPeriodicSystem}","page":"Help entries","title":"ComplexMixtures.updatecounters!","text":"updatecounters!(R::Result, system::AbstractPeriodicSystem)\n\nInternal structure or function, interface may change.\n\nFunction that updates the minimum-distance counters in R\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.viewmol-Union{Tuple{T}, Tuple{Int64, Vector{T}, Int64}} where T","page":"Help entries","title":"ComplexMixtures.viewmol","text":"viewmol(i::Int, x::Vector{T}, n::Int) where T\n\nInternal structure or function, interface may change.\n\nReturns a view of a coordinate vector corresponding to the atoms of a molecule with index i. n is the number of atoms of the molecule.\n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.which_types-Tuple{Selection, Vector{Int64}}","page":"Help entries","title":"ComplexMixtures.which_types","text":"which_types(s::Selection, indexes::Vector{Int})\n\nInternal structure or function, interface may change.\n\nFunction that returns the list of the indexes of the types of the atoms in a selection. For example, if a selection corresponds to a solvent of water molecules: There are three types, 1, 2, and 3, corresponding to the three atoms of the water molecule. If the indexes provided are, for instance, 11, 12, and 13, corresponding to a water molecule, this function will return 1, 2 and 3.\n\nThis is used to get equivalent-atom contributions to the distribution functions. For example, the input indexes span all water molecules, the output of this function will be still the three indexes corresponding to the three types of atoms that exist in a water molecule. \n\nIt is not possible to compute the contribution of one individual water molecule if the distribution function was computed for all molecules. Thus, the necessity to identify the types of atoms involved in a selection. \n\n\n\n\n\n","category":"method"},{"location":"help/#ComplexMixtures.writexyz-Union{Tuple{T}, Tuple{Vector{T}, String}} where T<:(AbstractVector)","page":"Help entries","title":"ComplexMixtures.writexyz","text":"writexyz(x::Vector{T}, file::String) where T <: AbstractVector\n\nInternal structure or function, interface may change.\n\nPrint test xyz file.\n\n\n\n\n\n","category":"method"},{"location":"mddf/#Computing-the-Minimum-Distance-Distribution-Function","page":"Computing the MDDF","title":"Computing the Minimum-Distance Distribution Function","text":"","category":"section"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"The main function of the ComplexMixtures package actually computes the MDDF between the solute and the solvent chosen. ","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"It is run with the following command:","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"results = mddf(trajectory) ","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"The MDDF along with other results, like the corresponding KB integrals, are returned in the results data structure, which is described in the next section.","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"It is possible to tune several options of the calculation, by setting the Options data structure with user-defined values in advance. The most common parameters to be set by the user are probably dbulk and stride. ","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"dbulk defines the distance from the solute above which the user believes that the reference solute molecule does not significantly anymore the structure of the solvent. The default value is 10 Angstroms, but for large solvent molecules this might not be enough. To increase dbulk, use: ","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"options = Options(dbulk=15.)\nresults = mddf(trajectory,options)","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"stride defines if some frames will be skip during the calculation (for speedup). For example, if stride=5, only one in five frames will be considered. Adjust stride with: ","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"options = Options(stride=5)\nresults = mddf(trajectory,options)","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"See the Options section for further details and other options to set.","category":"page"},{"location":"installation/#Installation","page":"Installation","title":"Installation","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"note: Note\nThis is a package written in Julia. We invite you to experiment with the language, but if you want to just call this package from Python, read the From Python section of the manual. Understanding all the features of the package requires reading the manual as whole. The syntaxes of using this package from Julia or Python are almost identical, and the motivation for using Python should be mostly the familiarity with further analsys tools, as the plotting packages. ","category":"page"},{"location":"installation/#Install-Julia","page":"Installation","title":"Install Julia","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"First you need to install the Julia language in your platform, from: http://julialang.org. Julia version 1.6 or greater is required. Using the juliaup tool is also a highly recommended way of installing and keeping Julia up to date.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"tip: Tip\nNew to Julia? Julia is a modern high-level yet performant programming language. Some tips and a nice workflow for using it effectively can be found here. For this specific package, following a the step-by-step examples provided here after installing Julia should be enough. ","category":"page"},{"location":"installation/#Install-the-packages","page":"Installation","title":"Install the packages","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"Within Julia, to install the packages required for running the examples here you need to do:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"julia> import Pkg\n\njulia> Pkg.add([\"ComplexMixtures\",\"Plots\",\"PDBTools\"])","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"Please read the recommended workflow below, for further information and to be sure to have a smoother experience.","category":"page"},{"location":"installation/#Recommended-workflow-for-reproducibility","page":"Installation","title":"Recommended workflow for reproducibility","text":"","category":"section"},{"location":"installation/#Create-an-environment","page":"Installation","title":"Create an environment","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"Once Julia is installed, we recommend to create an environment that will contain all the packages you may use for your analyses, including ComplexMixtures, in such a way that your results can always be reproduced and you don't get any version incompatibility.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"We illustrate this by creating the \"MyNewPaper\" environment, which will be hosted in a simple directory,","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"mkdir /home/user/Documents/MyNewPaper","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"Then, start Julia and activate the environment that will be hosted there:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"julia> import Pkg; Pkg.activate(\"/home/user/Documents/MyNewPaper\")\n Activating new project at `~/Documents/MyNewPaper`","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"and add to this environment the packages that your analyses will require:","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"julia> Pkg.add([\"ComplexMixtures\",\"PDBTools\",\"Plots\"])","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"That's it. Close Julia. Note that this created the files Manifest.toml and Project.toml in the MyNewPaper directory, which contain the information of packages and exact package versions you are using now on in this environment. Saving these files may be relevant for the future exact reproduction of your analyses. ","category":"page"},{"location":"installation/#Run-your-analysis-scripts-in-that-environment","page":"Installation","title":"Run your analysis scripts in that environment","text":"","category":"section"},{"location":"installation/","page":"Installation","title":"Installation","text":"Now, your analysis scripts, described in the next section in details, will look like: ","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"import Pkg; Pkg.activate(\"/home/user/Documents/MyNewPaper\")\n\nusing ComplexMixtures\nusing PDBTools\nusing Plots\n\n# etc ... ","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"And the script can be run with julia -t auto script.jl (where -t auto allows for multi-threading), or included in julia with julia> include(\"./scritp.jl\"), as described in the next section.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"tip: Tip\nBy loading the package with using ComplexMixturesthe most common functions of the package become readily available by their direct name, for example mddf(...).If you don't want to bring the functions into the scope of your script, useimport ComplexMixturesThen, the functions of the package are called, for example, using ComplexMixtures.mddf(...). To avoid having to write ComplexMixtures all the time, define an accronym. For example:import ComplexMixtures as CM\nCM.mddf(...)","category":"page"},{"location":"contrib/#contributions","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"One of the interesting features of Minimum-Distance distributions is that they can be naturally decomposed into the atomic or group contributions. Simply put, if a MDDF has a peak at a hydrogen-bonding distance, it is natural to decompose that peak into the contributions of each type of solute or solvent atom to that peak. ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"To obtain the atomic contributions of an atom or group of atoms, the contributions function is provided. For example, in a system composed of a protein and water, we would have defined the solute and solvent using:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"using PDBTools, ComplexMixtures\natoms = readPDB(\"system.pdb\")\nprotein = select(atoms,\"protein\")\nwater = select(atoms,\"water\")\nsolute = Selection(protein,nmols=1)\nsolvent = Selection(water,natomspermol=3)","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The MDDF calculation is executed with:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"trajectory = Trajectory(\"trajectory.dcd\",solute,solvent)\nresults = mddf(trajectory)","category":"page"},{"location":"contrib/#Atomic-contributions-in-the-result-data-structure","page":"Atomic and group contributions","title":"Atomic contributions in the result data structure","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The results data structure contains the decomposition of the MDDF into the contributions of every type of atom of the solute and the solvent. These data is available at the results.solute_atom and results.solvent_atom arrays: ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"julia> results.solute_atom\n50×1463 Array{Float64,2}:\n 0.0 0.0 0.0 … 0.0 0.0 0.0\n 0.0 0.0 0.0 … 0.0 0.0 0.0\n ...\n 0.0 0.14245 0.0 … 0.0 0.0 0.0\n 0.0 0.0 0.0 … 0.0 0.0 0.0\n\njulia> results.solvent_atom \n50×3 Array{Float64,2}:\n 0.0 0.0 0.0 \n 0.0 0.0 0.0 \n ...\n 0.26087 0.26087 0.173913\n 0.25641 0.0854701 0.170940","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Here, 50 is the number of bins of the histogram, whose distances are available at the results.d vector.","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"It is expected that for a protein most of the atoms do not contribute to the MDDF, and that all values are zero at very short distances, smaller than the radii of the atoms.","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The three columns of the results.solvent_atom array correspond to the thee atoms of the water molecule in this example. The sequence of atoms correspond to that of the PDB file, but can be retrieved with:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"julia> solvent.names\n3-element Array{String,1}:\n \"OH2\"\n \"H1\"\n \"H2\"","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Therefore, if the first column of the results.solvent_atom vector is plotted as a function of the distances, one gets the contributions to the MDDF of the Oxygen atom of water. For example, here we plot the total MDDF and the Oxygen contributions: ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"using Plots\nplot(results.d,results.mddf,label=\"Total MDDF\",linewidth=2)\nplot!(results.d,results.solvent_atom[:,1],label=\"OH2\",linewidth=2)\nplot!(xlabel=\"Distance / Å\",ylabel=\"MDDF\")","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"page"},{"location":"contrib/#Selecting-groups-by-atom-names-or-indexes","page":"Atomic and group contributions","title":"Selecting groups by atom names or indexes","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"To plot the contributions of the hydrogen atoms of water to the total MDDF, we have to select the two atoms, named H1 and H2. The contributions function provides several practical ways of doing that, with or without the use of PDBTools. ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The contributions function receives three parameters: ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The solute or solvent data structure, created with Selection. \nThe array of atomic contributions (here results.solute_atom or results.solvent_atom), corresponding to the selection in 1.\nA selection of a group of atoms within the molecule of interest, provided as described below. ","category":"page"},{"location":"contrib/#Selecting-by-indexes-within-the-molecule","page":"Atomic and group contributions","title":"Selecting by indexes within the molecule","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"To select simply by the index of the atoms of the molecules, just provide a list of indexes to the contributions function. For example, to select the hydrogen atoms, which are the second and third atoms of the water molecule, use:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"julia> indexes = [ 2, 3 ]\njulia> h_contributions = contributions(solvent,R.solvent_atom,indexes)\n500-element Array{Float64,1}:\n 0.0\n 0.0\n ⋮\n 0.7742706465861815\n 0.8084139794974875","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Plotting both the oxygen (index = 1) and hydrogen contributions results in:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"page"},{"location":"contrib/#Selecting-by-atom-name","page":"Atomic and group contributions","title":"Selecting by atom name","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The exact same plot above could be obtained by providing lists of atom names instead of indexes to the contributions function:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"oxygen = [\"OH2\"]\no_contributions = contributions(solvent,R.solvent_atom,oxygen) \nhydrogens = [\"H1\",\"H2\"]\nh_contributions = contributions(solvent,R.solvent_atom,hydrogens)","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The above plot can be obtained with:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"using Plots\nplot(results.d,results.mddf,label=\"Total MDDF\",linewidth=2)\nplot!(results.d,o_contributions,label=\"OH2\",linewidth=2)\nplot!(results.d,h_contributions,label=\"Hydrogen atoms\",linewidth=2)\nplot!(xlabel=\"Distance / Å\",ylabel=\"MDDF\")","category":"page"},{"location":"contrib/#General-selections-using-PDBTools","page":"Atomic and group contributions","title":"General selections using PDBTools","text":"","category":"section"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"More interesting and general is to select atoms of a complex molecule, like a protein, using residue names, types, etc. Here we illustrate how this is done by providing selection strings to contributions to obtain the contributions to the MDDF of different types of residues of a protein to the total MDDF. ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"For example, if we want to split the contributions of the charged and neutral residues to the total MDDF distribution, we could use to following code. Here, solute refers to the protein.","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"charged_residues = PDBTools.select(atoms,\"charged\")\ncharged_contributions = contributions(solute,R.solute_atom,charged_residues)\n\nneutral_residues = PDBTools.select(atoms,\"neutral\")\nneutral_contributions = contributions(solute,R.solute_atom,neutral_residues)","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The charged and neutral outputs are vectors containing the contributions of these residues to the total MDDF. The corresponding plot is: ","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"plot(results.d,results.mddf,label=\"Total MDDF\",linewidth=2)\nplot!(results.d,charged_contributions,label=\"Charged residues\",linewidth=2)\nplot!(results.d,neutral_contributions,label=\"Neutral residues\",linewidth=2)\nplot!(xlabel=\"Distance / Å\",ylabel=\"MDDF\")","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Resulting in:","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"page"},{"location":"contrib/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Note here how charged residues contribute strongly to the peak at hydrogen-bonding distances, but much less in general. Of course all selection options could be used, to obtain the contributions of specific types of residues, atoms, the backbone, the side-chains, etc. ","category":"page"},{"location":"parallel/#Parallel-execution","page":"Parallel execution","title":"Parallel execution","text":"","category":"section"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"It is highly recommended to run MDDF calculations in parallel, using multiple processors of a single computer. To run the computation in parallel, initialize julia with the -t auto option:","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"julia -t auto","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"The computation will use a number of threads equal to the number of physical cores of the computer. The number of computation threads to be used can be set by the Options(nthreads=N) parameter, where N is an integer. Hyperthreading (using more threads than physical CPUs) usually does not provide a significant speedup, and can be detrimental in some cases. ","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"To directly run a script in parallel, use:","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"julia -t auto example.jl","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"note: Note\nThe number of threads used for computation of the MDDF is the number of physical CPUs of the computer, which are obtained programmatically. Most times the use of hyper-threading is not beneficial. Adjust the number of threads with the Options(nthreads=N) parameter.","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"warning: Warning\nIf the calculations get Killed by no apparent reason, that is probably because you are running out of memory because of the many parallel computations running. One way to alleviate this problem is to force garbage collection, usingoptions = Options(GC=true,GC_threshold=0.5)\nR = mddf(trajectory,options)\nThe GC_threshold=0.5 indicates that if the free memory is smaller than 50% of the total memory of the machine, a garbage-collection run will occur. The default parameters are GC=true and GC_threshold=0.1. ","category":"page"},{"location":"multiple/#Working-with-multiple-trajectories","page":"Multiple trajectories","title":"Working with multiple trajectories","text":"","category":"section"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"Very commonly, one has multiple trajectories of the same system, and we want to obtain the average results of all trajectories. We provide a simple scheme to average the results of multiple MDDF calculations:","category":"page"},{"location":"multiple/#Create-a-vector-of-result-data-structures,-without-initialization","page":"Multiple trajectories","title":"Create a vector of result data structures, without initialization","text":"","category":"section"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"Let us assume that we have three Gromacs trajectories, with file names traj1.xtc, traj2.xtc, traj3.xtc. First let us create a list with these file names:","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"trajectory_files = [ \"traj1.xtc\" , \"traj2.xtc\" , \"traj3.xtc\" ]","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"And define an empty vector of Result structures:","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"results = Result[]","category":"page"},{"location":"multiple/#Run-the-calculations-in-a-loop","page":"Multiple trajectories","title":"Run the calculations in a loop","text":"","category":"section"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"The calculation on the multiple trajectories is then performed in a simple loop, such as","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"atoms = PDBTools.readPDB(\"./system.pdb\")\nsolute = Selection(atoms,\"protein\",nmols=1)\nsolvent = Selection(atoms,\"resname TMAO\",,natomspermol=14)\nfor file in trajectory_files\n trajectory = Trajectory(file,solute,solvent)\n # compute the MDDF data and push the result to the results array\n push!(results, mddf(trajectory))\nend","category":"page"},{"location":"multiple/#Merge-the-results-of-several-trajectories,-with-proper-weights","page":"Multiple trajectories","title":"Merge the results of several trajectories, with proper weights","text":"","category":"section"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"Of course, the resulting results vector will contain at each position the results of each calculation. To merge these results in a single result data structure, use:","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"R = merge(results)","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"The R structure generated contains the averaged results of all calculations, with weights proportional to the number of frames of each trajectory. That is, if the first trajectory had 2000 frames, and the second and third trajectories have 1000 frames each, the first trajectory will have a weight of 0.5 on the final results. The merge function can be used to merge previously merged results with new results as well.","category":"page"},{"location":"multiple/","page":"Multiple trajectories","title":"Multiple trajectories","text":"tip: Tip\nThe names of the files and and weights are stored in the R.files and R.weights vectors of the results structure:julia> R.files\n3-element Array{String,1}:\n \"./traj1.xtc\"\n \"./traj2.xtc\"\n \"./traj3.xtc\"\n\njulia> R.weights\n2-element Array{Float64,1}:\n 0.5\n 0.25\n 0.25\nIt is not a bad idea to check if that is what you were expecting.","category":"page"},{"location":"save/#save","page":"Save and load","title":"Save and load results","text":"","category":"section"},{"location":"save/","page":"Save and load","title":"Save and load","text":"Three functions serve the purpose of saving and loading the results obtained with ComplexMixtures:","category":"page"},{"location":"save/#Save-data-to-recover-it-later","page":"Save and load","title":"Save data to recover it later","text":"","category":"section"},{"location":"save/","page":"Save and load","title":"Save and load","text":"save(results,\"results.json\")","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"where results is the output data structure of the mddf() calculation, and results.json is the output file to be created. The file is written in JSON format, thus is not naturally human-readable.","category":"page"},{"location":"save/#Load-saved-data","page":"Save and load","title":"Load saved data","text":"","category":"section"},{"location":"save/","page":"Save and load","title":"Save and load","text":"results = load(\"results.json\")","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"The load function reads the output of the save function above, and restores the results data structure.","category":"page"},{"location":"save/#Write-data-in-a-human-readable-format","page":"Save and load","title":"Write data in a human-readable format","text":"","category":"section"},{"location":"save/","page":"Save and load","title":"Save and load","text":"If you Want the results to be written as simple ASCII tables such that you can read them with another analysis program, plotting graphic, or just want to inspect the data visually, use:","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"write(results,\"results.dat\")","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"Three files will be created by this function:","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"results.dat: Contains the main results, as the MDDF and KB-integral data.","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"results-ATOM_CONTRIB_SOLVENT.dat: contains the contribution of each atom type of the solvent to the MDDF.","category":"page"},{"location":"save/","page":"Save and load","title":"Save and load","text":"results-ATOM_CONTRIB_SOLUTE.dat: contains the contribution of each atom type of the solute to the MDDF.","category":"page"},{"location":"trajectory/#trajectories","page":"Loading the trajectory","title":"Loading trajectories","text":"","category":"section"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"To initialize a trajectory file for computation, use the command","category":"page"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"trajectory = Trajectory(\"trajectory.xtc\",solute,solvent)","category":"page"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"where solute and solvent are defined with the Selection function described before. This function opens the stream for reading frames, which are read once a time when the coordinates are required for computing the MDDF.","category":"page"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"The Trajectory function uses Chemfiles in background, and thus the most common trajectory formats are supported, as the ones produced with NAMD, Gromacs, LAMMPS, Amber, etc. ","category":"page"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"tip: Tip\nThe format of the trajectory file is automatically determined by Chemfiles from the extension of the file. However, it can be provided by the user with the format keyword, for example:trajectory = Trajectory(\"trajectory.xtc\",solute,solvent,format=\"xtc\")","category":"page"},{"location":"quickguide/#Quick-Guide","page":"Quick Guide","title":"Quick Guide","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Of course, follow the installation instructions first. A complete working example is shown below, and in the section that follows each command is described in detail.","category":"page"},{"location":"quickguide/#Complete-example","page":"Quick Guide","title":"Complete example","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Here we show the input file required for the study of the solvation of a protein by the TMAO solvent, which is a molecule 4 atoms. The protein is assumed to be at infinite dilution in the simulation. The trajectory of the simulation is in DCD format in this example, which is the default output of NAMD and CHARMM simulation packages.","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"# Activate environment (see the Installation -> Recommended Workflow manual section)\nimport Pkg; Pkg.activate(\"/home/user/MyNewPaper\")\n\n# Load packages\nusing PDBTools\nusing ComplexMixtures \nusing Plots\n\n# Load PDB file of the system\natoms = readPDB(\"./system.pdb\")\n\n# Select the protein and the TMAO molecules\nprotein = select(atoms,\"protein\")\ntmao = select(atoms,\"resname TMAO\")\n\n# Setup solute and solvent structures\nsolute = Selection(protein,nmols=1)\nsolvent = Selection(tmao,natomspermol=14)\n\n# Setup the Trajectory structure\ntrajectory = Trajectory(\"./trajectory.dcd\",solute,solvent)\n\n# Run the calculation and get results\nresults = mddf(trajectory)\n\n# Save the results to recover them later if required\nsave(results,\"./results.json\")\n\n# Plot the some of the most important results \nplot(results.d,results.mddf,xlabel=\"d\",ylabel=\"MDDF\") # plot the MDDF\nsavefig(\"./mddf.pdf\")\nplot(results.d,results.kb,xlabel=\"d\",ylabel=\"KB\") # plot the KB \nsavefig(\"./kb.pdf\")","category":"page"},{"location":"quickguide/#Running-the-example","page":"Quick Guide","title":"Running the example","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Given that this code is saved into a file named example.jl, it can be run within the Julia REPL with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"julia> include(\"example.jl\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"or directly with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"julia -t auto example.jl","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"where -t auto will launch julia with multi-threading. It is highly recommended to use multi-threading!","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"note: Note\nJulia compiles the code the first time it is run in each section. Thus, running script from the command line with, for example, julia -t auto example.jl may appear slow, particularly if you are modifying the script interactively. Ideally, do not restart Julia, just repeatedly include your script in the same Julia section. The second time the script is loaded will be much faster. For example:julia> @time include(\"./example.jl\") \n# ... some output\n27.554095 seconds (72.13 M allocations: 4.623 GiB, 4.37% gc time, 11.96% compilation time)\njulia> @time include(\"./example.jl\")\n# ... some output\n0.703780 seconds (3.24 M allocations: 897.260 MiB, 12.22% gc time)The first time the script was called it took ~30s, which included compilation of the code and loading of the packages. The second time the script was included it took 0.7s. Thus, for interactive modification of the script, don't restart Julia.This has been much improved in Julia 1.9, particularly if a stable environment is used, as suggested.","category":"page"},{"location":"quickguide/#Detailed-description-of-the-example","page":"Quick Guide","title":"Detailed description of the example","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Start julia and load the ComplexMixtures package, using:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"using ComplexMixtures","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"And here we will use the PDBTools package to obtain the selections of the solute and solvent molecules: ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"using PDBTools","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"(see Set solute and solvent for details).","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The fastest way to understand how to use this package is through an example. ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Let us consider a system of three components: a protein, water, a cossolvent: TMAO (trimetylamine-N-oxyde), which is a common osmolyte known to stabilize protein structures. A picture of this system is shown below, with the protein in blue, water, and TMAO molecules. The system was constructed with Packmol and the figure was produced with VMD.","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"
      \n\n
      ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"We want to study the interactions of the protein with TMAO in this example. The computation of the MDDF is performed by defining the solute and solvent selections, and running the calculation on the trajectory.","category":"page"},{"location":"quickguide/#Define-the-protein-as-the-solute","page":"Quick Guide","title":"Define the protein as the solute","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"To define the protein as the solute, we will use the PDBTools package, which provides a handy selection syntax. First, read the PDB file using ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"atoms = readPDB(\"./system.pdb\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Then, let us select the protein atoms (here we are using the PDBTools.select function):","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"protein = select(atoms,\"protein\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"And, finally, let us use the Selection function to setup the structure required by the MDDF calculation:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"solute = Selection(protein,nmols=1)","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"note: Note\nIt is necessary to indicate how many molecules (in this case, nmols=1, so that ComplexMixtures knows that the solute is to be considered as single structure. In this case there is no ambiguity, but if the solute was a micelle, for example, this option would let ComplexMixtures know that one wants to consider the micelle as a single structure.","category":"page"},{"location":"quickguide/#Define-TMAO-the-solvent-to-be-considered","page":"Quick Guide","title":"Define TMAO the solvent to be considered","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Equivalently, the solvent is set up with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"tmao = select(atoms,\"resname TMAO\")\nsolvent = Selection(tmao,natomspermol=14)\n","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"note: Note\nHere we opted to provide the number of atoms of a TMAO molecules (with the natomspermol keyword). This is generally more practical for small molecules than to provide the number of molecules.","category":"page"},{"location":"quickguide/#Set-the-Trajectory-structure","page":"Quick Guide","title":"Set the Trajectory structure","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The solute and solvent data structures are then fed into the Trajectory data structure, together with the trajectory file name, with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"trajectory = Trajectory(\"trajectory.dcd\",solute,solvent)","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"In the case, the trajectory is of NAMD \"dcd\" format. All formats supported by Chemfiles are automatically recognized. ","category":"page"},{"location":"quickguide/#Finally,-run-the-computation-and-get-the-results:","page":"Quick Guide","title":"Finally, run the computation and get the results:","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"If default options are used (as the bin size of the histograms, read all frames without skipping any), just run the mddf with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"results = mddf(trajectory)\n","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Some optional parameters for the computation are available in the Options section.","category":"page"},{"location":"quickguide/#The-results-data-structure-obtained","page":"Quick Guide","title":"The results data structure obtained","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The results data structure contains all the results of the MDDF calculation, including:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"results.d : Vector containing the distances to the solute. ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"results.mddf : Vector containing the minimum-distance distribution function at each distance.","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"That means, for example, that ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"plot(results.d,results.mddf,xlabel=\"d / \\AA\",ylabel=\"MDDF\") \n","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"results in the expected plot of the MDDF of TMAO as a function of the distance to the protein:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"
      \n\n
      ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The Kirkwood-Buff integral corresponding to that distribution is provided in the results.kb vector, and can be also directly plotted with ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"plot(results.d,results.kb,xlabel=\"d / \\AA\",ylabel=\"MDDF\") ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"to obtain:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"
      \n\n
      ","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"See the Atomic and group contributions section for a detailed account on how to obtain a molecular picture of the solvation by splitting the MDDF in the contributions of each type of atom of the solvent, each type of residue of the protein, etc.","category":"page"},{"location":"quickguide/#Save-the-results","page":"Quick Guide","title":"Save the results","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The results can be saved into a file (with JSON format) with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"save(results,\"./results.json\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"And these results can be loaded afterwards with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"load(\"./results.json\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Alternatively, a human-readable set of output files can be obtained to be analyzed in other software (or plotted with alternative tools), with","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"write(results,\"./results.dat\")","category":"page"},{"location":"selection/#selections","page":"Set solute and solvent","title":"Set the solute and solvent selections","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"The solute and solvent are defined in ComplexMixtures as lists (vectors) of the indexes of the atoms of the system. The solute and solvent information is stored in the Selection structure. For example, if the solute is a molecule formed by the first 5 atoms of the system, it would be defined as: ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"indexes = [ 1, 2, 3, 4, 5 ]\nsolute = Selection(indexes,nmols=1)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"note: Note\nWe need to inform the Selection function about the number of atoms of each molecule (using natomspermol=3, for example), or the number of molecules (using nmols=1000, for example), such that the atoms belonging to each molecule can be determined without ambiguity. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"The atom names can be also provided such that some of the output files contain more information on the atomic contributions. In this case the syntax is:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"indexes = [ 1, 2, 3, 4, 5 ]\nnames = [ \"H1\", \"H2\", \"H3\", \"H4\", \"C\" ]\nsolute = Selection(indexes,names,nmols=1)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"warning: Warning\nThe indexing in ComplexMixtures is 1-based. That means that the first atom of your structure file is in position 1 of the coordinates. Please be careful if using any selection tool to be sure that your selection is correct.","category":"page"},{"location":"selection/#Using-PDBTools","page":"Set solute and solvent","title":"Using PDBTools","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"PDBTools is a package we developed to read and write PDB files, which provides a simple selection tool. It is installed as a dependency of ComplexMixtures. Given a PDB file of the simulated system, the solute can be defined as, for example,","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"using PDBTools\natoms = PDBTools.readPDB(\"system.pdb\")\nprotein = PDBTools.select(atoms,\"protein\")\nsolute = Selection(protein,nmols=1)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"If the solvent is, for instance, water, the indexes of the water molecules can be obtained with:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"water = PDBTools.select(atoms,\"water\")\nsolvent = Selection(water,natomspermol=3)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"or, alternatively, a more compact syntax can be used, for example:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"water = PDBTools.select(\"system.pdb\",\"resname TIP3P\")\nsolvent = Selection(water,natomspermol=3)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"or even providing just the names of the input file and selection, which will run PDBTools in background:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"solvent = Selection(\"sytem.pdb\",\"water\",water,natomspermol=3)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"warning: Warning\nThe selection syntax of PDBTools is somewhat limited. Verify if the selections correspond to the the desired sets of atoms every time.","category":"page"},{"location":"selection/#Using-VMD","page":"Set solute and solvent","title":"Using VMD","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"VMD is a very popular and powerful package for visualization of simulations. It contains a very versatile library to read topologies and trajectory files, and a powerful selection syntax. We provide here a wrapper to VMD which allows using its capabilities. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"For example, the solute can be defined with: ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"indexes, names = VMDselect(\"./system.gro\",\"protein\",vmd=\"/usr/bin/vmd\")\nsolute = Selection(indexes,names,nmols=1)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"The main advantage here is that all the file types that VMD supports are supported. But VMD needs to be installed and is run in background, and it takes a few seconds. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"warning: Warning\nVMD uses 0-based indexing and VMDselect adjusts that. However, if a selection is performed by index, as with index 1, VMD will select the second atom, and the output will be [2]. Selections by type, name, segment, residue name, etc, won't be a problem.","category":"page"},{"location":"tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"A set of examples of analyses that can be performed with ComplexMixtures is given in this site. A brief the description of the possible results is provided here. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Some tools are provided to analyze the results:","category":"page"},{"location":"tools/#coordination_number","page":"Tools","title":"Coordination numbers","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"The function","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"coordination_number(R::Result, group_contributions::Vector{Float64})","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"computes the coordination number of a given group of atoms from the solute or solvent atomic contributions to the MDDF. Here, R is the result of the mddf calculation, and group_contributions is the output of the contributions function for the desired set of atoms.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"If no group is defined, the coordination number of the complete solute is returned, which is equivalent to the R.coordination_number field of the Result data structure:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"coordination_number(R::Result) == R.coordination_number","category":"page"},{"location":"tools/#Example","page":"Tools","title":"Example","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"In the following example we compute the coordination number of the atoms of residue 50 (which belongs to the solute - a protein) with the solvent atoms of TMAO, as a function of the distance. The plot produced will show side by side the residue contribution to the MDDF and the corresponding coordination number.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"using ComplexMixtures, PDBTools\nusing Plots, EasyFit\npdb = readPDB(\"test/data/NAMD/structure.pdb\")\nR = load(\"test/data/NAMD/protein_tmao.json\")\nsolute = Selection(PDBTools.select(pdb, \"protein\"), nmols=1)\nresidue50 = PDBTools.select(pdb, \"residue 50\")\n# Compute the group contribution to the MDDF\nresidue50_contribution = contributions(solute, R.solute_atom, residue50)\n# Now compute the coordination number\nresidue50_coordination = coordination_number(R, residue50_contribution)\n# Plot with twin y-axis\nplot(R.d, movavg(residue50_contribution,n=10).x,\n xaxis=\"distance / Å\", \n yaxis=\"MDDF contribution\", \n linewidth=2, label=nothing, color=1\n)\nplot!(twinx(),R.d, residue50_coordination, \n yaxis=\"Coordination number\", \n linewidth=2, label=nothing, color=2\n)\nplot!(title=\"Residue 50\", framestyle=:box, subplot=1)","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"With appropriate input data, this code produces:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"
      \n\n
      ","category":"page"},{"location":"tools/#Computing-a-2D-density-map-around-a-macromolecule","page":"Tools","title":"Computing a 2D density map around a macromolecule","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"One nice way to visualize the accumulation or depletion of a solvent around a macromolecule (a protein, for example), is to obtain a 2D map of the density as a function of the distance from its surface. For example, in the figure below the density of a solute (here, Glycerol), in the neighborhood of a protein is shown:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"
      \n\n
      ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Here, one can see that Glycerol accumulates on Asp76 and on the proximity of hydrogen-bonding residues (Serine residues mostly). This figure was obtained by extracting from atomic contributions of the protein the contribution of each residue to the MDDF. Using PDBTools, this can be done with, for example: ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"residues = collect(eachresidue(protein))\nresidue_contributions = zeros(length(R.d),length(residues))\nfor (i,residue) in pairs(residues)\n c = contributions(solute,R.solute_atom,residue) \n residue_contributions[:,i] .= c\nend","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The above produces a matrix with a number of columns equal to the number of residues and a number of rows equal to the number of MDDF points. That matrix can be plotted as a contour map with adequate plotting software. A complete running example is provided here, producing the figure above. ","category":"page"},{"location":"tools/#Computing-a-3D-density-map-around-a-macromolecule","page":"Tools","title":"Computing a 3D density map around a macromolecule","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"Three-dimensional representations of the distribution functions can also be obtained from the MDDF results. These 3D representations are obtained from the fact that the MDDFs can be decomposed into the contributions of each solute atom, and that each point in space is closest to a single solute atom as well. Thus, each point in space can be associated to one solute atom, and the contribution of that atom to the MDDF at the corresponding distance can be obtained. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"For example, the distribution function of a hydrogen-bonding liquid solvating a protein will display a characteristic peak at about 1.8Å. The MDDF at that distance can be decomposed into the contributions of all atoms of the protein which were found to form hydrogen bonds to the solvent. A 3D representation of these contributions can be obtained by computing, around a static protein (solute) structure, which are the regions in space which are closer to each atom of the protein. The position in space is then marked with the atom of the protein to which that region \"belongs\" and with the contribution of that atom to the MDDF at each distance within that region. A special function to compute this 3D distribution is provided here: grid3D. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"This is better illustrated by a graphical representation. In the figure below we see a 3D representation of the MDDF of Glycerol around a protein, computed from a simulation of this protein in a mixture of water and Glycerol. A complete set of files and a script to reproduce this example is available here. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"
      \n\n
      ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"In the figure on the left, the points in space around the protein are selected with the following properties: distance from the protein smaller than 2.0Å and relative contribution to the MDDF at the corresponding distance of at least 10% of the maximum contribution. Thus, we are selecting the regions of the protein corresponding to the most stable hydrogen-bonding interactions. The color of the points is the contribution to the MDDF, from blue to red. Thus, the most reddish-points corresponds to the regions where the most stable hydrogen bonds were formed. We have marked two regions here, on opposite sides of the protein, with arrows.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Clicking on those points we obtain which are the atoms of the protein contributing to the MDDF at that region. In particular, the arrow on the right points to the strongest red region, which corresponds to an Aspartic acid. These residues are shown explicitly under the density (represented as a transparent surface) on the figure in the center. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The figure on the right displays, overlapped with the hydrogen-bonding residues, the most important contributions to the second peak of the distribution, corresponding to distances from the protein between 2.0 and 3.5Å. Notably, the regions involved are different from the ones forming hydrogen bonds, indicating that non-specific interactions with the protein (and not a second solvation shell) are responsible for the second peak. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"An example input file which produces the files required for producing these images is:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"using ComplexMixtures, PDBTools\n\n# PDB file of the system simulated\npdb = readPDB(\"../Data/system.pdb\")\n\n# Load results of a ComplexMixtures run\nR = load(\"../Data/results_glyc50.json\") \n\n# Inform which is the solute\nprotein = select(pdb,\"protein\")\nsolute = Selection(protein,nmols=1)\n\n# Compute the 3D density grid and output it to the PDB file\ngrid = grid3D(\n solute=solute,\n solute_atoms=protein,\n mddf_result=R,\n output_file=\"grid.pdb\"\n)","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The call to grid3D in the last command will write an output a PDB file with the grid points, which loaded in a visualization software side-by-side with the protein structure, allows the production of the images shown. The grid.pdb file contains a regular PDB format, but the atoms are grid points. The identity of the atoms correspond to the identity of the protein atom contributing to the MDDF at that point (the closest protein atom). The temperature-factor column (beta) contains the relative contribution of that atom to the MDDF at the corresponding distance, and the occupancy field contains the distance itself.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The output grid variable contains the same information of the PDB file, which can be analyzed with the tools of PDBTools if the user wants to.","category":"page"},{"location":"tools/#Computing-radial-distribution-functions","page":"Tools","title":"Computing radial distribution functions","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"The distributions returned by the mddf function (the mddf and rdf vectors), are normalized by the random reference state or using a site count based on the numerical integration of the volume corresponding to each minimum-distance to the solute. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"If, however, the solute is defined by a single atom (as the oxygen atom of water, for example), the numerical integration of the volume can be replaced by a simple analytical spherical shell volume, reducing noise. The ComplexMixtures.gr function returns the radial distribution function and the KB integral computed from the results, using this volume estimate: ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"g, kb = ComplexMixtures.gr(R)","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"By default, the single-reference count (rdf_count) of the Result structure will be used to compute the radial distribution function. The function can be called with explicit control of all input parameters: ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"g, kb = ComplexMixtures.gr(r,count,density,binstep)","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"where:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Parameter Definition Result structure output data to provide\nr Vector of distances The d vector\ncount Number of site counts at each r The rdf or mddf vectors\ndensity Bulk density The density.solvent_bulk or density.solvent densities.\nbinstep The histogram step The options.binstep\n ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Example:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"...\nR = mddf(trajectory,options)\ng, kb = ComplexMixtures.gr(R.d,R.rdf_count,R.density.solvent_bulk,R.options.binstep)","category":"page"},{"location":"tools/#Overview-of-the-solvent-and-solute-properties","page":"Tools","title":"Overview of the solvent and solute properties","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"The output to the REPL of the Result structure provides an overview of the properties of the solution. The data can be retrieved into a data structure using the overview function. Examples: ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"...\njulia> results = mddf(trajectory)\n\njulia> results\n\n-------------------------------------------------------------------------------\n\n MDDF Overview: \n\n Solvent properties: \n ------------------- \n\n Simulation concentration: 1.5209006318095133 mol L⁻¹\n Molar volume: 657.5051512801567 cm³ mol⁻¹\n\n Concentration in bulk: 1.4918842545752287 mol L⁻¹\n Molar volume in bulk: 670.2932864484995 cm³ mol⁻¹ \n\n Solute properties: \n ------------------ \n\n Simulation Concentration: 1.5209006318095133 mol L⁻¹\n Estimated solute partial molar volume: 657.5051512801567 cm³ mol⁻¹\n\n Using dbulk = 20.0Å: \n Molar volume of the solute domain: 30292.570006549242 cm³ mol⁻¹\n\n Auto-correlation: true\n\n Trajectory files and weights: \n ./vinicius.xtc - w = 1.0\n\n Long range MDDF mean (expected 1.0): 1.1090804621839963 +/- 0.04298849642932878\n Long range RDF mean (expected 1.0): 1.15912932236198 +/- 0.05735018864444404\n\n-------------------------------------------------------------------------------","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"In this case, since solute and solvent are equivalent and the system is homogeneous, the molar volumes and concentrations are similar. This is not the case if the molecules are different or if the solute is at infinite dilution (in which case the bulk solvent density might be different from the solvent density in the simulation). ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"To retrieve the data of the overview structure use, for example:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"julia> overview = overview(results);\n\njulia> overview.solute_molar_volume\n657.5051512801567","category":"page"},{"location":"examples/#examples","page":"Full Example","title":"Example","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"note: Note\nAt this repository various examples are available illustrating the execution and possibilities of the package. Here we discuss one of these examples in detail.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The following examples consider a system composed a protein solvated by a mixture of water and glycerol, built with Packmol. The simulations were performed with NAMD with periodic boundary conditions and a NPT ensemble at room temperature and pressure. Molecular pictures were produced with VMD and plots were produced with Julia's Plots library.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Image of the system of the example: a protein solvated by a mixture of glycreol (green) and water, at a concentration of 50%vv. ","category":"page"},{"location":"examples/#How-to-run-this-example","page":"Full Example","title":"How to run this example","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Download and install Julia\nInstall the required packages. Within Julia, do:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"julia> import Pkg\n\njulia> Pkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"Formatting\"])","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Get the files:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"git clone https://github.com/m3g/ComplexMixturesExamples","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The files associated to the following examples are distributed at this page. ","category":"page"},{"location":"examples/#Data","page":"Full Example","title":"Data","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The Data directory contains the a pdb file of the system (system.pdb) and a sample from the trajectory (glyc50.dcd), with a few frames. It also contains the result of running the mddf calculation on the complete trajectory, results_glyc50.json. This last file was produced by ComplexMixtures, as indicated in the following examples. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The sample trajectory is provided so that the first example can be run, yet do not expect that the results are the same, as the sampling is much lower in this case. The complete trajectory can be retrieved from this link (3GB file). ","category":"page"},{"location":"examples/#Minimum-Distance-Distribuion-function","page":"Full Example","title":"Minimum-Distance Distribuion function","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Here we compute the minimum-distance distribution function, the Kirkwood-Buff integral, and the atomic contributions of the solvent to the density.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"This example illustrates the regular usage of ComplexMixtures, to compute the minimum distance distribution function, KB-integrals and group contributions. ","category":"page"},{"location":"examples/#How-to-run-this-example-2","page":"Full Example","title":"How to run this example","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"cd ComplexMixturesExamples/Protein_in_Glycerol/MDDF\njulia -t auto mddf.jl","category":"page"},{"location":"examples/#Detailed-explanation-of-the-example:","page":"Full Example","title":"Detailed explanation of the example:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Loading the packages required for computing the MDDF. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"using PDBTools\nusing ComplexMixtures","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Load the pdb file of the system using PDBTools:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"atoms = readPDB(\"../Data/system.pdb\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Create arrays of atoms with the protein and Glycerol atoms, using the select function of the PDBTools package:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"protein = select(atoms,\"protein\")\nglyc = select(atoms,\"resname GLYC\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Setup solute and solvent structures, required for computing the MDDF, with Selection function of the ComplexMixtures package:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"solute = Selection(protein,nmols=1)\nsolvent = Selection(glyc,natomspermol=14)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Read and setup the Trajectory structure required for the computations:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"trajectory = Trajectory(\"../Data/glyc50_complete.dcd\",solute,solvent)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Run the calculation and get results:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"results = mddf(trajectory)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"note: Note\nTo change the options of the calculation, set the Options structure accordingly and pass it as a parameter to mddf. For example:options = Options(cutoff=10.)\nmddf(trajectory,options)The complete set of options available is described here.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Save the reults to recover them later if required","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"save(results,\"./glyc50.json\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The trajectory that was loaded was for a toy-example. The complete trajectory is available here, but it is a 3GB file. The same procedure above was performed with that file and produced the results_Glyc50.json file, which is available in the Data directory here. We will continue with this file instead. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Load the actual results obtained with the complete simulation:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"results = load(\"../Data/results_glyc50.json\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Results are loaded, and now we can plot the data obtained.","category":"page"},{"location":"examples/#Produce-plots","page":"Full Example","title":"Produce plots","text":"","category":"section"},{"location":"examples/#MDDF-and-Kirkwood-Buff-integrals","page":"Full Example","title":"MDDF and Kirkwood-Buff integrals","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Load some packages that we will use to produce the plots:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"using Plots, Plots.PlotMeasures, LaTeXStrings","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Some default options that make the plots prettier:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"default(\n fontfamily=\"Computer Modern\",\n linewidth=2, framestyle=:box, label=nothing, grid=false\n)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"First, we will plot the MDDF and the corresponding Kirkwood-Buff integral, which are available in the results.mddf and results.kb fields of the results data set. The distances are available in the results.d vector. We also plot here an horizontal line and save the figure as a pdf file. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"plot(layout=(1,2))\nplot!(results.d,results.mddf,xlabel=L\"r/\\AA\",ylabel=\"mddf\",subplot=1)\nhline!([1],linestyle=:dash,linecolor=:gray,subplot=1)\nplot!(\n results.d,results.kb/1000, #to L/mol\n xlabel=L\"r/\\AA\",ylabel=L\"G_{us}/\\mathrm{L~mol^{-1}}\",\n subplot=2\n)\nplot!(size=(800,300),margin=4mm)\nsavefig(\"./mddf.pdf\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"This will produce the following plot:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/#Atomic-contributions-to-the-MDDF","page":"Full Example","title":"Atomic contributions to the MDDF","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Selecting the atoms corresponding to the hydroxyl groups, and of the aliphatic carbons of Glycerol. Here we list the types of the atoms as specified by the force-field.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"hydroxyls = [\"O1\",\"O2\",\"O3\",\"H1\",\"H2\",\"H3\"]\naliphatic = [\"C1\",\"C2\",\"HA\",\"HB\",\"HC\",\"HD\"]","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The contributions function of ComplexMixtures will extract from the result the contributions of each set of atoms to the total MDDF:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"hydr_contributions = contributions(solvent,results.solvent_atom,hydroxyls)\naliph_contributions = contributions(solvent,results.solvent_atom,aliphatic)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"And, finally, here we plot these group contributions on top of the total MDDF:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"plot(results.d,results.mddf,xlabel=L\"r/\\AA\",ylabel=\"mddf\",size=(600,400))\nplot!(results.d,hydr_contributions,label=\"Hydroxils\")\nplot!(results.d,aliph_contributions,label=\"Aliphatic chain\")\nhline!([1],linestyle=:dash,linecolor=:gray)\nsavefig(\"./mddf_atom_contrib.pdf\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"This will produce the following figure:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Note how hydroxyl clearly are the sole contribution to the peak at ~1.9 Angstroms, corresponding to hydrogen-bonding interactions. The aliphatic groups contribute importantly to the shoulder at larger distances, which correspond to non-specific interactions. ","category":"page"},{"location":"examples/#D-residue-contribution-density-map","page":"Full Example","title":"2D residue contribution density map","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"In this example we compute the density map of Glycerol in the vicinity of a set of residues of a protein, from the minimum-distance distribution function. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The MDDF can be decomposed in the contributions of each atom of the solute or of the solvent. Here, we sum up te contributions of all the atoms of each residue of the solute, which is a protein, and plot a density map with the final information. The output figure obtained is:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/#How-to-run-this-example:","page":"Full Example","title":"How to run this example:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"cd ComplexMixturesExamples/Protein_in_Glycerol/Density2D\njulia density2D.jl","category":"page"},{"location":"examples/#Detailed-explanation-of-the-example:-2","page":"Full Example","title":"Detailed explanation of the example:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Here, we use the contourf function of the Plots package of Julia. A detailed explanation of the input file density2D.jl is provide below: ","category":"page"},{"location":"examples/#Loading-packages-that-will-be-used:","page":"Full Example","title":"Loading packages that will be used:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"using Plots\nusing LaTeXStrings\nusing Formatting\nusing ComplexMixtures, PDBTools","category":"page"},{"location":"examples/#Some-default-options-so-the-plot-looks-nice","page":"Full Example","title":"Some default options so the plot looks nice","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"plot_font = \"Computer Modern\"\ndefault(\n fontfamily=plot_font,\n linewidth=2, framestyle=:box, label=nothing\n)","category":"page"},{"location":"examples/#Read-the-PDB-file-(using-PDBTools)","page":"Full Example","title":"Read the PDB file (using PDBTools)","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"pdb = readPDB(\"./system.pdb\")","category":"page"},{"location":"examples/#Load-results-of-the-ComplexMixtures-run","page":"Full Example","title":"Load results of the ComplexMixtures run","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"R = load(\"./results_glyc50.json\") ","category":"page"},{"location":"examples/#Define-which-are-the-solute-molecules-(the-protein)","page":"Full Example","title":"Define which are the solute molecules (the protein)","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"protein = select(pdb,\"protein\")\nsolute = Selection(protein,nmols=1)","category":"page"},{"location":"examples/#Define-which-are-the-solvent-molecules-(Glycerol-here)","page":"Full Example","title":"Define which are the solvent molecules (Glycerol here)","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"glycerol = select(pdb,\"resname GLYC\")\nsolvent = Selection(glycerol,natomspermol=14)","category":"page"},{"location":"examples/#Retrive-the-resiude-contribution-data","page":"Full Example","title":"Retrive the resiude contribution data","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Collect which are the protein residues ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"residues = collect(eachresidue(protein))","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Set a matrix that will store the results, with a number of lines corresponding to the length of the MDDF histogram, and with a number of columns corresponding to the number of residues:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"rescontrib = zeros(length(R.mddf),length(residues))","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Now, collect the contribution of each residue as a column of the above matrix. The notation pairs(residues) returns tuples containg the index ires and the corresponding residue. The .= symbol sets each element of the corresponding column of the rescontrib matrix to the output of contributions (by broadcasting). ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"for (ires,residue) in pairs(residues)\n rescontrib[:,ires] .= contributions(solute,R.solute_atom,residue)\nend","category":"page"},{"location":"examples/#Plot-only-for-distances-within-1.5-and-3.5:","page":"Full Example","title":"Plot only for distances within 1.5 and 3.5:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Here, we will plot only the contributions from residue 70 to residue 110, and from distances ranging from 1.5 to 3.5 which is where most of the action occurs:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"irange=70:110\nidmin = findfirst( d -> d > 1.5, R.d)\nidmax = findfirst( d -> d > 3.5, R.d)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"To obtain pretty labels for the residues in the x-axis, we retrieve the one-letter residue names and concatenate them with the residue number converted to strings:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"labels = PDBTools.oneletter.(resname.(residues)).*format.(resnum.(residues))","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"And, finally, we produce the plot, with a series of options that make this particular contour plot look nice:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"contourf(\n irange, # x\n R.d[idmin:idmax], # y\n rescontrib[idmin:idmax,irange], # z\n xlabel=\"Residue\", ylabel=L\"r/\\AA\",\n xticks=(irange,labels[irange]), xrotation=60,\n xtickfont=font(6,plot_font),\n color=cgrad(:tempo), linewidth=0.1, linecolor=:black,\n colorbar=:none, levels=5,\n size=(500,280)\n)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The final figure is saved as a pdf file:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"savefig(\"./density2D.pdf\")","category":"page"},{"location":"examples/#D-residue-contribution-density-map-2","page":"Full Example","title":"3D residue contribution density map","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"In this example we compute three-dimensional representations of the density map of Glycerol in the vicinity of a set of residues of a protein, from the minimum-distance distribution function. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Here, the MDDF is decomposed at each distance according to the contributions of each solute (the protein) residue. The grid is created such that, at each point in space around the protein, it is possible to identify: ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Which atom is the closest atom of the solute to that point.\nWhich is the contribution of that atom (or residue) to the distribution function.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Therefore, by filtering the 3D density map at each distance one can visualize over the solute structure which are the regions that mostly interact with the solvent of choice at each distance. Typical images of such a density are:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"In the figure on the left, the points in space around the protein are selected with the following properties: distance from the protein smaller than 2.0Å and relative contribution to the MDDF at the corresponding distance of at least 10% of the maximum contribution. Thus, we are selecting the regions of the protein corresponding to the most stable hydrogen-bonding interactions. The color of the points is the contribution to the MDDF, from blue to red. Thus, the most reddish-points corresponds to the regions where the most stable hydrogen bonds were formed. We have marked two regions here, on opposite sides of the protein, with arrows.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Clicking on those points we obtain which are the atoms of the protein contributing to the MDDF at that region. In particular, the arrow on the right points to the strongest red region, which corresponds to an Aspartic acid. These residues are shown explicitly under the density (represented as a transparent surface) on the figure in the center.","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The figure on the right displays, overlapped with the hydrogen-bonding residues, the most important contributions to the second peak of the distribution, corresponding to distances from the protein between 2.0 and 3.5Å. Notably, the regions involved are different from the ones forming hydrogen bonds, indicating that non-specific interactions with the protein (and not a second solvation shell) are responsible for the second peak. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"A short tutorial video showing how to open the input and output PDB files in VMD and produce images of the density is available here: ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"
      \n\n
      ","category":"page"},{"location":"examples/#How-to-run-this-example:-2","page":"Full Example","title":"How to run this example:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"cd ComplexMixturesExamples/Protein_in_Glycerol/Density3D\njulia density3D.jl","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Alternatively, open Julia and copy/paste or the commands in density3D.jl or use include(\"./density3D.jl\"). These options will allow you to remain on the Julia section with access to the grid data structure that was generated and corresponds to the output grid.pdb file. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"This will create (actually overwrite) the grid.pdb file. Here we provide a previously setup VMD session that contains the data with the visualization choices used to generate the figure above. Load it with:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"vmd -e grid.vmd","category":"page"},{"location":"examples/#Detailed-explanation-of-the-example:-3","page":"Full Example","title":"Detailed explanation of the example:","text":"","category":"section"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"Initially we load the ComplexMixtures and PDBTools packages:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"using ComplexMixtures, PDBTools","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"With the readPDB function of PDBTools, we read the PDB file of the system simulated:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"pdb = readPDB(\"../Data/system.pdb\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"and using ComplexMixtures, we load the results from the calculation of the MDDF of Glycerol around the protein, which was computed previously:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"R = load(\"../Data/results_glyc50.json\") ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The solute here is the protein, and we need to setup the structures that define which atoms and type of solute it is. First, we select from the atoms of the pdb file of the system, those belonging to the protein, using select from PDBTools:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"protein = select(pdb,\"protein\")","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"and then we define the solute structure that is actually used in ComplexMixtures, by passing those atoms and specifying that the solute is a single molecule to the Selection function of ComplexMixtures:","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"solute = Selection(protein,nmols=1)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The 3D grid representing the density around the protein is computed with the grid3D function provided by ComplexMixtures. It receives the solute structure (of type Selection), the list of solute atoms (of type PDBTools.Atoms, as the protein selection above), the name of the output file and some optional parameters to define the grid. Here we compute the grid only between 1.5 and 3.5Å, characterizing the first and second solvation shells. The grid has by default a step of 0.5Å. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"grid = grid3D(\n solute=solute,\n solute_atoms=protein,\n mddf_result=R,\n output_file=\"grid.pdb\",\n dmin=1.5,\n dmax=3.5\n)","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"The command above will generate the grid, save it to grid.pdb and let it available in the grid.pdb array of atoms, for further inspection, if desired. ","category":"page"},{"location":"examples/","page":"Full Example","title":"Full Example","text":"By changing dmin, dmax, and step, one controls the grid size and resolution. This may generate very large output files.","category":"page"},{"location":"options/#options","page":"Options","title":"Options","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"There are some options to control what exactly is going to be computed to obtain the MDDF. These options can be defined by the user and passed to the mddf function, using, for example: ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"options = Options(lastframe=1000)\nresults = mddf(trajectory,options)","category":"page"},{"location":"options/#Common-options-that-the-user-might-want-to-set:","page":"Options","title":"Common options that the user might want to set:","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"firstframe: Integer, first frame of the trajectory to be considered.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"lastframe: Integer, last frame of the trajectory to be considered.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"stride: Integer, consider every stride frames, that is, if stride=5 only one in five frames will be considered.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"binstep: Real, length of the bin step of the histograms, default = 0.02 Angstroms.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"dbulk: Real, distance from which the solution is to be considered as a bulk solution, that is, where the presence of the solute does not affect the structure of the solution anymore. This parameter is important in particular for systems with a single solute molecule (a protein, for example), where the density of the solvent in the box is not the bulk density of the solvent, which must be computed independently. Default: 10 Angstroms. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"cutoff: Real, the maximum distance to be considered in the construction of histograms. Default: 10 Angstroms. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"usecutoff: true/false: If true, the cutoff distance might be different from dbulk and the density of the solvent in bulk will be estimated from the density within dbulk and cutoff. If false, the density of the solvent is estimated from the density outside dbulk by exclusion. Default: false. ","category":"page"},{"location":"options/#Options-that-most-users-will-probably-never-change:","page":"Options","title":"Options that most users will probably never change:","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"irefatom: Integer, index of the reference atom in the solvent molecule used to compute the shell volumes and domain volumes in the Monte-Carlo volume estimates. The final rdf data is reported for this atom as well. By default, we choose the atom which is closer to the center of coordinates of the molecule, but any choice should be fine. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"n_random_samples: Integer, how many samples of random molecules are generated for each solvent molecule to compute the shell volumes and random MDDF counts. Default: 10. Increase this only if you have short trajectory and want to obtain reproducible results for that short trajectory. For long trajectories (most desirable and common), this value can even be decreased to speed up the calculations. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"seed: Seed for random number generator. If -1, the seed will be generated from the entropy of the system. If your results are dependent on the seed, is is probable that you do not have enough sampling. Mostly used for testing purposes. Two runs are only identical if ran with the same seed and in serial mode. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"StableRNG (::Bool), defaults to false. Use a stable random number generator from the StableRNGs package, to produce identical runs on different architectures and Julia versions. Only used for testing. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"nthreads: How many threads to use. By default, it will be the number of physical cores of the computer.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"lcell: Integer, the cell length of the linked-cell method (actually the cell length is cutoff/lcell). Default: 1. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"GC: Bool, force garbage collection, to avoid memory overflow. Default: true. That this might be required is probably a result of something that can vastly improved in memory management. This may slow down parallel runs significantly if the GC runs too often.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"GC_threshold: Float64, minimum fraction of the total memory of the system required to force a GC run. That is, if GC_threshold=0.1, which is the default, every time the free memory becomes less or equal to 10% of the total memory available, a GC run occurs. ","category":"page"},{"location":"python/#python","page":"From Python","title":"From Python","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"note: Note\nMost features of the package are available through this Python interface. However, some flexibility may be reduced and, also, the tunning of the plot appearance is left to the user, as it is expected that he/she is fluent with some tools within Python if chosing this interface.Python 3 or greater is required.Please report issues, incompatibilities, or any other difficulty in using the package and its interface.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"The following examples consider a system composed a protein solvated by a mixture of water and glycerol, built with Packmol. The simulations were performed with NAMD with periodic boundary conditions and a NPT ensemble at room temperature and pressure. Molecular pictures were produced with VMD.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"
      \n\n
      ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"Image of the system of the example: a protein solvated by a mixture of glycreol (green) and water, at a concentration of 50%vv. The complete example is available at this repository.","category":"page"},{"location":"python/#Loading-the-ComplexMixtures.py-file","page":"From Python","title":"Loading the ComplexMixtures.py file","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"The Python interface of ComplexMixtures is implemented in the ComplexMixtures.py file. Just download it from the link and save it in a known path.","category":"page"},{"location":"python/#Installing-juliacall","page":"From Python","title":"Installing juliacall","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"juliacall is a package that allows calling Julia programs from Python. Install it with","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"pip install juliacall","category":"page"},{"location":"python/#Installing-Julia-and-underlying-packages","page":"From Python","title":"Installing Julia and underlying packages","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"Once juliacall is installed, from within Python, execute:","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"import ComplexMixtures","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"here we assume that the ComplexMixtures.py file is in the same directory where you launched Python.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"note: Note\nOn the first time you execute this command, the Julia executable and the required Julia packages (ComplexMixtures and PDBTools) will be downloaded and installed. At the end of the process quit Python (not really required, but we prefer to separate the installation from the use of the module). ","category":"page"},{"location":"python/#How-to-run-this-example","page":"From Python","title":"How to run this example","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"The Data directory contains the a pdb file of the system (system.pdb) and a sample from the trajectory (glyc50.dcd), with a few frames. It also contains the result of running the mddf calculation on the complete trajectory, results_glyc50.json. This last file was produced by ComplexMixtures, as indicated in the following examples. ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"The sample trajectory is provided so that the first example can be run, yet do not expect that the results are the same, as the sampling is much lower in this case. The complete trajectory can be retrieved from this link (3GB file). ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"We assume that you navigated to the directory of the example, and copied the Python module file to it: ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"git clone https://github.com/m3g/ComplexMixturesExamples\ncd ComplexMixturesExamples/Protein_in_Glycerol/MDDF\ncp /path/to/ComplexMixtures.py ./\nexport JULIA_NUM_THREADS=8","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"The last line will allow Julia to execute multi-threaded, which will improve a lot the performance on most machines. Set the number of threads to the number of cores of your computer.","category":"page"},{"location":"python/#Minimum-Distance-Distribuion-function","page":"From Python","title":"Minimum-Distance Distribuion function","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"Note that the example here follows an identical syntax to the Julia example, except that we qualify the name of the loaded module and implicitly load the PDBTools package.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"The script to compute the MDDFs as associated data from within python is, then:","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"import ComplexMixtures as cm\n\n# Load the pdb file of the system using `PDBTools`:\natoms = cm.readPDB(\"../Data/system.pdb\")\n\n# Create arrays of atoms with the protein and Glycerol atoms, \n# using the `select` function of the `PDBTools` package:\nprotein = cm.select(atoms,\"protein\")\nglyc = cm.select(atoms,\"resname GLYC\")\n\n# Setup solute and solvent structures, required for computing the MDDF, \n# with `Selection` function of the `ComplexMixtures` package:\nsolute = cm.Selection(protein,nmols=1)\nsolvent = cm.Selection(glyc,natomspermol=14)\n\n# Read and setup the Trajectory structure required for the computations:\ntrajectory = cm.Trajectory(\"../Data/glyc50_complete.dcd\",solute,solvent)\n\n# Run the calculation and get results:\nresults = cm.mddf(trajectory)\n\n# Save the reults to recover them later if required\ncm.save(results,\"./glyc50.json\")","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"note: Note\nTo change the options of the calculation, set the Options structure accordingly and pass it as a parameter to mddf. For example:options = cm.Options(cutoff=10.)\nresults = cm.mddf(trajectory,options)The complete set of options available is described here.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"The trajectory that was loaded was for a toy-example. The complete trajectory is available here, but it is a 3GB file. The same procedure above was performed with that file and produced the results_Glyc50.json file, which is available in the Data directory here. We will continue with this file instead. ","category":"page"},{"location":"python/#Produce-plots","page":"From Python","title":"Produce plots","text":"","category":"section"},{"location":"python/#MDDF-and-Kirkwood-Buff-integrals","page":"From Python","title":"MDDF and Kirkwood-Buff integrals","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"import ComplexMixtures as cm\nimport matplotlib.pyplot as plt\n\n# Load the actual results obtained with the complete simulation:\nresults = cm.load(\"../Data/results_glyc50.json\")\n\n# Plot MDDF and KB\nfig, axs = plt.subplots(2)\naxs[0].plot(results.d, results.mddf)\naxs[0].set(ylabel=\"MDDF\")\n\n# Plot KB integral\naxs[1].plot(results.d, results.kb)\naxs[1].set(xlabel=\"distance / Angs\", ylabel=\"MDDF\")\n\nplt.savefig(\"mddf_kb.png\")","category":"page"},{"location":"python/#Atomic-contributions-to-the-MDDF","page":"From Python","title":"Atomic contributions to the MDDF","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"Selecting the atoms corresponding to the hydroxyl groups, and of the aliphatic carbons of Glycerol. Here we list the types of the atoms as specified by the force-field. ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"import ComplexMixtures as cm\nimport matplotlib.pyplot as plt\n\natoms = cm.readPDB(\"../Data/system.pdb\")\nprotein = cm.select(atoms,\"protein\")\nglyc = cm.select(atoms,\"resname GLYC\")\nsolute = cm.Selection(protein,nmols=1)\nsolvent = cm.Selection(glyc,natomspermol=14)\n\n# load results\nresults = cm.load(\"../Data/results_glyc50.json\")\n\n# Select atoms by name\nhydroxyls = cm.list([\"O1\",\"O2\",\"O3\",\"H1\",\"H2\",\"H3\"])\naliphatic = cm.list([\"C1\",\"C2\",\"HA\",\"HB\",\"HC\",\"HD\"])\n\n# Extract the contributions of the groups above\nhydr_contributions = cm.contributions(solvent,results.solvent_atom,hydroxyls)\naliph_contributions = cm.contributions(solvent,results.solvent_atom,aliphatic)\n\n# Plot\nplt.plot(results.d, results.mddf)\nplt.plot(results.d, hydr_contributions)\nplt.plot(results.d, aliph_contributions)\nplt.xlabel(\"distance / Angs\")\nplt.ylabel(\"MDDF\")\nplt.savefig(\"group_contributions.png\")","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"note: Note\nThe syntax here diverges from the Julia-only examples by requiring the lists of names to be converted to Julia arrays, which happens by using the cm.list(python_list) function calls.","category":"page"},{"location":"#Introduction","page":"Introduction","title":"Introduction","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"ComplexMixtures.jl is a package to study the solute and solvent interactions of mixtures of molecules of complex shape. Conventional radial distribution functions are not appropriate to represent the structure of a solvent around a solute with many atoms, and a variable, non-spherical shape. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Typical solutes of complex shape are proteins, nucleic acids, and polymers in general. Smaller molecules like lipids, carbohydrates, etc, are also complex enough such that representing the structure of the solution of those molecules with distribution functions is not trivial.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Minimum-Distance Distribution Functions (MDDFs) are a very general and practical way to represent solute-solvent interactions for molecules with arbitrarily complex sizes and geometries. Briefly, instead of computing the density distribution function of a particular atom or the center-of-mass of the molecules, one computes the distribution function of the minimum-distance between any solute and solvent atoms. This provides a size and shape-independent distribution which is very natural to interpret in terms of molecular interactions. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Additionally, the MDDFs can be decomposed into contributions of each type of atom (or groups of atoms) of the solute and solvent molecules, such that the profiles of the distributions can be interpreted in terms of the chemical nature of the species involved in the interactions at each distance. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Finally, as with radial distribution functions, MDDFs can be used to compute Kirkwood-Buff integrals to connect the accumulation or depletion of the solvents components to thermodynamic properties, like protein structural stability, solubility, and others.","category":"page"},{"location":"#Features","page":"Introduction","title":"Features","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Check out our examples repository, featuring the analysis of solvation structures for proteins, polymers, membrane, and complex solutions! The examples are also described in our featured article.","category":"page"},{"location":"#.-Minimum-distance-distribution-functions:-understanding-solvation-at-a-molecular-level","page":"Introduction","title":"1. Minimum-distance distribution functions: understanding solvation at a molecular level","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"This figure illustrates one of the main features of minimum-distance distribution functions, by showing the distribution of DMF molecules at the surface of an polyacrylamide molecule. The direct interactions are evident by the peak at hydrogen-bonding distances and, additionally, the contribution of each group of atoms of the DMF can be clearly distinguished by decomposing the total MDDF into atomic or chemical group contributions. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"
      \n\n
      \nMinimum distance distribution function and its decomposition into the chemical\ngroups of the solvent (top) and solute (bottom) molecules.

      \n
      ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Decomposition of the total MDDF into the contributions of the solute atoms (in this case, a protein) is also possible. Any chemical group decomposition is possible. Here, we decompose the MDDF into the contribution of each protein residue. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"
      \n\n
      \nDensity map of a solvent in the vicinity of each protein residue. \n
      ","category":"page"},{"location":"#.-Thermodynamic-interpretation-through-Kirkwood-Buff-theory","page":"Introduction","title":"2. Thermodynamic interpretation through Kirkwood-Buff theory","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Minimum-distance distribution functions can be used to compute Kirkwood-Buff integrals, and thus, thermodynamic parameters associated to solvation. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Kirkwood-Buff integrals carry the information of the total accumulation or depletion of each solvent around a solute. For example, the figure below displays the KB integrals of an ionic liquid solvating different conformational states of a protein [link]. The figure illustrates that the solvation structures are dependent on the protein folding state. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"
      \n\n
      \nKirkwood-Buff integrals of an ionic liquid solvating a protein in different conformational states.

      \n
      ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"From differences in KB integrals among cossolvents, the Preferential Solvation parameter can be computed. This is an important parameter because it can be measured experimentally and is ultimately associated with the equilibrium thermodynamics of the solvation. In the following figure, we show that, for example, the preferential solvation of a protein in different folding states is dependent in a non-trivial way on the concentration of an ionic liquid in aqueous solutions. ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"
      \n\n
      \nPreferential interaction parameters obtained for the solvation of a protein by ionic liquids.

      \n
      ","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"In particular, the plot shows that besides being preferentially excluded from the protein surface at high concentrations in the native state, suggesting protein folding stabilization, the interactions with the protein in the denatured states are stronger, leading to denaturation at all concentrations. ","category":"page"},{"location":"#References","page":"Introduction","title":"References","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"L. Martínez, ComplexMixtures.jl: Investigating the structure of solutions of complex-shaped molecules from a solvent-shell perspective. J. Mol. Liq. 117945, 2021. [Full Text]\nL. Martínez, S. Shimizu, Molecular interpretation of preferential interactions in protein solvation: a solvent-shell perspective by means of minimum-distance distribution functions. J. Chem. Theor. Comp. 13, 6358–6372, 2017. [Full Text]","category":"page"},{"location":"#See-also","page":"Introduction","title":"See also","text":"","category":"section"},{"location":"#Seminar","page":"Introduction","title":"Seminar","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Presentation about ComplexMixtures.jl and protein-solvent interactions: https://youtu.be/umSRjsITzyA","category":"page"},{"location":"#Applications","page":"Introduction","title":"Applications","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"A. F. Pereira, V. Piccoli, L. Martínez, Trifluoroethanol direct interactions with protein backbones destabilize alpha-helices. J. Mol. Liq. 365, 120209, 2022. [Full Text]\nV. Piccoli, L. Martínez, Ionic liquid solvation of proteins in native and denatured states. J. Mol. Liq. 363, 119953, 2022. [Full Text]\nV. Piccoli, L. Martínez, Correlated counterion effects in the solvation of proteins by ionic-liquids. J. Mol. Liq. 320, 114347, 2020. [Full Text]\nI. P. de Oliveira, L. Martínez, The shift in urea orientation at protein surfaces at low pH is compatible with a direct mechanism of protein denaturation. Phys. Chem. Chem. Phys. 22, 354-367, 2020. [Full Text]\nI. P. de Oliveira, L. Martínez, Molecular basis for competitive solvation of the Burkholderia cepacia lipase by sorbitol and urea. Phys. Chem. Chem. Phys. 18, 21797-21808, 2016. [Full Text]","category":"page"}] } diff --git a/dev/selection/index.html b/dev/selection/index.html index eaa48a82..19c32127 100644 --- a/dev/selection/index.html +++ b/dev/selection/index.html @@ -8,4 +8,4 @@ solute = Selection(protein,nmols=1)

      If the solvent is, for instance, water, the indexes of the water molecules can be obtained with:

      water = PDBTools.select(atoms,"water")
       solvent = Selection(water,natomspermol=3)

      or, alternatively, a more compact syntax can be used, for example:

      water = PDBTools.select("system.pdb","resname TIP3P")
       solvent = Selection(water,natomspermol=3)

      or even providing just the names of the input file and selection, which will run PDBTools in background:

      solvent = Selection("sytem.pdb","water",water,natomspermol=3)
      Warning

      The selection syntax of PDBTools is somewhat limited. Verify if the selections correspond to the the desired sets of atoms every time.

      Using VMD

      VMD is a very popular and powerful package for visualization of simulations. It contains a very versatile library to read topologies and trajectory files, and a powerful selection syntax. We provide here a wrapper to VMD which allows using its capabilities.

      For example, the solute can be defined with:

      indexes, names = VMDselect("./system.gro","protein",vmd="/usr/bin/vmd")
      -solute = Selection(indexes,names,nmols=1)

      The main advantage here is that all the file types that VMD supports are supported. But VMD needs to be installed and is run in background, and it takes a few seconds.

      Warning

      VMD uses 0-based indexing and VMDselect adjusts that. However, if a selection is performed by index, as with index 1, VMD will select the second atom, and the output will be [2]. Selections by type, name, segment, residue name, etc, won't be a problem.

      +solute = Selection(indexes,names,nmols=1)

      The main advantage here is that all the file types that VMD supports are supported. But VMD needs to be installed and is run in background, and it takes a few seconds.

      Warning

      VMD uses 0-based indexing and VMDselect adjusts that. However, if a selection is performed by index, as with index 1, VMD will select the second atom, and the output will be [2]. Selections by type, name, segment, residue name, etc, won't be a problem.

      diff --git a/dev/tools/index.html b/dev/tools/index.html index bbaca77f..eba127f2 100644 --- a/dev/tools/index.html +++ b/dev/tools/index.html @@ -88,4 +88,4 @@ -------------------------------------------------------------------------------

      In this case, since solute and solvent are equivalent and the system is homogeneous, the molar volumes and concentrations are similar. This is not the case if the molecules are different or if the solute is at infinite dilution (in which case the bulk solvent density might be different from the solvent density in the simulation).

      To retrieve the data of the overview structure use, for example:

      julia> overview = overview(results);
       
       julia> overview.solute_molar_volume
      -657.5051512801567
      +657.5051512801567 diff --git a/dev/trajectory/index.html b/dev/trajectory/index.html index 8be51693..390adb08 100644 --- a/dev/trajectory/index.html +++ b/dev/trajectory/index.html @@ -1,2 +1,2 @@ -Loading the trajectory · ComplexMixtures.jl

      Loading trajectories

      To initialize a trajectory file for computation, use the command

      trajectory = Trajectory("trajectory.xtc",solute,solvent)

      where solute and solvent are defined with the Selection function described before. This function opens the stream for reading frames, which are read once a time when the coordinates are required for computing the MDDF.

      The Trajectory function uses Chemfiles in background, and thus the most common trajectory formats are supported, as the ones produced with NAMD, Gromacs, LAMMPS, Amber, etc.

      Tip

      The format of the trajectory file is automatically determined by Chemfiles from the extension of the file. However, it can be provided by the user with the format keyword, for example:

      trajectory = Trajectory("trajectory.xtc",solute,solvent,format="xtc")
      +Loading the trajectory · ComplexMixtures.jl

      Loading trajectories

      To initialize a trajectory file for computation, use the command

      trajectory = Trajectory("trajectory.xtc",solute,solvent)

      where solute and solvent are defined with the Selection function described before. This function opens the stream for reading frames, which are read once a time when the coordinates are required for computing the MDDF.

      The Trajectory function uses Chemfiles in background, and thus the most common trajectory formats are supported, as the ones produced with NAMD, Gromacs, LAMMPS, Amber, etc.

      Tip

      The format of the trajectory file is automatically determined by Chemfiles from the extension of the file. However, it can be provided by the user with the format keyword, for example:

      trajectory = Trajectory("trajectory.xtc",solute,solvent,format="xtc")