diff --git a/v2.7.2/.documenter-siteinfo.json b/v2.7.2/.documenter-siteinfo.json index eeacce53..31bd8f62 100644 --- a/v2.7.2/.documenter-siteinfo.json +++ b/v2.7.2/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-08-06T11:39:57","documenter_version":"1.5.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.4","generation_timestamp":"2024-08-06T11:50:56","documenter_version":"1.5.0"}} \ No newline at end of file diff --git a/v2.7.2/contributions/index.html b/v2.7.2/contributions/index.html index 134adbad..75c7bfe2 100644 --- a/v2.7.2/contributions/index.html +++ b/v2.7.2/contributions/index.html @@ -63,7 +63,7 @@ rc2 = ResidueContributions(result2, select(atoms, "protein")) # difference of the residue contributions between the two simulations: rc_diff = rc2 - rc1 -contourf(rc_diff) # plots a contour map of the difference
Compat

Slicing, indexing, and multiplication and divison by scalars were introduces in v2.7.0.

source
ComplexMixtures.contributionsMethod
contributions(R::Result, group::Union{SoluteGroup,SolventGroup}; type = :mddf)

Returns the contributions of the atoms of the solute or solvent to the MDDF, coordination number, or MD count.

Arguments

  • R::Result: The result of a calculation.
  • group::Union{SoluteGroup,SolventGroup}: The group of atoms to consider.
  • type::Symbol: The type of contributions to return. Can be :mddf (default), :coordination_number, or :md_count.

Examples

julia> using ComplexMixtures, PDBTools
+contourf(rc_diff) # plots a contour map of the difference
Compat

Slicing, indexing, and multiplication and divison by scalars were introduces in v2.7.0.

source
ComplexMixtures.contributionsMethod
contributions(R::Result, group::Union{SoluteGroup,SolventGroup}; type = :mddf)

Returns the contributions of the atoms of the solute or solvent to the MDDF, coordination number, or MD count.

Arguments

  • R::Result: The result of a calculation.
  • group::Union{SoluteGroup,SolventGroup}: The group of atoms to consider.
  • type::Symbol: The type of contributions to return. Can be :mddf (default), :coordination_number, or :md_count.

Examples

julia> using ComplexMixtures, PDBTools
 
 julia> dir = ComplexMixtures.Testing.data_dir*"/Gromacs";
 
@@ -89,4 +89,4 @@
 
 julia> ca_cb = contributions(results, SoluteGroup(["CA", "CB"])); # contribution of CA and CB atoms to the MDDF
 
-julia> ca_cb = contributions(results, SoluteGroup(["CA", "CB"]); type=:coordination_number); # contribution of CA and CB atoms to the coordination number
source
+julia> ca_cb = contributions(results, SoluteGroup(["CA", "CB"]); type=:coordination_number); # contribution of CA and CB atoms to the coordination numbersource diff --git a/v2.7.2/example1/index.html b/v2.7.2/example1/index.html index 44e42138..4784152f 100644 --- a/v2.7.2/example1/index.html +++ b/v2.7.2/example1/index.html @@ -153,4 +153,4 @@

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.

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.

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.

How to run this example:

Assuming that the input files are available in the script directory, just run the script with:

julia density3D.jl

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.

This will create 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:

vmd -e grid.vmd

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:

-
+ diff --git a/v2.7.2/example2/index.html b/v2.7.2/example2/index.html index f8121fdc..ad6e21d9 100644 --- a/v2.7.2/example2/index.html +++ b/v2.7.2/example2/index.html @@ -250,4 +250,4 @@ savefig("./map2D_acr.png") println("Plot saved to map2D_acr.png")

Output

The terminal methyl groups interact strongly with DMF, and strong local density augmentations are visible in particular on the amine groups. These occur at less than 2.0Angs and are characteristic of hydrogen-bond interactions. Interestingly, the DMF molecules are excluded from the aliphatic and carbonyl groups of the polymer, relative to the other groups.

Finally, it is noticeable that the central mer is more weakly solvated by DMF than the mers approaching the extremes of the polymer chain. This is likely a result of the partial folding of the polymer, that protects that central mers from the solvent in a fraction of the polymer configurations.

-

References

Molecules built with JSME: B. Bienfait and P. Ertl, JSME: a free molecule editor in JavaScript, Journal of Cheminformatics 5:24 (2013) http://biomodel.uah.es/en/DIY/JSME/draw.en.htm

The system was built with Packmol.

The simulations were perfomed with NAMD, with CHARMM36 parameters.

+

References

Molecules built with JSME: B. Bienfait and P. Ertl, JSME: a free molecule editor in JavaScript, Journal of Cheminformatics 5:24 (2013) http://biomodel.uah.es/en/DIY/JSME/draw.en.htm

The system was built with Packmol.

The simulations were perfomed with NAMD, with CHARMM36 parameters.

diff --git a/v2.7.2/example3/index.html b/v2.7.2/example3/index.html index f26770cc..23b5458b 100644 --- a/v2.7.2/example3/index.html +++ b/v2.7.2/example3/index.html @@ -512,4 +512,4 @@ annotate!(12, 2.7, text("Palmitoyl", :left, 12, plot_font), subplot=2) savefig("POPC_water_chains.png") -println("The plot was saved as POPC_water_chains.png")

Ethanol displays an important density augmentation at the vicinity of the carbonyl that follows the glycerol group, and accumulates on the proximity of the aliphatic chain. The density of ethanol decreases as one advances into the aliphatic chain, displaying a minimum around the insaturation in the Oleoyl chain. The terminal methyl group of both chains display a greater solvation by ethanol, suggesting the twisting of the aliphatic chain expose these terminal groups to membrane depth where ethanol is already abundant.

The equivalent maps for water are strikingly different, and show that water is excluded from the interior of the membrane:

References

Membrane built with the VMD membrane plugin.

Water and ethanol layers added with Packmol.

The simulations were performed with NAMD, with CHARMM36 parameters.

Density of the ethanol-water mixture from: https://wissen.science-and-fun.de/chemistry/chemistry/density-tables/ethanol-water-mixtures/

+println("The plot was saved as POPC_water_chains.png")

Ethanol displays an important density augmentation at the vicinity of the carbonyl that follows the glycerol group, and accumulates on the proximity of the aliphatic chain. The density of ethanol decreases as one advances into the aliphatic chain, displaying a minimum around the insaturation in the Oleoyl chain. The terminal methyl group of both chains display a greater solvation by ethanol, suggesting the twisting of the aliphatic chain expose these terminal groups to membrane depth where ethanol is already abundant.

The equivalent maps for water are strikingly different, and show that water is excluded from the interior of the membrane:

References

Membrane built with the VMD membrane plugin.

Water and ethanol layers added with Packmol.

The simulations were performed with NAMD, with CHARMM36 parameters.

Density of the ethanol-water mixture from: https://wissen.science-and-fun.de/chemistry/chemistry/density-tables/ethanol-water-mixtures/

diff --git a/v2.7.2/example4/index.html b/v2.7.2/example4/index.html index 46fe23d4..8c5eeabe 100644 --- a/v2.7.2/example4/index.html +++ b/v2.7.2/example4/index.html @@ -279,4 +279,4 @@ ) savefig("./GlycerolWater_map.png") -println("Plot saved to GlycerolWater_map.png")

The interesting result here is that the $\mathrm{CH}$ group of glycerol is protected from both solvents. There is a strong density augmentation at the vicinity of hydroxyl groups, and the second peak of the MDDFs is clearly associated to interactions with the $\mathrm{CH_2}$ groups.

+println("Plot saved to GlycerolWater_map.png")

The interesting result here is that the $\mathrm{CH}$ group of glycerol is protected from both solvents. There is a strong density augmentation at the vicinity of hydroxyl groups, and the second peak of the MDDFs is clearly associated to interactions with the $\mathrm{CH_2}$ groups.

diff --git a/v2.7.2/examples/index.html b/v2.7.2/examples/index.html index b69e7ce5..6d8f0889 100644 --- a/v2.7.2/examples/index.html +++ b/v2.7.2/examples/index.html @@ -2,4 +2,4 @@ Examples: · ComplexMixtures.jl

Examples

List of examples

How to run these examples

1 Download and install Julia

To run the scripts, we suggest the following procedure:

  1. Create a directory, for example example1.
  2. Copy the required data files, indicated in each example.
  3. Launch julia in that directory, activate the directory environment, and install the required packages. This is done by launching Julia and executing:
    import Pkg 
     Pkg.activate(".")
     Pkg.add(["ComplexMixtures", "PDBTools", "Plots", "LaTeXStrings", "EasyFit"])
    -exit()
  4. Copy the code of each script in to a file, and execute with:
    julia -t auto script.jl
    Alternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation. For a more advanced Julia usage, we suggest the VSCode IDE with the Julia Language Support extension.
+exit()
  • Copy the code of each script in to a file, and execute with:
    julia -t auto script.jl
    Alternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation. For a more advanced Julia usage, we suggest the VSCode IDE with the Julia Language Support extension.
  • diff --git a/v2.7.2/index.html b/v2.7.2/index.html index 8649ca06..35298af7 100644 --- a/v2.7.2/index.html +++ b/v2.7.2/index.html @@ -16,4 +16,4 @@
    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

    Please cite the following articles if the package was useful to you:

    See also

    Seminar

    Applications

    +

    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

    Please cite the following articles if the package was useful to you:

    See also

    Seminar

    Applications

    diff --git a/v2.7.2/installation/index.html b/v2.7.2/installation/index.html index 3fdb6f79..a48cf85f 100644 --- a/v2.7.2/installation/index.html +++ b/v2.7.2/installation/index.html @@ -11,4 +11,4 @@ using LaTeXStrings # 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 acronym. For example:

    import ComplexMixtures as CM
    -CM.mddf(...)
    +CM.mddf(...) diff --git a/v2.7.2/mddf/index.html b/v2.7.2/mddf/index.html index f85d403b..d9374585 100644 --- a/v2.7.2/mddf/index.html +++ b/v2.7.2/mddf/index.html @@ -21,8 +21,8 @@ julia> options = Options(lastframe=10, bulk_range=(10.0, 15.0)); -julia> results = mddf(trajectory, options)source

    The mddf functions is run with, for example:

    results = mddf(trajectory, Options(bulk_range=(10.0, 15.0)))  

    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 bulk_range and stride.

    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, bulk_range=(10.0, 15.0))
    +julia> results = mddf(trajectory, options)
    source

    The mddf functions is run with, for example:

    results = mddf(trajectory, Options(bulk_range=(10.0, 15.0)))  

    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 bulk_range and stride.

    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, bulk_range=(10.0, 15.0))
     results = mddf(trajectory, options)
    Note

    bulk_range defines the subset of the system, as defined according to a range of distances from the solute, that are to be considered as the bulk solution. Within this range of distances, the user believes that the reference solute molecule does not significantly affect anymore the structure of the solvent.

    By default, all molecules above 10 Angstroms from the solute are considered bulk molecules (corresponding to Options(dbulk=10.0)), but it is highly recommended to use a manual definition of bulk_range.

    The definition of a range of distances within the system to compute the bulk density is adequate because this system subset is then an open system with a solvent molecule reservoir. The adequate choice of bulk_range can be inspected by the proper convergence of the distribution functions (which must converge to 1.0) and a proper convergence of the KB integrals.

    The bulk_range option was introduced in version 2.1.0.

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

    Coordination numbers only

    The coordination_number function, called with the same arguments as the mddf function, can be used to compute coordination numbers without the normalization required for the MDDF:

    ComplexMixtures.coordination_numberMethod
    coordination_number(
         trajectory::Trajectory, options::Options;
         kargs...
    -)

    Computes the coordination numbers for each solute molecule in the trajectory, given the Trajectory. This is an auxiliary function of the ComplexMixtures package, which is used to compute coordination numbers when the normalization of the distribution is not possible or needed.

    The output is a Result structure, which contains the data as the result of a call to mddf, except that all counters which require normalization of the distribution will be zero. In summary, this result data structure can be used to compute the coordination numbers, but not the MDDF, RDF, or KB integrals.

    The keyword arguments are the same as for the mddf function, and are passed to it. This function is a wrapper around mddf with the coordination_number_only keyword set to true.

    source

    This function can be useful if the normalization is not possible or meaningful. The computation is much faster if the normalization is not necessary.

    Note

    The mddf, kb, and random count parameters will be empty when using this options, and are meaningless.

    +)

    Computes the coordination numbers for each solute molecule in the trajectory, given the Trajectory. This is an auxiliary function of the ComplexMixtures package, which is used to compute coordination numbers when the normalization of the distribution is not possible or needed.

    The output is a Result structure, which contains the data as the result of a call to mddf, except that all counters which require normalization of the distribution will be zero. In summary, this result data structure can be used to compute the coordination numbers, but not the MDDF, RDF, or KB integrals.

    The keyword arguments are the same as for the mddf function, and are passed to it. This function is a wrapper around mddf with the coordination_number_only keyword set to true.

    source

    This function can be useful if the normalization is not possible or meaningful. The computation is much faster if the normalization is not necessary.

    Note

    The mddf, kb, and random count parameters will be empty when using this options, and are meaningless.

    diff --git a/v2.7.2/multiple/index.html b/v2.7.2/multiple/index.html index 622bda83..5b5a4dcc 100644 --- a/v2.7.2/multiple/index.html +++ b/v2.7.2/multiple/index.html @@ -18,4 +18,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/v2.7.2/options/index.html b/v2.7.2/options/index.html index 1d855659..29258e64 100644 --- a/v2.7.2/options/index.html +++ b/v2.7.2/options/index.html @@ -18,4 +18,4 @@ StableRNG::Bool = false, nthreads::Int = 0, silent::Bool = false -)

    Create an Options object with the specified options.

    source +)

    Create an Options object with the specified options.

    source diff --git a/v2.7.2/parallel/index.html b/v2.7.2/parallel/index.html index 7377f593..f8445819 100644 --- a/v2.7.2/parallel/index.html +++ b/v2.7.2/parallel/index.html @@ -1,3 +1,3 @@ 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 N option, where N is the number of processes to be used. For example, to use 8 parallel processes, use:

    julia -t 8 example.jl

    The computation will use a number of parallel processes equal to N. Use -t auto to automatically pick the number of threads available in your computer.

    Optimal number of threads

    The number of threads used for computation of the MDDF is the number of threads available to Julia. Many computers allow hyperthreading, and not necessarily this this beneficial for the execution of this package. The optimal number of threads may vary. Some newer CPUs have "energy saving" cores, which are also relatively slow.

    Independently of the number of threads initialized with the -t command-line parameter, the number of processes launched by ComplexMixtures in any given computation can be adjusted by the Options(nthreads=N) option. This won't provide any speedup if the optional number of threads is greater than the number of threads available to Julia at runtime.

    Memory issues

    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.

    The main reason for memory exhaustion is the annotation of the contributions of each atom of the solute molecules to the total counts. By default, in a parallel run, one copy of such data structures is saved for each thread. This might be an issue if the solute is molecular structure with many hundreds of thousand atoms, and if the number of CPUs available is very high, but memory is not as abundant.

    There are different ways to deal with this issue:

    1. Use predefined groups, to reduce the size of the group array contributions.
    2. Use the low_memory=true option the call to mddf (for example with mddf(traj, options; low_memory=true).
    3. Reduce the number of threads used (with Options(nthreads=N)).
    4. Increase the frequency of garbage collection calls:
      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.3.
    +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.3. diff --git a/v2.7.2/python/index.html b/v2.7.2/python/index.html index c76cf290..7367c9d2 100644 --- a/v2.7.2/python/index.html +++ b/v2.7.2/python/index.html @@ -83,4 +83,4 @@ plt.legend() plt.xlabel("distance / Angs") plt.ylabel("MDDF") -plt.savefig("group_contributions.png")

    Despite the low sampling, it is clear that hydroxyl groups contribute to the greter peak of the distribution, at hydrogen-bonding distances, as expected. The contributions of the aliphatic groups to the MDDF occurs at longer distances, associated to non-specific interactions.

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

    Despite the low sampling, it is clear that hydroxyl groups contribute to the greter peak of the distribution, at hydrogen-bonding distances, as expected. The contributions of the aliphatic groups to the MDDF occurs at longer distances, associated to non-specific interactions.

    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/v2.7.2/quickguide/index.html b/v2.7.2/quickguide/index.html index 123a9fc6..0d1ff71f 100644 --- a/v2.7.2/quickguide/index.html +++ b/v2.7.2/quickguide/index.html @@ -51,4 +51,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 / Å", ylabel="KB(d) / L / mol") 

    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/v2.7.2/references/index.html b/v2.7.2/references/index.html index ae82bfd1..de12eff2 100644 --- a/v2.7.2/references/index.html +++ b/v2.7.2/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. 347, 117945, 2022. [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

    • V. Piccoli, L. Martínez, Competitive Effects of Anions on Protein Solvation by Aqueous Ionic Liquids. J. Phys. Chem. B 2024. [Full Text]

    • A. F. Pereira, L. Martínez, Helical Content Correlations and Hydration Structures of the Folding Ensemble of the B Domain of Protein A. J. Chem. Inf. Model. 64, 3350-3359, 2024. [Full 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]

    • 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, neighbor 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. 347, 117945, 2022. [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

    • V. Piccoli, L. Martínez, Competitive Effects of Anions on Protein Solvation by Aqueous Ionic Liquids. J. Phys. Chem. B 2024. [Full Text]

    • A. F. Pereira, L. Martínez, Helical Content Correlations and Hydration Structures of the Folding Ensemble of the B Domain of Protein A. J. Chem. Inf. Model. 64, 3350-3359, 2024. [Full 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]

    • 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, neighbor lists, etc.

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

    diff --git a/v2.7.2/results/index.html b/v2.7.2/results/index.html index abf66098..487a7fdb 100644 --- a/v2.7.2/results/index.html +++ b/v2.7.2/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. Note that all coordinates that are read automatically here (by the Chemfiles) library will be in Angstroms, independently on the software used to generate the trajectories.

    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 soluteAtomSelectionContains the number of atoms, number of atoms per molecule and number of molecules of the solute.
    solventProperties of the solvent.AtomSelectionContains 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

    Reference functions

    ComplexMixtures.DensityType
    mutable struct Density

    Structure to contain the density values obtained from the calculation.

    • solute::Float64

    • solvent::Float64

    • solvent_bulk::Float64

    source
    ComplexMixtures.ResultType
    mutable struct Result

    Structure to contain the results of the MDDF calculation.

    • Version::VersionNumber

    • nbins::Int64

    • dbulk::Float64

    • cutoff::Float64

    • d::Vector{Float64}

    • md_count::Vector{Float64}

    • md_count_random::Vector{Float64}

    • coordination_number::Vector{Float64}

    • coordination_number_random::Vector{Float64}

    • mddf::Vector{Float64}

    • kb::Vector{Float64}

    • autocorrelation::Bool

    • solute::AtomSelection

    • solvent::AtomSelection

    • solute_group_count::Vector{Vector{Float64}}

    • solvent_group_count::Vector{Vector{Float64}}

    • rdf_count::Vector{Float64}

    • rdf_count_random::Vector{Float64}

    • sum_rdf_count::Vector{Float64}

    • sum_rdf_count_random::Vector{Float64}

    • rdf::Vector{Float64}

    • kb_rdf::Vector{Float64}

    • density::ComplexMixtures.Density

    • volume::ComplexMixtures.Volume

    • files::Vector{ComplexMixtures.TrajectoryFileOptions}

    • weights::Vector{Float64}

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

    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
    ComplexMixtures.loadMethod
    load(filename::String)

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

    source
    ComplexMixtures.overviewMethod
    overview(R::Result)

    Function that outputs the volumes and densities in the most natural units.

    source
    ComplexMixtures.saveMethod
    save(R::Result, filename::String)

    Function to write the result data structure to a json file.

    source
    +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. Note that all coordinates that are supported by default (and are thus read by the Chemfiles library) will be in Å, independently on the software used to generate the trajectories, as described here [http://chemfiles.org/chemfiles/latest/overview.html#units].

    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 soluteAtomSelectionContains the number of atoms, number of atoms per molecule and number of molecules of the solute.
    solventProperties of the solvent.AtomSelectionContains 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

    Reference functions

    ComplexMixtures.DensityType
    mutable struct Density

    Structure to contain the density values obtained from the calculation.

    • solute::Float64

    • solvent::Float64

    • solvent_bulk::Float64

    source
    ComplexMixtures.ResultType
    mutable struct Result

    Structure to contain the results of the MDDF calculation.

    • Version::VersionNumber

    • nbins::Int64

    • dbulk::Float64

    • cutoff::Float64

    • d::Vector{Float64}

    • md_count::Vector{Float64}

    • md_count_random::Vector{Float64}

    • coordination_number::Vector{Float64}

    • coordination_number_random::Vector{Float64}

    • mddf::Vector{Float64}

    • kb::Vector{Float64}

    • autocorrelation::Bool

    • solute::AtomSelection

    • solvent::AtomSelection

    • solute_group_count::Vector{Vector{Float64}}

    • solvent_group_count::Vector{Vector{Float64}}

    • rdf_count::Vector{Float64}

    • rdf_count_random::Vector{Float64}

    • sum_rdf_count::Vector{Float64}

    • sum_rdf_count_random::Vector{Float64}

    • rdf::Vector{Float64}

    • kb_rdf::Vector{Float64}

    • density::ComplexMixtures.Density

    • volume::ComplexMixtures.Volume

    • files::Vector{ComplexMixtures.TrajectoryFileOptions}

    • weights::Vector{Float64}

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

    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
    ComplexMixtures.loadMethod
    load(filename::String)

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

    source
    ComplexMixtures.overviewMethod
    overview(R::Result)

    Function that outputs the volumes and densities in the most natural units.

    source
    ComplexMixtures.saveMethod
    save(R::Result, filename::String)

    Function to write the result data structure to a json file.

    source
    diff --git a/v2.7.2/save/index.html b/v2.7.2/save/index.html index 7ca40309..419fe76e 100644 --- a/v2.7.2/save/index.html +++ b/v2.7.2/save/index.html @@ -3,4 +3,4 @@ R::Result, filename::String; solute_group_names::Vector{String} = R.solute.group_names, solvent_group_names::Vector{String} = R.solvent.group_names, -)

    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 group names are defined in R, the solute_group_names and solvent_group_names arguments are not necessary. If they are not defined, the user can pass the names of the groups as strings in the solute_group_names and solvent_group_names arguments.

    source +)

    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 group names are defined in R, the solute_group_names and solvent_group_names arguments are not necessary. If they are not defined, the user can pass the names of the groups as strings in the solute_group_names and solvent_group_names arguments.

    source diff --git a/v2.7.2/search_index.js b/v2.7.2/search_index.js index 1d3d5549..a81aa6a6 100644 --- a/v2.7.2/search_index.js +++ b/v2.7.2/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. 347, 117945, 2022. [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":"V. Piccoli, L. Martínez, Competitive Effects of Anions on Protein Solvation by Aqueous Ionic Liquids. J. Phys. Chem. B 2024. [Full Text]\nA. F. Pereira, L. Martínez, Helical Content Correlations and Hydration Structures of the Folding Ensemble of the B Domain of Protein A. J. Chem. Inf. Model. 64, 3350-3359, 2024. [Full Text]\nA. 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, neighbor 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, Options(bulk_range=(8.0, 12.0)))","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. Note that all coordinates that are read automatically here (by the Chemfiles) library will be in Angstroms, independently on the software used to generate the trajectories. ","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 AtomSelection Contains the number of atoms, number of atoms per molecule and number of molecules of the solute.\nsolvent Properties of the solvent. AtomSelection 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":"results/#Reference-functions","page":"Results","title":"Reference functions","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"Modules = [ComplexMixtures]\nPages = [\"results.jl\"]","category":"page"},{"location":"results/#ComplexMixtures.Density","page":"Results","title":"ComplexMixtures.Density","text":"mutable struct Density\n\nStructure to contain the density values obtained from the calculation.\n\nsolute::Float64\nsolvent::Float64\nsolvent_bulk::Float64\n\n\n\n\n\n","category":"type"},{"location":"results/#ComplexMixtures.Result","page":"Results","title":"ComplexMixtures.Result","text":"mutable struct Result\n\nStructure to contain the results of the MDDF calculation.\n\nVersion::VersionNumber\nnbins::Int64\ndbulk::Float64\ncutoff::Float64\nd::Vector{Float64}\nmd_count::Vector{Float64}\nmd_count_random::Vector{Float64}\ncoordination_number::Vector{Float64}\ncoordination_number_random::Vector{Float64}\nmddf::Vector{Float64}\nkb::Vector{Float64}\nautocorrelation::Bool\nsolute::AtomSelection\nsolvent::AtomSelection\nsolute_group_count::Vector{Vector{Float64}}\nsolvent_group_count::Vector{Vector{Float64}}\nrdf_count::Vector{Float64}\nrdf_count_random::Vector{Float64}\nsum_rdf_count::Vector{Float64}\nsum_rdf_count_random::Vector{Float64}\nrdf::Vector{Float64}\nkb_rdf::Vector{Float64}\ndensity::ComplexMixtures.Density\nvolume::ComplexMixtures.Volume\nfiles::Vector{ComplexMixtures.TrajectoryFileOptions}\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":"results/#Base.merge-Tuple{Vector{<:Result}}","page":"Results","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":"results/#ComplexMixtures.load-Tuple{String}","page":"Results","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":"results/#ComplexMixtures.overview-Tuple{Result}","page":"Results","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":"results/#ComplexMixtures.save-Tuple{Result, String}","page":"Results","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":"contributions/#contributions","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"section"},{"location":"contributions/","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":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"To obtain the atomic contributions of an atom or group of atoms to the MDDF, the coordination number, or the site count at each distance, 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":"contributions/","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 = AtomSelection(protein,nmols=1)\nsolvent = AtomSelection(water,natomspermol=3)","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The MDDF calculation is executed with:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"trajectory = Trajectory(\"trajectory.dcd\",solute,solvent)\nresults = mddf(trajectory, Options(bulk_range=(8.0, 12.0)))","category":"page"},{"location":"contributions/#Atomic-contributions-in-the-result-data-structure","page":"Atomic and group contributions","title":"Atomic contributions in the result data structure","text":"","category":"section"},{"location":"contributions/","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 contributions can be retrieved using the contributions function, with the SoluteGroup and SolventGroup selectors.","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"For example, if the MDDF of water (solvent) relative to a solute was computed, and water has atom names OH2, H1, H2, one can retrieve the contributions of the oxygen atom with:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"OH2 = contributions(results, SolventGroup([\"OH2\"]))","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"or with, if OH2 is the first atom in the molecule,","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"OH2 = contributions(results, SolventGroup([1]))","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The contributions of the hydrogen atoms can be obtained, similarly, with:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"H = contributions(results, SolventGroup([\"H1\", \"H2\"]))","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"or with, if OH2 is the first atom in the molecule,","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"H = contributions(results, SolventGroup([2, 3]))","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Each of these calls will return a vector of the constributions of these atoms to the total MDDF. ","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"For example, here we plot the total MDDF and the Oxygen contributions: ","category":"page"},{"location":"contributions/","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, contributions(results, SolventGroup([\"OH2\"])), label=[\"OH2\"], linewidth=2)\nplot!(xlabel=\"Distance / Å\", ylabel=\"MDDF\")","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"page"},{"location":"contributions/#Contributions-to-coordination-numbers-or-site-counts","page":"Atomic and group contributions","title":"Contributions to coordination numbers or site counts","text":"","category":"section"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The keyword type defines the return type of the contribution:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"type=:mddf : the contribution of the group to the MDDF is returned (default).\ntype=:coordination_number : the contribution of the group to the coordination number, that is, the cumulative sum of counts at each distance, is returned.\ntype=:md_count : the contribution of the group to the site count at each distance is returned. ","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Example of the usage of the type option:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"ca_contributions = contributions(results, SoluteGroup([\"CA\"]); type=:coordination_number)","category":"page"},{"location":"contributions/#Using-PDBTools","page":"Atomic and group contributions","title":"Using PDBTools","text":"","category":"section"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"If the solute is a protein, or other complex molecule, selections defined with PDBTools can be used. For example, this will retrieve the contribution of the acidic residues of a protein to total MDDF:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"using PDBTools\natoms = readPDB(\"system.pdb\")\nacidic_residues = select(atoms, \"acidic\")\nacidic_contributions = contributions(results, SoluteGroup(acidic_residues))","category":"page"},{"location":"contributions/","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":"contributions/","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":"contributions/","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":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"charged_residues = PDBTools.select(atoms,\"charged\")\ncharged_contributions = contributions(results, SoluteGroup(charged_residues))\n\nneutral_residues = PDBTools.select(atoms,\"neutral\")\nneutral_contributions = contributions(atoms, SoluteGroup(neutral_residues))","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The charged_contributions and neutral_contributions outputs are vectors containing the contributions of these residues to the total MDDF. The corresponding plot is: ","category":"page"},{"location":"contributions/","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":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Resulting in:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"page"},{"location":"contributions/","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":"contributions/#Reference-functions","page":"Atomic and group contributions","title":"Reference functions","text":"","category":"section"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Modules = [ComplexMixtures]\nPages = [\"contributions.jl\"]","category":"page"},{"location":"contributions/#ComplexMixtures.ResidueContributions","page":"Atomic and group contributions","title":"ComplexMixtures.ResidueContributions","text":"ResidueContributions (data structure)\n\nConstructor function:\n\nResidueContributions(\n results::Result, atoms::AbstractVector{PDBTools.Atom};\n dmin=1.5, dmax=3.5,\n type=:mddf,\n)\n\nCompute the residue contributions to the solute-solvent pair distribution function. The function returns a ResidueContributions object that can be used to plot the residue contributions, or to perform arithmetic operations with other ResidueContributions objects.\n\nArguments\n\nresults::Result: The result object obtained from the mddf function.\natoms::AbstractVector{PDBTools.Atom}: The vector of atoms of the solute, or a part of it.\n\nOptional arguments\n\ndmin::Float64: The minimum distance to consider. Default is 1.5.\ndmax::Float64: The maximum distance to consider. Default is 3.5.\ntype::Symbol: The type of the pair distribution function (:mddf, :md_count, or :coordination_number). Default is :mddf.\nsilent::Bool: If true, the progress bar is not shown. Default is false.\n\nA structure of type ResultContributions can be used to plot the residue contributions to the solute-solvent pair distribution function, using the Plots.contourf function, and to perform arithmetic operations with other ResidueContributions objects, multiplying or dividing by a scalar, and slicing (see examples below).\n\nExamples\n\nConstructing a ResidueContributions object\n\njulia> using ComplexMixtures, PDBTools\n\njulia> using ComplexMixtures.Testing: data_dir; ComplexMixtures._testing_show_method[] = true; # testing mode\n\njulia> atoms = readPDB(data_dir*\"/NAMD/Protein_in_Glycerol/system.pdb\");\n\njulia> results = load(data_dir*\"/NAMD/Protein_in_Glycerol/protein_glyc.json\");\n\njulia> rc = ResidueContributions(results, select(atoms, \"protein\"); silent=true)\n\n Residue Contributions\n 3.51 █ █ █ █ █\n 3.27 █ █ █\n 3.03 █ █ █ █ █ █ █ █\n 2.79 █ ██ █ █ █ █ █ ██ █ █ █\n d 2.55 █ █ ██ █ █ █ █ ██ ██ █ █ █ █ █ █ █\n 2.31 █ █ ██ █ ███ █ ██ ██ ██ █ ██ █ ██ █ █ █\n 2.07 █ █ █ █ █████ █ ██ ██ ██ █ ██ █ █ ██ █ █\n 1.83 █ █ █ █ █████ █ ██ █ ██ █ ██ █ ██ █ █\n 1.59\n A1 T33 T66 S98 S130 T162 A194 H226 G258 \n\n\nPlotting\n\nusing ComplexMixtures, PDBTools, Plots\n...\nresult = mddf(traj, options)\nrc = ResidueContributions(result, select(atoms, \"protein\"))\ncontourf(rc) # plots a contour map\n\nSlicing\n\nSlicing, or indexing, the residue contributions returns a new ResidueContributions object with the selected residues:\n\nusing ComplexMixtures, PDBTools, Plots\n...\nresult = mddf(traj, options)\nrc = ResidueContributions(result, select(atoms, \"protein\"))\nrc_7 = rc[7] # contributions of residue 7\nrc_range = rc[10:50] # slice the residue contributions\ncontourf(rc_range) # plots a contour map of the selected residues\n\nArithmetic operations\n\nusing ComplexMixtures, PDBTools, Plots\n...\n# first simulation (for example, low temperature):\nresult1 = mddf(traj2, options)\nrc1 = ResidueContributions(result1, select(atoms, \"protein\"))\n# second simulation (for example, high temperature):\nresult2 = mddf(traj2, options)\nrc2 = ResidueContributions(result2, select(atoms, \"protein\"))\n# difference of the residue contributions between the two simulations:\nrc_diff = rc2 - rc1\ncontourf(rc_diff) # plots a contour map of the difference\n\ncompat: Compat\nSlicing, indexing, and multiplication and divison by scalars were introduces in v2.7.0.\n\n\n\n\n\n","category":"type"},{"location":"contributions/#ComplexMixtures.contributions-Tuple{Result, Union{SoluteGroup, SolventGroup}}","page":"Atomic and group contributions","title":"ComplexMixtures.contributions","text":"contributions(R::Result, group::Union{SoluteGroup,SolventGroup}; type = :mddf)\n\nReturns the contributions of the atoms of the solute or solvent to the MDDF, coordination number, or MD count.\n\nArguments\n\nR::Result: The result of a calculation.\ngroup::Union{SoluteGroup,SolventGroup}: The group of atoms to consider.\ntype::Symbol: The type of contributions to return. Can be :mddf (default), :coordination_number, or :md_count.\n\nExamples\n\njulia> using ComplexMixtures, PDBTools\n\njulia> dir = ComplexMixtures.Testing.data_dir*\"/Gromacs\";\n\njulia> atoms = readPDB(dir*\"/system.pdb\");\n\njulia> protein = select(atoms, \"protein\");\n\njulia> emim = select(atoms, \"resname EMI\"); \n\njulia> solute = AtomSelection(protein, nmols = 1)\nAtomSelection \n 1231 atoms belonging to 1 molecule(s).\n Atoms per molecule: 1231\n Number of groups: 1231\n\njulia> solvent = AtomSelection(emim, natomspermol = 20)\nAtomSelection \n 5080 atoms belonging to 254 molecule(s).\n Atoms per molecule: 20\n Number of groups: 20\n\njulia> results = load(dir*\"/protein_EMI.json\"); # load pre-calculated results\n\njulia> ca_cb = contributions(results, SoluteGroup([\"CA\", \"CB\"])); # contribution of CA and CB atoms to the MDDF\n\njulia> ca_cb = contributions(results, SoluteGroup([\"CA\", \"CB\"]); type=:coordination_number); # contribution of CA and CB atoms to the coordination number\n\n\n\n\n\n","category":"method"},{"location":"example1/#Protein-in-water/glycerol","page":"◦ Protein in water/glycerol","title":"Protein in water/glycerol","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/#Index","page":"◦ Protein in water/glycerol","title":"Index","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"Data, packages, and execution\nMDDF, KB integrals, and group contributions\n2D density map\n3D density map","category":"page"},{"location":"example1/#data-example1","page":"◦ Protein in water/glycerol","title":"Data, packages, and execution","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"The files required to run this example are:","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"system.pdb: The PDB file of the complete system.\nglyc50_traj.dcd: Trajectory file. This is a 1GB file, necessary for running from scratch the calculations.","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"To run the scripts, we suggest the following procedure:","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"Create a directory, for example example1.\nCopy the required data files above to this directory.\nLaunch julia in that directory, activate the directory environment, and install the required packages. This is done by launching Julia and executing:\nimport Pkg \nPkg.activate(\".\")\nPkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"EasyFit\"])\nexit()\nCopy the code of each script in to a file, and execute with:\njulia -t auto script.jl\nAlternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation. For a more advanced Julia usage, we suggest the VSCode IDE with the Julia Language Support extension. ","category":"page"},{"location":"example1/#mddf-example1","page":"◦ Protein in water/glycerol","title":"MDDF, KB integrals, and group contributions","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"Here we compute the minimum-distance distribution function, the Kirkwood-Buff integral, and the atomic contributions of the solvent to the density. This example illustrates the regular usage of ComplexMixtures, to compute the minimum distance distribution function, KB-integrals and group contributions. ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    Complete example code: click here!","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example1/script1.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"

    ","category":"page"},{"location":"example1/#Output","page":"◦ Protein in water/glycerol","title":"Output","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"The code above will produce the following plots, which contain the minimum-distance distribution of glycerol relative to the protein, and the corresponding KB integral:","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"and the same distribution function, decomposed into the contributions of the hydroxyl and aliphatic groups of glycerol:","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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(bulk_range=(10.0, 15.0), stride=5)\nmddf(trajectory, options)The complete set of options available is described here.","category":"page"},{"location":"example1/#2D-map-example1","page":"◦ Protein in water/glycerol","title":"2D density map","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"In this followup from the example above, we compute group contributions of the solute (the protein) to the MDDFs, split into the contributions each protein residue. This allows the observation of the penetration of the solvent on the structure, and the strength of the interaction of the solvent, or cossolvent, with each type of residue in the structure. The ResidueContributions and Plots.contourf auxiliary functions, documented here, are used: ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    Complete example code: click here!","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example1/script2.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"

    ","category":"page"},{"location":"example1/#Output-2","page":"◦ Protein in water/glycerol","title":"Output","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"The code above will produce the following plot, which contains, for each residue, the contributions of each residue to the distribution function of glycerol, within 1.5 to 3.5 mathrmAA of the surface of the protein.","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","category":"page"},{"location":"example1/#3D-map-example1","page":"◦ Protein in water/glycerol","title":"3D density map","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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. For further information about the grid3D function, go to the 3D grid map section of the manual.","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    Complete example code: click here!","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example1/script3.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"

    ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/#How-to-run-this-example:","page":"◦ Protein in water/glycerol","title":"How to run this example:","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"Assuming that the input files are available in the script directory, just run the script with:","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"julia density3D.jl","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"This will create 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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"vmd -e grid.vmd","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","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 analysis 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, version 1.9 or greater is required. Using the juliaup tool is a highly recommended way of installing and keeping Julia up to date.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"Alternatively, you can install Julia by downloading the binaries directly from the Julia webpage.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"note: Note\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\", \"PDBTools\", \"Plots\", \"EasyFit\", \"LaTeXStrings\"])","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"Here, PDBTools.jl is an auxiliary package to read PDB files and select atoms within them. The Plots, EasyFit and LaTeXStrings packages will help producing nice looking plots. ","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> import Pkg; Pkg.add([\"ComplexMixtures\",\"PDBTools\",\"Plots\", \"EasyFit\", \"LaTeXStrings\"])","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\nusing EasyFit\nusing LaTeXStrings\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 acronym. For example:import ComplexMixtures as CM\nCM.mddf(...)","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"CollapsedDocStrings = true","category":"page"},{"location":"mddf/#Computing-the-MDDF","page":"Computing the MDDF","title":"Computing the MDDF","text":"","category":"section"},{"location":"mddf/#Minimum-Distance-Distribution-Function","page":"Computing the MDDF","title":"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":"mddf","category":"page"},{"location":"mddf/#ComplexMixtures.mddf","page":"Computing the MDDF","title":"ComplexMixtures.mddf","text":"mddf(\n trajectory::Trajectory, \n options::Options; \n frame_weights = Float64[], \n coordination_number_only = false,\n low_memory = false,\n)\n\nComputes 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\nThe options parameter is optional. If not set, the default Options() structure will be used.\n\nOptional execution keywords\n\nThe frame_weights keyword is an array of weights for each frame of the trajectory. If this is provided, the MDDF will be computed as a weighted average of the MDDFs of each frame. This can be used to study the solvation dependency in perturbed ensembles. \n\nThe coordination_number_only, is a boolean that, if set to true, will compute only the site-counts and coordination numbers of the solvent molecules around the solute, and not the MDDF, RDF, or KB integrals. This is useful when the normalization of the distribution is not possible or needed, for instance when the bulk solutio is not properly defined. The computation is much faster in this case. \n\nThe low_memory can be set to true to reduce the memory requirements of the computation. This will parallelize the computation of the minimum distances at a lower level, reducing the memory requirements at the expense of some performance. \n\ncompat: Compat\nThe low_memory option was introduced in v2.4.0.\n\nExamples\n\njulia> using ComplexMixtures, PDBTools\n\njulia> using ComplexMixtures.Testing: data_dir\n\njulia> dir = \"$data_dir/NAMD\";\n\njulia> atoms = readPDB(\"$dir/structure.pdb\");\n\njulia> solute = AtomSelection(select(atoms, \"protein\"), nmols=1);\n\njulia> solvent = AtomSelection(select(atoms, \"resname TMAO\"), natomspermol=14);\n\njulia> trajectory = Trajectory(\"$dir/trajectory.dcd\",solute,solvent);\n\njulia> options = Options(lastframe=10, bulk_range=(10.0, 15.0));\n\njulia> results = mddf(trajectory, options)\n\n\n\n\n\n","category":"function"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"The mddf functions is run with, for example:","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"results = mddf(trajectory, Options(bulk_range=(10.0, 15.0))) ","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 bulk_range and stride. ","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, bulk_range=(10.0, 15.0))\nresults = mddf(trajectory, options)","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"note: Note\nbulk_range defines the subset of the system, as defined according to a range of distances from the solute, that are to be considered as the bulk solution. Within this range of distances, the user believes that the reference solute molecule does not significantly affect anymore the structure of the solvent. By default, all molecules above 10 Angstroms from the solute are considered bulk molecules (corresponding to Options(dbulk=10.0)), but it is highly recommended to use a manual definition of bulk_range.The definition of a range of distances within the system to compute the bulk density is adequate because this system subset is then an open system with a solvent molecule reservoir. The adequate choice of bulk_range can be inspected by the proper convergence of the distribution functions (which must converge to 1.0) and a proper convergence of the KB integrals.The bulk_range option was introduced in version 2.1.0.","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":"mddf/#Coordination-numbers-only","page":"Computing the MDDF","title":"Coordination numbers only","text":"","category":"section"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"The coordination_number function, called with the same arguments as the mddf function, can be used to compute coordination numbers without the normalization required for the MDDF:","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"coordination_number(::Trajectory, ::Options)","category":"page"},{"location":"mddf/#ComplexMixtures.coordination_number-Tuple{Trajectory, Options}","page":"Computing the MDDF","title":"ComplexMixtures.coordination_number","text":"coordination_number(\n trajectory::Trajectory, options::Options;\n kargs...\n)\n\nComputes the coordination numbers for each solute molecule in the trajectory, given the Trajectory. This is an auxiliary function of the ComplexMixtures package, which is used to compute coordination numbers when the normalization of the distribution is not possible or needed. \n\nThe output is a Result structure, which contains the data as the result of a call to mddf, except that all counters which require normalization of the distribution will be zero. In summary, this result data structure can be used to compute the coordination numbers, but not the MDDF, RDF, or KB integrals.\n\nThe keyword arguments are the same as for the mddf function, and are passed to it. This function is a wrapper around mddf with the coordination_number_only keyword set to true.\n\n\n\n\n\n","category":"method"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"This function can be useful if the normalization is not possible or meaningful. The computation is much faster if the normalization is not necessary.","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"note: Note\nThe mddf, kb, and random count parameters will be empty when using this options, and are meaningless. ","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 N option, where N is the number of processes to be used. For example, to use 8 parallel processes, use:","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"julia -t 8 example.jl","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"The computation will use a number of parallel processes equal to N. Use -t auto to automatically pick the number of threads available in your computer. ","category":"page"},{"location":"parallel/#Optimal-number-of-threads","page":"Parallel execution","title":"Optimal number of threads","text":"","category":"section"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"The number of threads used for computation of the MDDF is the number of threads available to Julia. Many computers allow hyperthreading, and not necessarily this this beneficial for the execution of this package. The optimal number of threads may vary. Some newer CPUs have \"energy saving\" cores, which are also relatively slow.","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"Independently of the number of threads initialized with the -t command-line parameter, the number of processes launched by ComplexMixtures in any given computation can be adjusted by the Options(nthreads=N) option. This won't provide any speedup if the optional number of threads is greater than the number of threads available to Julia at runtime.","category":"page"},{"location":"parallel/#Memory-issues","page":"Parallel execution","title":"Memory issues","text":"","category":"section"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"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. ","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"The main reason for memory exhaustion is the annotation of the contributions of each atom of the solute molecules to the total counts. By default, in a parallel run, one copy of such data structures is saved for each thread. This might be an issue if the solute is molecular structure with many hundreds of thousand atoms, and if the number of CPUs available is very high, but memory is not as abundant.","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"There are different ways to deal with this issue:","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"Use predefined groups, to reduce the size of the group array contributions.\nUse the low_memory=true option the call to mddf (for example with mddf(traj, options; low_memory=true). \nReduce the number of threads used (with Options(nthreads=N)).\nIncrease the frequency of garbage collection calls:\noptions = 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.3. ","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 = AtomSelection(atoms,\"protein\",nmols=1)\nsolvent = AtomSelection(atoms,\"resname TMAO\",natomspermol=14)\noptions = Options(bulk_range=(8.0, 12.0))\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, options))\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":"save/","page":"Save and load","title":"Save and load","text":"Modules = [ComplexMixtures]\nPages = [\"tools/write.jl\"]","category":"page"},{"location":"save/#Base.write-Tuple{Result, String}","page":"Save and load","title":"Base.write","text":"write(\n R::Result, filename::String;\n solute_group_names::Vector{String} = R.solute.group_names,\n solvent_group_names::Vector{String} = R.solvent.group_names,\n)\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 group names are defined in R, the solute_group_names and solvent_group_names arguments are not necessary. If they are not defined, the user can pass the names of the groups as strings in the solute_group_names and solvent_group_names arguments.\n\n\n\n\n\n","category":"method"},{"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 AtomSelection 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":"trajectory/#Reference-functions","page":"Loading the trajectory","title":"Reference functions","text":"","category":"section"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"Modules = [ComplexMixtures]\nPages = [\"Trajectory.jl\"]","category":"page"},{"location":"trajectory/#ComplexMixtures.Trajectory","page":"Loading the trajectory","title":"ComplexMixtures.Trajectory","text":"Trajectory(filename::String, solute::AtomSelection, solvent::AtomSelection; 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":"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/#Basic-example","page":"Quick Guide","title":"Basic 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 with 14 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/#Input-files","page":"Quick Guide","title":"Input files","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The files necessary to run this would be:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"system.pdb: a PDB file of the complete simulated system.\ntrajectory.dcd: the simulation trajectory, here exemplified in the DCD format.\nscript.jl: the Julia script, described below.","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"These files are not provided for this example. For complete running examples, please check our examples section.","category":"page"},{"location":"quickguide/#The-Julia-script","page":"Quick Guide","title":"The Julia script","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/basic/script.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Given that this code is saved into a file named script.jl, it can be run within the Julia REPL with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"julia> include(\"script.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 script.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\nSome newer CPUs have \"fast\" and \"slow\" cores, designed for performance or energy savings. Thus using all cores, with -t auto, may not be the best strategy for optimal performance. Experimenting with different number of cores using -t N where N is the number of cores used is always necessary for tunning performance.","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 cosolvent: 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 AtomSelection function to setup the structure required by the MDDF calculation:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"solute = AtomSelection(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 = AtomSelection(tmao, natomspermol=14)","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, Options(bulk_range=(8.0, 12.0)))\n","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Some optional parameters for the computation are available in the Options section. Depending on the number of atoms and trajectory length, this can take a while. Computing a MDDF is much more expensive than computing a regular radial distribution function, because the normalization requires the generation of an ideal distribution of the molecules in the system. ","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 / Å\", ylabel=\"mddf(d)\") \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 / Å\", ylabel=\"KB(d) / L / mol\") ","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":"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 by selecting subsets of atoms from the system. These subsets are defined by the AtomSelection data structures. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"To construct a AtomSelection data structure, one needs to provide, at least, the (1-based) indices of the atoms that belong to the selection, and either the number of atoms of each molecule or the number of molecules in the selection.","category":"page"},{"location":"selection/#Using-the-PDBTools-package","page":"Set solute and solvent","title":"Using the PDBTools package","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"The PDBTools package helps the construction of the solute and solvent data structures, by providing a convenient selection syntax. Additionally, it sets up the names of the atoms of the system in the data structure, which can be used to retrieve atom and and group contributions to MDDFs and coordination numbers. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"For example, here we define a protein of a system as the solute:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"julia> using ComplexMixtures, PDBTools\n\njulia> atoms = readPDB(ComplexMixtures.Testing.pdbfile);\n\njulia> protein = select(atoms, \"protein\");\n\njulia> solute = AtomSelection(protein, nmols=1)\nAtomSelection \n 1463 atoms belonging to 1 molecule(s).\n Atoms per molecule: 1463\n Number of groups: 1463 ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"We need to inform the AtomSelection 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":"Now, we define the solvent of the system as the water molecules:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"julia> water = select(atoms, \"water\"); \n\njulia> solvent = AtomSelection(water, natomspermol=3)\nAtomSelection \n 58014 atoms belonging to 19338 molecule(s).\n Atoms per molecule: 3\n Number of groups: 3","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. The PDBTools.jl (v1.0 or greater) package provides a simple wrapper to VMD that allows using the same syntax at it supports.","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":"using ComplexMixtures, PDBTools\n\natoms = readPDB(\"system.pdb\")\n\nindices, names = select_with_vmd(\"./system.pdb\", \"protein\", vmd=\"/usr/bin/vmd\")\n\nprotein = atoms[indices]\n\nsolute = AtomSelection(protein, 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 to be executed. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"The VMDSelect function also accepts an optional keyword parameter srcload, which can be used to load custom scripts within vmd before setting the selection. This allows the definition of tcl scripts with custom selection macros, for instance. The usage would be: ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"using PDBTools\n\nindices, names = select_with_vmd(\n \"file.pdb\", \n \"resname MYRES\"; \n srcload = [ \"mymacros1.tcl\", \"mymacros2.tcl\" ]\n)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"Which corresponds to sourceing each of the macro files in VMD before defining the selection with the custom MYRES name.","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]. AtomSelections by type, name, segment, residue name, etc, won't be a problem.","category":"page"},{"location":"selection/#predefinition-of-groups","page":"Set solute and solvent","title":"Predefinition of atom groups","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"Importantly, this should be only a concern for the solvation analysis of systems in which individual molecules are very large. This feature was introduced in version 2.0 of the package to support the study of small molecule distribution in virus structures, of millions of atoms. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"By default, the contribution of each type of atom to the coordination number counts is stored, to allow the decomposition of the final MDDFs into any group contribution. However, when a structure, like a virus, has millions of atoms, storing the contribution of each atom becomes prohibitive in terms of memory. Thus, one may need to predefine the groups in which the contributions will be analyzed.","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"Here, we illustrate this feature by presselecting the acidic and basic residues of a protein:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"julia> using ComplexMixtures, PDBTools\n\njulia> atoms = readPDB(ComplexMixtures.Testing.pdbfile);\n\njulia> protein = select(atoms, \"protein\");\n\njulia> acidic_residues = select(atoms, \"protein and acidic\");\n\njulia> basic_residues = select(atoms, \"protein and basic\");\n\njulia> solute = AtomSelection(\n protein, \n nmols=1,\n group_atom_indices = [ index.(acidic_residues), index.(basic_residues) ],\n group_names = [ \"acidic residues\", \"basic residues\" ]\n )\nAtomSelection \n 1463 atoms belonging to 1 molecule(s).\n Atoms per molecule: 1463\n Number of groups: 2 ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"In this example, then, the solute AtomSelection has two groups. The indices of the atoms of the groups are stored in the group_atom_indices vector and the group names in the group_names vector. The atom_group auxiliary function is the most practical way to retrive the indices of the atoms of the group.","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"julia> atom_group(solute, \"acidic residues\")\n162-element Vector{Int64}:\n 24\n 25\n 26\n ⋮\n 1436\n 1437","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"With these group selections predefined, the contributions of these groups to the MDDF or coordination numbers can be retrived directly from the result data structure with, for example:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"julia> trajectory = Trajectory(trajectory_file, solute, solvent)\n\njulia> result = mddf(trajectory, Options(bulk_range=(8.0, 12.0)));\n\njulia> acidic_residue_contributions = contributions(result, SoluteGroup(\"acidic residues\"))","category":"page"},{"location":"selection/#Reference-functions","page":"Set solute and solvent","title":"Reference functions","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"Modules = [ComplexMixtures]\nPages = [\"AtomSelection.jl\"]","category":"page"},{"location":"selection/#ComplexMixtures.AtomSelection","page":"Set solute and solvent","title":"ComplexMixtures.AtomSelection","text":"struct AtomSelection\n\nStructure that contains the information about the solute and solvent molecules.\n\nnmols::Int64\nnatomspermol::Int64\nindices::Vector{Int64}\ncustom_groups::Bool\ngroup_atom_indices::Vector{Vector{Int64}}\ngroup_names::Vector{String}\n\n\n\n\n\n","category":"type"},{"location":"selection/#ComplexMixtures.AtomSelection-Tuple","page":"Set solute and solvent","title":"ComplexMixtures.AtomSelection","text":"AtomSelection constructors\n\nThe AtomSelection structure carries the information of the molecules that are going to be used to compute the MDDF. The structure can be initialized in different ways:\n\nInitialize the structure providing a vector of PDBTools.Atom(s).\n\n AtomSelection(\n atoms::AbstractVector{<:PDBTools.Atom}; \n nmols::Int = 0, \n natomspermol::Int = 0,\n group_atom_indices::Union{Nothing,Vector{Vector{Int}}} = nothing,\n group_names::Vector{String} = String[]\n ) \n\nThe indices of the atoms will be retrived from the indices of the atoms as defined in the PDB file, thus the PDB file must correspond to the same system as that of the simulation. \n\nEither the number of molecules (nmols) or the number of atoms per molecule (natomspermol) must be provided.\n\nIf group_atom_indices is nothing or group_names is empty, the names of the groups will be retrieved from the atom names, and in the coordination numbers of each individual atom will be stored.\n\nExample\n\njulia> using ComplexMixtures, PDBTools\n\njulia> pdbfile = ComplexMixtures.Testing.pdbfile;\n\njulia> atoms = PDBTools.readPDB(pdbfile, \"resname TMAO\");\n\njulia> atsel = AtomSelection(atoms, natomspermol=14)\nAtomSelection \n 2534 atoms belonging to 181 molecule(s).\n Atoms per molecule: 14\n Number of groups: 14 \n\njulia> atom_group_name(atsel, 1)\n\"N\"\n\njulia> atom_group_name(atsel, 5)\n\"O1\"\n\njulia> length(atom_group_names(atsel))\n14\n\nLower level: initialize the structure providing the index of atoms and groups.\n\n AtomSelection(\n indices::Vector{Int};\n nmols::Int = 0,\n natomspermol::Int = 0,\n group_atom_indices::Union{Nothing,Vector{Vector{Int}}} = nothing,\n group_names::Vector{String} = String[]\n )\n\nConstruct an AtomSelection structure from the most low-level information: the index of atoms and groups.\n\nEither the number of molecules (nmols) or the number of atoms per molecule (natomspermol) must be provided.\n\nGroups of atoms can be defined by providing a vector of vectors of atom indices (group_atom_indices), and a vector of group names (group_names). If group_atom_indices is set to nothing, the coordination numbers of each individual atoms wil be stored.\n\nExamples\n\njulia> using ComplexMixtures\n\njulia> AtomSelection([1,2,3], nmols=1)\nAtomSelection \n 3 atoms belonging to 1 molecule(s).\n Atoms per molecule: 3\n Number of groups: 3\n\njulia> AtomSelection([1,2,3], natomspermol=1)\nAtomSelection \n 3 atoms belonging to 3 molecule(s).\n Atoms per molecule: 1\n Number of groups: 1\n\njulia> AtomSelection([1,2,3], natomspermol=1, group_atom_indices=[[1,2],[3]], group_names=[\"G1\", \"G2\"])\nAtomSelection \n 3 atoms belonging to 3 molecule(s).\n Atoms per molecule: 1\n Number of groups: 2 \n\n\n\n\n\n","category":"method"},{"location":"selection/#ComplexMixtures.SoluteGroup","page":"Set solute and solvent","title":"ComplexMixtures.SoluteGroup","text":"SoluteGroup and SolventGroup data structures.\n\nThese structures are used to select groups of atoms to extract their contributions from the MDDF results. \n\nMost tipically, the groups are defined from a selection of atoms with the PDBTools package, or by providing directly the indices of teh atoms in the structure. \n\nAlternativelly, if the groups were predefined, the groups can be selected by group index or group name. \n\nThe possible constructors are:\n\nSoluteGroup(atoms::Vector{PDBTools.Atom})\nSoluteGroup(atom_indices::Vector{Int})\nSoluteGroup(atom_names::Vector{String})\nSoluteGroup(group_name::String)\nSoluteGroup(residue::PDBTools.Residue)\nSoluteGroup(atsel::AtomSelection)\n\nabove, each constructor can be replaced by SolventGroup. The resulting data structures are used as input parameters for the contributions function:\n\ncontributions(results::Result, group::Union{SoluteGroup, SolventGroup}; type=:mddf)\n\nSee the contributions help entry for additional information.\n\nExamples\n\nDefining solute groups with different input types:\n\njulia> using ComplexMixtures, PDBTools\n\njulia> atoms = PDBTools.readPDB(ComplexMixtures.Testing.pdbfile, \"protein\"); \n\njulia> SoluteGroup(select(atoms, \"protein and resname ASP\")) # vector of PDBTools.Atom(s)\nSoluteGroup defined by:\n atom_indices: [ 24, 25, ..., 1056, 1057 ] - 72 atoms\n\njulia> SoluteGroup(1:100) # atom indices (range or vector)\nSoluteGroup defined by:\n atom_indices: [ 1, 2, ..., 99, 100 ] - 100 atoms\n\njulia> SoluteGroup([\"N\", \"CA\", \"C\", \"O\"]) # vector of atom names\nSoluteGroup defined by:\n atom_names: [ N, CA, C, O ] - 4 atom names.\n \njulia> SoluteGroup(\"acidic residues\") # predefined group name\nSoluteGroup defined by:\n group_name: \"acidic residues\"\n\njulia> SoluteGroup(1) # predefined group index\nSoluteGroup defined by:\n group_index: 1\n\njulia> SoluteGroup(collect(eachresidue(atoms))[2]) # PDBTools.Residue(s)\nSoluteGroup defined by:\n atom_indices: [ 13, 14, ..., 22, 23 ] - 11 atoms\n\n\n\n\n\n\n","category":"type"},{"location":"selection/#ComplexMixtures.SolventGroup","page":"Set solute and solvent","title":"ComplexMixtures.SolventGroup","text":"SoluteGroup and SolventGroup data structures.\n\nThese structures are used to select groups of atoms to extract their contributions from the MDDF results. \n\nMost tipically, the groups are defined from a selection of atoms with the PDBTools package, or by providing directly the indices of teh atoms in the structure. \n\nAlternativelly, if the groups were predefined, the groups can be selected by group index or group name. \n\nThe possible constructors are:\n\nSoluteGroup(atoms::Vector{PDBTools.Atom})\nSoluteGroup(atom_indices::Vector{Int})\nSoluteGroup(atom_names::Vector{String})\nSoluteGroup(group_name::String)\nSoluteGroup(residue::PDBTools.Residue)\nSoluteGroup(atsel::AtomSelection)\n\nabove, each constructor can be replaced by SolventGroup. The resulting data structures are used as input parameters for the contributions function:\n\ncontributions(results::Result, group::Union{SoluteGroup, SolventGroup}; type=:mddf)\n\nSee the contributions help entry for additional information.\n\nExamples\n\nDefining solute groups with different input types:\n\njulia> using ComplexMixtures, PDBTools\n\njulia> atoms = PDBTools.readPDB(ComplexMixtures.Testing.pdbfile, \"protein\"); \n\njulia> SoluteGroup(select(atoms, \"protein and resname ASP\")) # vector of PDBTools.Atom(s)\nSoluteGroup defined by:\n atom_indices: [ 24, 25, ..., 1056, 1057 ] - 72 atoms\n\njulia> SoluteGroup(1:100) # atom indices (range or vector)\nSoluteGroup defined by:\n atom_indices: [ 1, 2, ..., 99, 100 ] - 100 atoms\n\njulia> SoluteGroup([\"N\", \"CA\", \"C\", \"O\"]) # vector of atom names\nSoluteGroup defined by:\n atom_names: [ N, CA, C, O ] - 4 atom names.\n \njulia> SoluteGroup(\"acidic residues\") # predefined group name\nSoluteGroup defined by:\n group_name: \"acidic residues\"\n\njulia> SoluteGroup(1) # predefined group index\nSoluteGroup defined by:\n group_index: 1\n\njulia> SoluteGroup(collect(eachresidue(atoms))[2]) # PDBTools.Residue(s)\nSoluteGroup defined by:\n atom_indices: [ 13, 14, ..., 22, 23 ] - 11 atoms\n\n\n\n\n\n\n","category":"type"},{"location":"selection/#ComplexMixtures.atom_group-Tuple{AtomSelection, Int64}","page":"Set solute and solvent","title":"ComplexMixtures.atom_group","text":"atom_group(atsel::AtomSelection, i::Int)\natom_group(atsel::AtomSelection, groupname::String)\n\natom_group(atsel::AtomSelection, i::Int)\natom_group(atsel::AtomSelection, groupname::String)\n\nReturn the indices of the atoms that belong to a given group.\n\nExample\n\njulia> using ComplexMixtures\n\njulia> atsel = AtomSelection([1,2,3], natomspermol=1, group_atom_indices=[[1,2],[3]], group_names=[\"G1\", \"G2\"])\nAtomSelection \n 3 atoms belonging to 3 molecule(s).\n Atoms per molecule: 1\n Number of groups: 2\n\njulia> atom_group(atsel, 1)\n2-element Vector{Int64}:\n 1\n 2\n\njulia> atom_group(atsel, \"G2\")\n1-element Vector{Int64}:\n 3\n\njulia> atom_group_name(atsel, 1)\n\"G1\"\n\n\n\n\n\n","category":"method"},{"location":"selection/#ComplexMixtures.atom_group_name-Tuple{AtomSelection, Int64}","page":"Set solute and solvent","title":"ComplexMixtures.atom_group_name","text":"atom_group_name(atsel::AtomSelection, i::Int)\natom_group_names(atsel::AtomSelection)\n\nReturn the name of the group of atoms with index i. The atom_group_names function returns a vector with the names of all the groups.\n\nExample\n\njulia> using ComplexMixtures\n\njulia> atsel = AtomSelection([1,2,3], natomspermol=1, group_atom_indices=[[1,2],[3]], group_names=[\"G1\", \"G2\"])\nAtomSelection \n 3 atoms belonging to 3 molecule(s).\n Atoms per molecule: 1\n Number of groups: 2\n\njulia> atom_group_name(atsel, 1)\n\"G1\"\n\njulia> atom_group_names(atsel)\n2-element Vector{String}:\n \"G1\"\n \"G2\"\n\n\n\n\n\n","category":"method"},{"location":"selection/#ComplexMixtures.atom_group_names-Tuple{Any}","page":"Set solute and solvent","title":"ComplexMixtures.atom_group_names","text":"atom_group_name(atsel::AtomSelection, i::Int)\natom_group_names(atsel::AtomSelection)\n\nReturn the name of the group of atoms with index i. The atom_group_names function returns a vector with the names of all the groups.\n\nExample\n\njulia> using ComplexMixtures\n\njulia> atsel = AtomSelection([1,2,3], natomspermol=1, group_atom_indices=[[1,2],[3]], group_names=[\"G1\", \"G2\"])\nAtomSelection \n 3 atoms belonging to 3 molecule(s).\n Atoms per molecule: 1\n Number of groups: 2\n\njulia> atom_group_name(atsel, 1)\n\"G1\"\n\njulia> atom_group_names(atsel)\n2-element Vector{String}:\n \"G1\"\n \"G2\"\n\n\n\n\n\n","category":"method"},{"location":"example4/#Glycerol/water-mixture","page":"◦ Water/Glycerol mixture","title":"Glycerol/water mixture","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"This example illustrates the use of ComplexMixtures.jl to study the solution structure of a crowded (1:1 molar fraction) solution of glycerol in water. Here, we compute the distribution function and atomic contributions associated to the inter-species interactions (water-glycerol) and the glycerol-glycerol auto-correlation function. This example aims to illustrate how to obtain a detailed molecular picture of the solvation structures in an homogeneous mixture.","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The system simulated consists of 1000 water molecules (red) and 1000 glycerol molecules (purple).","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"
    \n\n
    ","category":"page"},{"location":"example4/#Index","page":"◦ Water/Glycerol mixture","title":"Index","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"Data, packages, and execution\nGlycerol-Glycerol and Water-Glycerol distribution functions\nGlycerol group contributions to MDDFs\n2D map of group contributions","category":"page"},{"location":"example4/#data-example4","page":"◦ Water/Glycerol mixture","title":"Data, packages, and execution","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The files required to run this example are:","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"equilibrated.pdb: The PDB file of the complete system.\ntraj_Glyc.dcd: Trajectory file. This is a 200Mb file, necessary for running from scratch the calculations.","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"To run the scripts, we suggest the following procedure:","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"Create a directory, for example example4.\nCopy the required data files above to this directory.\nLaunch julia in that directory: activate the directory environment, and install the required packages. This launching Julia and executing:\nimport Pkg \nPkg.activate(\".\")\nPkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"EasyFit\"])\nexit()\nCopy the code of each script in to a file, and execute with:\njulia -t auto script.jl\nAlternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation.","category":"page"},{"location":"example4/#glyc_mddf-example4","page":"◦ Water/Glycerol mixture","title":"Glycerol-Glycerol and Water-Glycerol distribution functions","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The first and most simple analysis is the computation of the minimum-distance distribution functions between the components of the solution. In this example we focus on the distributions of the two components relative to the glycerol molecules. Thus, we display the glycerol auto-correlation function, and the water-glycerol correlation function in the first panel of the figure below. The second panel displays the KB integrals of the two components computed from each of these distributions.","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"
    Complete example code: click here!","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example4/script1.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"

    ","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"(Image: )","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"Both water and glycerol form hydrogen bonds with (other) glycerol molecules, as indicated by the peaks at ~1.8mathrmAA. The auto-correlation function of glycerol shows a more marked second peak corresponding to non-specific interactions, which (as we will show) are likely associated to interactions of its aliphatic groups.","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The KB integrals in the second panel show similar values water and glycerol, with the KB integral for water being slightly greater. This means that glycerol molecules are (sightly, if the result is considered reliable) preferentially hydrated from a macroscopic standpoint.","category":"page"},{"location":"example4/#glyc-groups-example4","page":"◦ Water/Glycerol mixture","title":"Glycerol group contributions to MDDFs","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"
    Complete example code: click here!","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example4/script2.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"

    ","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"(Image: )","category":"page"},{"location":"example4/#map-example4","page":"◦ Water/Glycerol mixture","title":"2D map of group contributions","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The above distributions can be split into the contributions of each glycerol chemical group. The 2D maps below display this decomposition.","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"
    Complete example code: click here!","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example4/script3.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"

    ","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"(Image: )","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The interesting result here is that the mathrmCH group of glycerol is protected from both solvents. There is a strong density augmentation at the vicinity of hydroxyl groups, and the second peak of the MDDFs is clearly associated to interactions with the mathrmCH_2 groups.","category":"page"},{"location":"example2/#Polyacrylamide-in-DMDF","page":"◦ Polyacrylamide in DMF","title":"Polyacrylamide in DMDF","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"In this example we illustrate how the solvation structure of a polymer can be studied with ComplexMixtures.jl. The system is a 5-mer segment of polyacrylamide (PAE - capped with methyl groups), solvated with dimethylformamide (DMF). The system is interesting because of the different functional groups and polarities involved in the interactions of DMF with PAE. A snapshot of the system is shown below.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    \n\n
    ","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The structures of DMF and of the polyacrylamide segment are:","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    \n\n\n\n\n\n\n\n\n
    DMFPolyacrylamide
    \n
    ","category":"page"},{"location":"example2/#Index","page":"◦ Polyacrylamide in DMF","title":"Index","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"Data, packages, and execution\nMDDF and KB integrals\nGroup contributions\n2D density map","category":"page"},{"location":"example2/#data-example2","page":"◦ Polyacrylamide in DMF","title":"Data, packages, and execution","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The files required to run this example are:","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"equilibrated.pdb: The PDB file of the complete system.\ntraj_Polyacry.dcd: Trajectory file. This is a 275Mb file, necessary for running from scratch the calculations.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"To run the scripts, we suggest the following procedure:","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"Create a directory, for example example2.\nCopy the required data files above to this directory.\nLaunch julia in that directory: activate the directory environment, and install the required packages. This launching Julia and executing:\nimport Pkg \nPkg.activate(\".\")\nPkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"EasyFit\"])\nexit()\nCopy the code of each script in to a file, and execute with:\njulia -t auto script.jl\nAlternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation.","category":"page"},{"location":"example2/#mddf-example2","page":"◦ Polyacrylamide in DMF","title":"MDDF and KB integrals","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"Here we compute the minimum-distance distribution function, the Kirkwood-Buff integral, and the atomic contributions of the solvent to the density. This example illustrates the regular usage of ComplexMixtures, to compute the minimum distance distribution function, KB-integrals and group contributions. ","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    Complete example code: click here!","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example2/script1.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"

    ","category":"page"},{"location":"example2/#Output","page":"◦ Polyacrylamide in DMF","title":"Output","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The distribution of DMF molecules around polyacrylamide is shown below. There is a peak at ~2.5Angs, indicating favorable non-specific interactions between the solvent molecules and the polymer. The peak is followed by a dip and diffuse peaks at higher distances. Thus, the DMF molecules are structured around the polymer, but essentially only in the first solvation shell. ","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"(Image: )","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The KB integral in a bicomponent mixture converges to the (negative of the) apparent molar volume of the solute. It is negative, indicating that the accumulation of DMF in the first solvation shell of the polymer is not enough to compensate the excluded volume of the solute. ","category":"page"},{"location":"example2/#groups-example2","page":"◦ Polyacrylamide in DMF","title":"Group contributions","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The MDDF can be decomposed into the contributions of the DMF chemical groups, and on the polyacrylamide chemical groups. In the first panel below we show the contributions of the DMF chemical groups to the distribution function.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    Complete example code: click here!","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example2/script2.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"

    ","category":"page"},{"location":"example2/#Output-2","page":"◦ Polyacrylamide in DMF","title":"Output","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The decomposition reveals that specific interactions peaking at distances slightly smaller than 2AA exist between the polymer and the carbonyl group of DMF. Thus, there hydrogen bonds between the polymer and this group, which dominate the interactions between the solute and the solvent at short distances. The non-specific interactions peak at 2.5Angs and are composed of contributions of all DMF chemical groups, but particularly of the methyl groups.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"(Image: )","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The decomposition of the same MDDF in the contributions of the chemical groups of the polymer is clearly associated to the DMF contributions. The specific, hydrogen-bonding, interactions, are associated to the polymer amine groups. The amine groups also contribute to the non-specific interactions at greater distances, but these are a sum of the contributions of all polymer groups, polar or aliphatic.","category":"page"},{"location":"example2/#2Dmap-example2","page":"◦ Polyacrylamide in DMF","title":"2D density map","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"We can decompose the MDDF into the contributions of each portion of the polymer chain. The map below displays the contributions of each chemical group of the polymer, now split into the mers of the polymer, to the MDDF.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    Complete example code: click here!","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example2/script3.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"

    ","category":"page"},{"location":"example2/#Output-3","page":"◦ Polyacrylamide in DMF","title":"Output","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The terminal methyl groups interact strongly with DMF, and strong local density augmentations are visible in particular on the amine groups. These occur at less than 2.0Angs and are characteristic of hydrogen-bond interactions. Interestingly, the DMF molecules are excluded from the aliphatic and carbonyl groups of the polymer, relative to the other groups.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"Finally, it is noticeable that the central mer is more weakly solvated by DMF than the mers approaching the extremes of the polymer chain. This is likely a result of the partial folding of the polymer, that protects that central mers from the solvent in a fraction of the polymer configurations.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    \n\n
    ","category":"page"},{"location":"example2/#References","page":"◦ Polyacrylamide in DMF","title":"References","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"Molecules built with JSME: B. Bienfait and P. Ertl, JSME: a free molecule editor in JavaScript, Journal of Cheminformatics 5:24 (2013) http://biomodel.uah.es/en/DIY/JSME/draw.en.htm","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The system was built with Packmol.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The simulations were perfomed with NAMD, with CHARMM36 parameters. ","category":"page"},{"location":"example3/#POPC-membrane-in-water/ethanol","page":"◦ POPC membrane in water/ethanol","title":"POPC membrane in water/ethanol","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"In this example ComplexMixtures.jl is used to study the interactions of a POPC membrane with a mixture of 20%(mol/mol) ethanol in water. At this concentration ethanol destabilizes the membrane.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    \n\n
    ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"System image: a POPC membrane (center) solvated by a mixture of water (purple) and ethanol (green). The system is composed by 59 POPC, 5000 water, and 1000 ethanol molecules. ","category":"page"},{"location":"example3/#Index","page":"◦ POPC membrane in water/ethanol","title":"Index","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Data, packages, and execution\nMDDF and KB integrals\nGroup contributions\nInteraction of POPC groups with water\nInteraction of POPC groups with ethanol\nDensity map on POPC chains","category":"page"},{"location":"example3/#data-example3","page":"◦ POPC membrane in water/ethanol","title":"Data, packages, and execution","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The files required to run this example are:","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"equilibrated.pdb: The PDB file of the complete system.\ntraj_POPC.dcd: Trajectory file. This is a 365Mb file, necessary for running from scratch the calculations.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"To run the scripts, we suggest the following procedure:","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Create a directory, for example example3.\nCopy the required data files above to this directory.\nLaunch julia in that directory: activate the directory environment, and install the required packages. This launching Julia and executing:\nimport Pkg \nPkg.activate(\".\")\nPkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"EasyFit\"])\nexit()\nCopy the code of each script in to a file, and execute with:\njulia -t auto script.jl\nAlternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation.","category":"page"},{"location":"example3/#mddf-example3","page":"◦ POPC membrane in water/ethanol","title":"MDDF and KB integrals","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Here we show the distribution functions and KB integrals associated to the solvation of the membrane by water and ethanol. ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    Complete example code: click here!","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example3/script1.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"

    ","category":"page"},{"location":"example3/#Output","page":"◦ POPC membrane in water/ethanol","title":"Output","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The distribution functions are shown in the first panel of the figure below, and the KB integrals are shown in the second panel.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Clearly, both water and ethanol accumulate on the proximity of the membrane. The distribution functions suggest that ethanol displays a greater local density augmentation, reaching concentrations roughly 4 times higher than bulk concentrations. Water has a peak at hydrogen-bonding distances (~1.8mathrmAA) and a secondary peak at 2.5mathrmAA.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Despite the fact that ethanol displays a greater relative density (relative to its own bulk concentration) at short distances, the KB integral of water turns out to be greater (more positive) than that of ethanol. This implies that the membrane is preferentially hydrated.","category":"page"},{"location":"example3/#groups1-example3","page":"◦ POPC membrane in water/ethanol","title":"Ethanol group contributions","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The minimum-distance distribution function can be decomposed into the contributions of the ethanol molecule groups. ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    Complete example code: click here!","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example3/script2.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"

    ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"In the figure below we show the contributions of the ethanol hydroxyl and aliphatic chain groups to the total MDDF.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"As expected, the MDDF at hydrogen-bonding distances is composed by contributions of the ethanol hydroxyl group, and the non-specific interactions at ~2.5mathrmAA have a greater contribution of the aliphatic chain of the solvent molecules. It is interesting to explore the chemical complexity of POPC in what concerns these interactions.","category":"page"},{"location":"example3/#groups2-example3","page":"◦ POPC membrane in water/ethanol","title":"Interaction of POPC groups with water","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The MDDF can also be decomposed into the contributions of the solute atoms and chemical groups. First, we show the contributions of the POPC chemical groups to the water-POPC distribution.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    Complete example code: click here!","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example3/script3.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"

    ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Not surprisingly, water interactions occur majoritarily with the Phosphate and Choline groups of POPC molecules, that is, with the polar head of the lipid. The interactions at hydrogen-bonding distances are dominated by the phosphate group, and non-specific interaction occur mostly with the choline group. Some water molecules penetrate the membrane and interact with the glycerol and aliphatic chains of POPC, but these contributions are clearly secondary.","category":"page"},{"location":"example3/#groups3-example3","page":"◦ POPC membrane in water/ethanol","title":"Interaction of POPC groups with ethanol","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The interactions of ethanol molecules with the membrane are more interesting, because ethanol penetrates the membrane. Here we decompose the ethanol-POPC distribution function into the contributions of the POPC chemical groups.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    Complete example code: click here!","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example3/script4.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"

    ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Ethanol molecules interact with the choline and phosphate groups of POPC molecules, as do water molecules. The contributions to the MDDF at hydrogen-bonding distances come essentially from ethanol-phosphate interactions.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"However, ethanol molecules interact frequently with the glycerol and aliphatic chains of POPC. Interactions with the Oleoyl chain are slightly stronger than with the Palmitoyl chain. This means that ethanol penetrates the hydrophobic core of the membrane, displaying non-specific interactions with the lipids and with the glycerol group. These interactions are probably associated to the destabilizing role of ethanol in the membrane structure.","category":"page"},{"location":"example3/#map-example3","page":"◦ POPC membrane in water/ethanol","title":"Density map on POPC chains","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The MDDFs can be decomposed at more granular level, in which each chemical group of the aliphatic chains of the POPC molecules are considered independently. This allows the study of the penetration of the ethanol molecules in the membrane. In the figure below, the carbonyl following the glycerol group of the POPC molecules is represented in the left, and going to the right the aliphatic chain groups are sequentially shown.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    Complete example code: click here!","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example3/script5.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"

    ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Ethanol displays an important density augmentation at the vicinity of the carbonyl that follows the glycerol group, and accumulates on the proximity of the aliphatic chain. The density of ethanol decreases as one advances into the aliphatic chain, displaying a minimum around the insaturation in the Oleoyl chain. The terminal methyl group of both chains display a greater solvation by ethanol, suggesting the twisting of the aliphatic chain expose these terminal groups to membrane depth where ethanol is already abundant.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The equivalent maps for water are strikingly different, and show that water is excluded from the interior of the membrane:","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/#References","page":"◦ POPC membrane in water/ethanol","title":"References","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Membrane built with the VMD membrane plugin. ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Water and ethanol layers added with Packmol.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The simulations were performed with NAMD, with CHARMM36 parameters. ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Density of the ethanol-water mixture from: https://wissen.science-and-fun.de/chemistry/chemistry/density-tables/ethanol-water-mixtures/","category":"page"},{"location":"tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"Coordination numbers\n2D density map per residue\n3D density map around a macromolecule\nOverview of the solvent and solute properties\nComputing radial distribution functions","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"CollapsedDocStrings = true","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::Union{SoluteGroup, SolventGroup})","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/","page":"Tools","title":"Tools","text":"note: Note\nThere are some systems for which the normalization of the distributions is not necessary or possible. It is still possible to compute the coordination numbers, by running, instead of mddf, the coordination_number function:coordination_number(trajectory::Trajectory, options::Options)This call will return Result data structure but with all fields requiring normalization with zeros. In summary, this result data structure can be used to compute the coordination numbers, but not the MDDF, RDF, or KB integrals.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"compat: Compat\nThe independent computation of coordination numbers was introduced in version 1.1.","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 = AtomSelection(PDBTools.select(pdb, \"protein\"), nmols=1)\nresidue50 = PDBTools.select(pdb, \"residue 50\")\n# Compute the group contribution to the MDDF\nresidue50_contribution = contributions(R, SoluteGroup(residue50))\n# Now compute the coordination number\nresidue50_coordination = coordination_number(R, SoluteGroup(residue50))\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/","page":"Tools","title":"Tools","text":"Modules = [ComplexMixtures]\nPages = [\"coordination_number.jl\"]","category":"page"},{"location":"tools/#ComplexMixtures.coordination_number","page":"Tools","title":"ComplexMixtures.coordination_number","text":"coordination_number(R::Result) = R.coordination_number\ncoordination_number(R::Result, s::Union{SoluteGroup,SolventGroup})\n\nComputes the coordination number of a given group of atoms of the solute or solvent\n\natomic 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.AtomSelection)\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 indices, 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 = AtomSelection(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 = AtomSelection(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":"function"},{"location":"tools/#2D_per_residue","page":"Tools","title":"2D density map per residue","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, coordination numbers or minimum-distance counts. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"compat: Compat\nAll features described in this section are only available in v2.7.0 or greater.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The computation of the contributions of each residue can be performed with the convenience function ResidueContributions, which creates an object containing the contributions of the residues to the mddf (or coordination numbers, or minimum-distance counts), the residue names, and distances:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"ResidueContributions","category":"page"},{"location":"tools/#ComplexMixtures.ResidueContributions-tools","page":"Tools","title":"ComplexMixtures.ResidueContributions","text":"ResidueContributions (data structure)\n\nConstructor function:\n\nResidueContributions(\n results::Result, atoms::AbstractVector{PDBTools.Atom};\n dmin=1.5, dmax=3.5,\n type=:mddf,\n)\n\nCompute the residue contributions to the solute-solvent pair distribution function. The function returns a ResidueContributions object that can be used to plot the residue contributions, or to perform arithmetic operations with other ResidueContributions objects.\n\nArguments\n\nresults::Result: The result object obtained from the mddf function.\natoms::AbstractVector{PDBTools.Atom}: The vector of atoms of the solute, or a part of it.\n\nOptional arguments\n\ndmin::Float64: The minimum distance to consider. Default is 1.5.\ndmax::Float64: The maximum distance to consider. Default is 3.5.\ntype::Symbol: The type of the pair distribution function (:mddf, :md_count, or :coordination_number). Default is :mddf.\nsilent::Bool: If true, the progress bar is not shown. Default is false.\n\nA structure of type ResultContributions can be used to plot the residue contributions to the solute-solvent pair distribution function, using the Plots.contourf function, and to perform arithmetic operations with other ResidueContributions objects, multiplying or dividing by a scalar, and slicing (see examples below).\n\nExamples\n\nConstructing a ResidueContributions object\n\njulia> using ComplexMixtures, PDBTools\n\njulia> using ComplexMixtures.Testing: data_dir; ComplexMixtures._testing_show_method[] = true; # testing mode\n\njulia> atoms = readPDB(data_dir*\"/NAMD/Protein_in_Glycerol/system.pdb\");\n\njulia> results = load(data_dir*\"/NAMD/Protein_in_Glycerol/protein_glyc.json\");\n\njulia> rc = ResidueContributions(results, select(atoms, \"protein\"); silent=true)\n\n Residue Contributions\n 3.51 █ █ █ █ █\n 3.27 █ █ █\n 3.03 █ █ █ █ █ █ █ █\n 2.79 █ ██ █ █ █ █ █ ██ █ █ █\n d 2.55 █ █ ██ █ █ █ █ ██ ██ █ █ █ █ █ █ █\n 2.31 █ █ ██ █ ███ █ ██ ██ ██ █ ██ █ ██ █ █ █\n 2.07 █ █ █ █ █████ █ ██ ██ ██ █ ██ █ █ ██ █ █\n 1.83 █ █ █ █ █████ █ ██ █ ██ █ ██ █ ██ █ █\n 1.59\n A1 T33 T66 S98 S130 T162 A194 H226 G258 \n\n\nPlotting\n\nusing ComplexMixtures, PDBTools, Plots\n...\nresult = mddf(traj, options)\nrc = ResidueContributions(result, select(atoms, \"protein\"))\ncontourf(rc) # plots a contour map\n\nSlicing\n\nSlicing, or indexing, the residue contributions returns a new ResidueContributions object with the selected residues:\n\nusing ComplexMixtures, PDBTools, Plots\n...\nresult = mddf(traj, options)\nrc = ResidueContributions(result, select(atoms, \"protein\"))\nrc_7 = rc[7] # contributions of residue 7\nrc_range = rc[10:50] # slice the residue contributions\ncontourf(rc_range) # plots a contour map of the selected residues\n\nArithmetic operations\n\nusing ComplexMixtures, PDBTools, Plots\n...\n# first simulation (for example, low temperature):\nresult1 = mddf(traj2, options)\nrc1 = ResidueContributions(result1, select(atoms, \"protein\"))\n# second simulation (for example, high temperature):\nresult2 = mddf(traj2, options)\nrc2 = ResidueContributions(result2, select(atoms, \"protein\"))\n# difference of the residue contributions between the two simulations:\nrc_diff = rc2 - rc1\ncontourf(rc_diff) # plots a contour map of the difference\n\ncompat: Compat\nSlicing, indexing, and multiplication and divison by scalars were introduces in v2.7.0.\n\n\n\n\n\n","category":"type"},{"location":"tools/","page":"Tools","title":"Tools","text":"The output of ResidueContributions is by default shown as a simple unicode plot:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"
    \n\n
    ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The ResidueContribution object can be used to produce a high-quality contour plot using the Plots.contourf function:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Plots.contourf(::ResidueContributions)","category":"page"},{"location":"tools/#Plots.contourf-Tuple{ResidueContributions}","page":"Tools","title":"Plots.contourf","text":"contourf(\n rc::ResidueContributions; \n step::Int=1,\n oneletter=false,\n xlabel=\"Residue\",\n ylabel=\"r / Å\",\n)\n\nPlot the contribution of each residue to the solute-solvent pair distribution function as a contour plot. This function requires loading the Plots package.\n\nArguments\n\nrc::ResidueContributions: The residue contributions to the solute-solvent pair distribution function, as computed by the ResidueContributions function.\n\nOptional arguments\n\nstep: The step of the residue ticks in the x-axis of the plot. Default is 1.\noneletter::Bool: Use one-letter residue codes. Default is false. One-letter codes are only available for the 20 standard amino acids.\nxlabel and ylabel: Labels for the x and y axes. Default is \"Residue\" and \"r / Å\".\n\nThis function will set color limits and choose the scale automatically. These parameters can be set with the clims and color arguments of Plots.contourf. Other plot customizations can be done by passing other keyword arguments to this function, which will be passed to Plots.contourf.\n\nExample\n\njulia> using ComplexMixtures, Plots, PDBTools\n\njulia> results = load(\"mddf.json\")\n\njulia> atoms = readPDB(\"system.pdb\", \"protein\")\n\njulia> rc = ResidueContributions(results, atoms; oneletter=true)\n\njulia> plt = contourf(rc; step=5)\n\nThis will produce a plot with the contribution of each residue to the solute-solvent pair distribution function, as a contour plot, with the residues in the x-axis and the distance in the y-axis.\n\nTo customize the plot, use the Plot.contourf keyword parameters, for example:\n\njulia> plt = contourf(rc; step=5, size=(800,400), title=\"Title\", clims=(-0.1, 0.1))\n\ncompat: Compat\nThis function requires loading the Plots package and is available in ComplexMixtures v2.5.0 or greater.Support for all Plots.contourf parameters was introduced in ComplexMixtures v2.6.0.\n\n\n\n\n\n","category":"method"},{"location":"tools/","page":"Tools","title":"Tools","text":"A complete example of its usage can be seen here. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The ResidueContributions object can be indexes and sliced, for the analysis of the contributions of specific residues or range of residues:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"rc = ResidueContributions(results1, select(atoms, \"protein\")); \nrc_7 = rc[7] # contributions of residue 7\nrc_range = rc[20:50] # contributions of a range of residues","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Slicing will return a new ResidueContributions object.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Additionally, these ResidueContributions objects can be subtracted, divided, summed, or multiplied, to compare contributions of residues among different simulations. Typically, if one wants to compare the solvation of residues in two different simulations, one can do:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"# first simulation (for example, low temperature)\nrc1 = ResidueContributions(results1, select(atoms, \"protein\")); \n\n# second simulation (for example, high temperature)\nrc2 = ResidueContributions(results2, select(atoms, \"protein\"));\n\n# difference in residue contributions to solvation\nrc_diff = rc2 - rc1\n\n# Plot difference\nusing Plots\ncontourf(rc_diff; title=\"Density difference\", step=2, colorbar=:left)","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Which will produce a plot similar to the one below (the data of this plot is just illustrative):","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"which will return a new ResidueContributions object.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"
    \n\n
    ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Finally, it is also possible to renormalize the contributions by multiplication or division by scalars,","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"rc2 = rc / 15\nrc2 = 2 * rc","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"tip: Tip\nThis function is a convenience function only.Basically, we are extracting the contribution of each residue independently and building a matrix where each row represents a distance and each column a residue. Using PDBTools, this can be done with, for example: residues = collect(eachresidue(protein))\nresidue_contributions = zeros(length(R.d),length(residues))\nfor (i,residue) in pairs(residues)\n c = contributions(results, SoluteGroup(residue)) \n residue_contributions[:,i] .= c\nendThe 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. ","category":"page"},{"location":"tools/#grid3D","page":"Tools","title":"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":"A 3D density map is constructed with the grid3D function:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Modules = [ComplexMixtures]\nPages = [\"tools/grid3D.jl\"]","category":"page"},{"location":"tools/#ComplexMixtures.grid3D","page":"Tools","title":"ComplexMixtures.grid3D","text":"grid3D(\n result::Result, atoms, output_file::Union{Nothing,String} = nothing; \n dmin=1.5, ddax=5.0, step=0.5, silent = false,\n)\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\nresult is a ComplexMixtures.Result object atoms is a vector of PDBTools.Atoms with all the atoms of the system. output_file is the name of the file where the grid will be written. If nothing, the grid is only returned as a matrix. \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\nsilent is a boolean to suppress the progress bar.\n\nThe output PDB has the following characteristics:\n\nThe positions of the atoms are grid points. \nThe identity of the atoms correspond to the identity of the protein atom contributing to the MDDF at that point (the closest protein atom). \nThe temperature-factor column (beta) contains the relative contribution of that atom to the MDDF at the corresponding distance. \nThe occupancy field contains the distance itself.\n\nExample\n\njulia> using ComplexMixtures, PDBTools\n\njulia> atoms = readPDB(\"./system.pdb\");\n\njulia> R = ComplexMixtures.load(\"./results.json\");\n\njulia> grid = grid3D(R, atoms, \"grid.pdb\");\n\nExamples of how the grid can be visualized are provided in the user guide of ComplexMixtures. \n\n\n\n\n\n","category":"function"},{"location":"tools/","page":"Tools","title":"Tools","text":"The call to grid3D 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 where: ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The positions of the atoms are grid points. \nThe identity of the atoms correspond to the identity of the protein atom contributing to the MDDF at that point (the closest protein atom). \nThe temperature-factor column (beta) contains the relative contribution of that atom to the MDDF at the corresponding distance. \nThe occupancy field contains the distance itself.","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/#radial_distribution","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/","page":"Tools","title":"Tools","text":"Modules = [ComplexMixtures]\nPages = [\"gr.jl\"]","category":"page"},{"location":"tools/#ComplexMixtures.gr-Tuple{Result}","page":"Tools","title":"ComplexMixtures.gr","text":"gr(R::Result) = gr(R.d,R.rdf_count,R.density.solvent_bulk,R.files[1].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":"tools/#ComplexMixtures.gr-Tuple{Vector{Float64}, Vector{Float64}, Float64, Float64}","page":"Tools","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":"tools/#overview","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":"...\n\njulia> results = mddf(trajectory, Options(bulk_range=(8.0, 12.0)))\n\njulia> results\n--------------------------------------------------------------------------------\nMDDF Overview - ComplexMixtures - Version 2.0.8\n--------------------------------------------------------------------------------\n\nSolvent properties:\n-------------------\n\nSimulation concentration: 0.49837225882780106 mol L⁻¹\nMolar volume: 2006.532230249041 cm³ mol⁻¹\n\nConcentration in bulk: 0.5182380507741433 mol L⁻¹\nMolar volume in bulk: 1929.6151614228274 cm³ mol⁻¹\n\nSolute properties:\n------------------\n\nSimulation Concentration: 0.002753437894076249 mol L⁻¹\nEstimated solute partial molar volume: 13921.98945754469 cm³ mol⁻¹\n\nBulk range: 8.0 - 12.0 Å\nMolar volume of the solute domain: 34753.1382279134 cm³ mol⁻¹\n\nAuto-correlation: false\n\nTrajectory files and weights:\n\n /home/user/NAMD/trajectory.dcd - w = 1.0\n\nLong range MDDF mean (expected 1.0): 1.0378896753018338 ± 1.0920172247127446\nLong range RDF mean (expected 1.0): 1.2147429551790854 ± 1.2081838161780682\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":"tools/#Legacy","page":"Tools","title":"Legacy","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"The legacy function contourf_per_residue provides a direct way to produce contour plots:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"contourf_per_residue(::Result, ::AbstractVector{PDBTools.Atom})","category":"page"},{"location":"tools/#ComplexMixtures.contourf_per_residue-Tuple{Result, AbstractVector{Atom}}","page":"Tools","title":"ComplexMixtures.contourf_per_residue","text":"contourf_per_residue(\n results::Result, atoms::AbstractVector{PDBTools.Atom}; \n residue_range=nothing, \n dmin=1.5, dmax=3.5, \n oneletter=false,\n xlabel=\"Residue\",\n ylabel=\"r / Å\",\n type=:mddf,\n clims=nothing,\n colorscale=:tempo,\n)\n\nPlot the contribution of each residue to the solute-solvent pair distribution function as a contour plot. This function requires loading the Plots package.\n\nArguments\n\nresults::Result: The result of a mddf call.\natoms::AbstractVector{Atom}: The atoms of the solute.\n\nOptional arguments\n\nresidue_range: The range of residues to plot. Default is all residues. Use a step to plot every n residues, e.g., 1:2:30.\ndmin::Real: The minimum distance to plot. Default is 1.5.\ndmax::Real: The maximum distance to plot. Default is 3.5.\noneletter::Bool: Use one-letter residue codes. Default is false. One-letter codes are only available for the 20 standard amino acids.\nxlabel and ylabel: Labels for the x and y axes. Default is \"Residue\" and \"r / Å\".\ntype::Symbol: That data to plot. Default is :mddf for MDDF contributions. Options are :coordination_number, and :mddf_count.\nclims: The color limits for the contour plot.\ncolorscale: The color scale for the contour plot. Default is :tempo. We suggest :bwr if the zero is at the middle of the color scale (use clims to adjust the color limits).\n\nExample\n\njulia> using ComplexMixtures, Plots, PDBTools\n\njulia> results = load(\"mddf.json\")\n\njulia> atoms = readPDB(\"system.pdb\", \"protein\")\n\njulia> plt = contourf_per_residue(results, atoms; oneletter=true)\n\nThis will produce a plot with the contribution of each residue to the solute-solvent pair distribution function, as a contour plot, with the residues in the x-axis and the distance in the y-axis.\n\nThe resulting plot can customized using the standard mutating plot! function, for example, \n\njulia> plot!(plt, size=(800, 400), title=\"Contribution per residue\")\n\ncompat: Compat\nThis function requires loading the Plots package and is available in ComplexMixtures v2.2.0 or greater.The type and clims arguments, and the support for a step in xticks_range were introduced in ComplexMixtures v2.3.0.\n\n\n\n\n\n","category":"method"},{"location":"updating_scripts/#updating-scripts","page":"Updating scripts","title":"Updating scripts from v1 to v2","text":"","category":"section"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"The syntax chances necessary to update script from version 1.X to 2.X of the package are:","category":"page"},{"location":"updating_scripts/#Atom-selections","page":"Updating scripts","title":"Atom selections","text":"","category":"section"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"The previous Selection structure was renamed to AtomSelection for clarity.","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Before:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"water = Selection(water; natomspermol=3)","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Now:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"water = AtomSelection(water; natomspermol=3)","category":"page"},{"location":"updating_scripts/#Group-contributions-syntax","page":"Updating scripts","title":"Group contributions syntax","text":"","category":"section"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"The syntax to computing group contributions is improved. Previously, the contrib or contributions functions required three somewhat redundant parameters. ","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Before:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"The call to contributions required 3 parameters: the Selection structure, the matrix of contributions, and the indexes of the atoms for which the contributions were desired:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"h_contributions = contributions(solvent, R.solvent_atom, h_indexes)","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Now:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"The contributions are extracted from the Result data structure, by providing either a SoluteGroup or SolventGroup object, which are setup with the group names, group indexes, atom names, or atom indexes:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"h_contributions = contributions(R, SolventGroup(h_indexes))","category":"page"},{"location":"updating_scripts/#Frame-weights","page":"Updating scripts","title":"Frame weights","text":"","category":"section"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"frame_weights is now an option of the mddf execution. That is previously, they were defined in the Options data structure, and now they are passed to the mddf function.","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Before:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"options = Options(frame_weights=[1.0, 2.0], bulk_range=(8.0, 12.0))\nresults = mddf(trajectory, options)","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Now:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"results = mddf(trajectory, options; frame_weights=[1.0, 2.0])","category":"page"},{"location":"examples/#examples","page":"Examples:","title":"Examples","text":"","category":"section"},{"location":"examples/#List-of-examples","page":"Examples:","title":"List of examples","text":"","category":"section"},{"location":"examples/","page":"Examples:","title":"Examples:","text":"Protein in water/glycerol\nPolyacrylamide in DMDF\nPOPC membrane in water/ethanol\nGlycerol/water mixture","category":"page"},{"location":"examples/#How-to-run-these-examples","page":"Examples:","title":"How to run these examples","text":"","category":"section"},{"location":"examples/","page":"Examples:","title":"Examples:","text":"1 Download and install Julia","category":"page"},{"location":"examples/","page":"Examples:","title":"Examples:","text":"To run the scripts, we suggest the following procedure:","category":"page"},{"location":"examples/","page":"Examples:","title":"Examples:","text":"Create a directory, for example example1.\nCopy the required data files, indicated in each example.\nLaunch julia in that directory, activate the directory environment, and install the required packages. This is done by launching Julia and executing:\nimport Pkg \nPkg.activate(\".\")\nPkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"EasyFit\"])\nexit()\nCopy the code of each script in to a file, and execute with:\njulia -t auto script.jl\nAlternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation. For a more advanced Julia usage, we suggest the VSCode IDE with the Julia Language Support extension. ","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, bulk_range=(8.0, 12.0))\nresults = mddf(trajectory, options)","category":"page"},{"location":"options/#Frame-ranges-and-histogram-properties","page":"Options","title":"Frame ranges and histogram properties","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"These are common options that the regular user might want to set in their calculation.","category":"page"},{"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":"bulk_range: This parameter defines the range of distances from the solute that will be considered as the bulk region of the solution. The density of the bulk solution is estimated by counting the number of molecules of the solvent in this region, and by performing a numerical integration of its volume. Set this range to a region of the solution where the MDDF is converged to 1 for practical purposes. Tuning this parameter is crucial for a proper convergence of the MDDFs and KB integrals. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"compat: Compat\nThe bulk_range option was introduced in version 2.1.0.","category":"page"},{"location":"options/#Lower-level-options","page":"Options","title":"Lower level options","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"These will probably never be set by the user, unless if dealing with some special system (large very large, or very low density system).","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. By default, all molecules at distances greater than 10.0 Angstroms are considered bulk molecules. However, the definition of bulk_range is highly encouraged. ","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. The definition of bulk_range instead is highly encouraged. ","category":"page"},{"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":"options/#Frame-statistical-reweighing","page":"Options","title":"Frame statistical reweighing","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"compat: Compat\nFrame reweighing is available in ComplexMixtures 2.0.0 or greater.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"Most times the weights of each frame of the trajectory are the same, resulting from some standard MD simulation. If, for some reason, the frames have different statistical weights, the weights can be passed to the as an optional parameter frame_weights.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"For example:","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"julia> results = mddf(trajectory, options; frame_weights=[0.0, 1.0, 2.0])","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"The code above will assign a larger weight to the third frame of the trajectory. These weights are relative (meaning that [0.0, 1.0, 2.0] would produce the same result). What will happen under the hood is that the distance counts of the frames will be multiplied by each frame weight, and normalized for the sum of the weights.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"Important: The length of the frame_weights vector must be at least equal to the number of the last frame read from the trajectory. That is, if lastframe is not set, and all the frames will be read, the length of frame_weights must be equal to the length of the trajectory (the stride parameter will skip the information both of the frames and its weights). If lastframe is set, then the length of frame_weights must be at least lastframe (it can be greater, and further values will be ignored). Importantly, the indices of the elements in frame_weights are assumed to correspond to the indices of the frames in the original trajectory file.","category":"page"},{"location":"options/#Compute-coordination-number-only","page":"Options","title":"Compute coordination number only","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"For some systems, it may be impossible, or to expensive, to compute the normalization of the minimum-distance distribution function. Nevertheless, the coordination number may still be an interesting information to be retrieved from the simulations. To run the computation to compute coordination numbers only, do:","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"julia> results = mddf(trajectory, options; coordination_number_only = true)","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"note: Note\nWith coordination_number_only set to true, the arrays associated to MDDFs and KB integrals will be empty in the output data structure. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"Modules = [ComplexMixtures]\nPages = [\"Options.jl\"]","category":"page"},{"location":"options/#ComplexMixtures.Options-Tuple{}","page":"Options","title":"ComplexMixtures.Options","text":"Options(;\n firstframe::Int = 1,\n lastframe::Int = -1,\n stride::Int = 1,\n irefatom::Int = -1,\n n_random_samples::Int = 10,\n binstep::Float64 = 0.02,\n dbulk::Union{Nothing,Real} = nothing,\n cutoff::Union{Nothing,Real} = nothing,\n usecutoff::Union{Nothing,Bool} = nothing,\n bulk_range=nothing,\n lcell::Int = 1,\n GC::Bool = true,\n GC_threshold::Float64 = 0.3,\n seed::Int = 321,\n StableRNG::Bool = false,\n nthreads::Int = 0,\n silent::Bool = false\n)\n\nCreate an Options object with the specified options. \n\n\n\n\n\n","category":"method"},{"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 choosing 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 glycerol (green) and water, at a concentration of 50%vv.","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/#Example","page":"From Python","title":"Example","text":"","category":"section"},{"location":"python/#Index","page":"From Python","title":"Index","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"Data, packages, and execution\nMinimum-Distance Distribution function\nMDDF and KB integrals\nAtomic contributions to the MDDF","category":"page"},{"location":"python/#data-pythonexample","page":"From Python","title":"Data, packages, and execution","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"The files required to run this example are:","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"system.pdb: The PDB file of the complete system.\nglyc50_sample.dcd: A 30Mb sample trajectory file. The full trajectory can also be used, but it is a 1GB file.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"To start, create a directory and copy the ComplexMixtures.py file to it. Navigate into this directory, and, to start, set the number of threads that Julia will use, to run the calculations in parallel. Typically, in bash, this means defining teh following environment variable:","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"export JULIA_NUM_THREADS=8","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"where 8 is the number of CPU cores available in your computer. For further information about Julia multi-threading, and on setting this environment variable in other systems, please read this section of the Julia manual.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"Finally, each script can be executed with, for example:","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"python3 script.py","category":"page"},{"location":"python/#script1-python","page":"From Python","title":"Minimum-Distance Distribution function","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"
    Complete example code: click here!","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`python\n$(read(\"./assets/scripts/python/script1.py\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"

    ","category":"page"},{"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":"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(bulk_range=(8.0, 12.0))\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/#python-plotting1","page":"From Python","title":"MDDF and KB integrals","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"The following python script will produce the typical MDDF and KB integral plot, for the sample system. The noise in the figures is because the trajectory sample is small.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"
    Complete example code: click here!","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`python\n$(read(\"./assets/scripts/python/script2.py\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"

    ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"(Image: )","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"In the top plot, we see that glycerol and water display clear solvation shells around the protein, with glycerol having a greater peak. This accumulation leads to a greater (less negative) KB integral for glycerol than water, as shown in the second plot. This indicates that the protein is preferentially solvated by glycerol in this system (assuming that sampling is adequate in this small trajectory).","category":"page"},{"location":"python/#python-plotting2","page":"From Python","title":"Atomic contributions to the MDDF","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"The following script produces a plot of the group contributions of Glycerol to the total MDDF function. The Glycerol MDDF is split into the contributions of the hydroxyl and aliphatic groups.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"
    Complete example code: click here!","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`python\n$(read(\"./assets/scripts/python/script3.py\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"

    ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"(Image: )","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"Despite the low sampling, it is clear that hydroxyl groups contribute to the greter peak of the distribution, at hydrogen-bonding distances, as expected. The contributions of the aliphatic groups to the MDDF occurs at longer distances, associated to non-specific interactions. ","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":"","page":"Introduction","title":"Introduction","text":"compat: Compat\nImportant: This manual refers to version 2 of ComplexMixtures.jl. There are syntax changes relative to the 1.X series, and analysis scripts written for the previous versions won't work. The list of changes necessary to updated the scripts is described here.","category":"page"},{"location":"#Help!","page":"Introduction","title":"Help!","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Please ask for help if having any difficulty using the package. Reach us by:","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Asking a question on the Julia Discourse forum. Please mark @lmiq on your post, otherwise we may miss it! This may be very effective to get help from many Julia users on questions not directly related to physical-chemistry.\nOpening an issue if you think you found a problem in the package. Even documentation problems can be reported.\nJoining us at Zulip-chat in the m3g stream of the Julia Zulip forum.\nSending an e-mail to: lmartine@unicamp.br.","category":"page"},{"location":"#Features","page":"Introduction","title":"Features","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Check out our examples, 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":"#1.-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":"#2.-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 cosolvents, 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":"Please cite the following articles if the package was useful to you:","category":"page"},{"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. 347, 117945, 2022. [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":"V. Piccoli, L. Martínez, Competitive Effects of Anions on Protein Solvation by Aqueous Ionic Liquids. J. Phys. Chem. B 2024. [Full Text]\nA. F. Pereira, L. Martínez, Helical Content Correlations and Hydration Structures of the Folding Ensemble of the B Domain of Protein A. J. Chem. Inf. Model. 64, 3350-3359, 2024. [Full Text]\nA. 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. 347, 117945, 2022. [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":"V. Piccoli, L. Martínez, Competitive Effects of Anions on Protein Solvation by Aqueous Ionic Liquids. J. Phys. Chem. B 2024. [Full Text]\nA. F. Pereira, L. Martínez, Helical Content Correlations and Hydration Structures of the Folding Ensemble of the B Domain of Protein A. J. Chem. Inf. Model. 64, 3350-3359, 2024. [Full Text]\nA. 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, neighbor 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, Options(bulk_range=(8.0, 12.0)))","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. Note that all coordinates that are supported by default (and are thus read by the Chemfiles library) will be in Å, independently on the software used to generate the trajectories, as described here [http://chemfiles.org/chemfiles/latest/overview.html#units]. ","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 AtomSelection Contains the number of atoms, number of atoms per molecule and number of molecules of the solute.\nsolvent Properties of the solvent. AtomSelection 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":"results/#Reference-functions","page":"Results","title":"Reference functions","text":"","category":"section"},{"location":"results/","page":"Results","title":"Results","text":"Modules = [ComplexMixtures]\nPages = [\"results.jl\"]","category":"page"},{"location":"results/#ComplexMixtures.Density","page":"Results","title":"ComplexMixtures.Density","text":"mutable struct Density\n\nStructure to contain the density values obtained from the calculation.\n\nsolute::Float64\nsolvent::Float64\nsolvent_bulk::Float64\n\n\n\n\n\n","category":"type"},{"location":"results/#ComplexMixtures.Result","page":"Results","title":"ComplexMixtures.Result","text":"mutable struct Result\n\nStructure to contain the results of the MDDF calculation.\n\nVersion::VersionNumber\nnbins::Int64\ndbulk::Float64\ncutoff::Float64\nd::Vector{Float64}\nmd_count::Vector{Float64}\nmd_count_random::Vector{Float64}\ncoordination_number::Vector{Float64}\ncoordination_number_random::Vector{Float64}\nmddf::Vector{Float64}\nkb::Vector{Float64}\nautocorrelation::Bool\nsolute::AtomSelection\nsolvent::AtomSelection\nsolute_group_count::Vector{Vector{Float64}}\nsolvent_group_count::Vector{Vector{Float64}}\nrdf_count::Vector{Float64}\nrdf_count_random::Vector{Float64}\nsum_rdf_count::Vector{Float64}\nsum_rdf_count_random::Vector{Float64}\nrdf::Vector{Float64}\nkb_rdf::Vector{Float64}\ndensity::ComplexMixtures.Density\nvolume::ComplexMixtures.Volume\nfiles::Vector{ComplexMixtures.TrajectoryFileOptions}\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":"results/#Base.merge-Tuple{Vector{<:Result}}","page":"Results","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":"results/#ComplexMixtures.load-Tuple{String}","page":"Results","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":"results/#ComplexMixtures.overview-Tuple{Result}","page":"Results","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":"results/#ComplexMixtures.save-Tuple{Result, String}","page":"Results","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":"contributions/#contributions","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"section"},{"location":"contributions/","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":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"To obtain the atomic contributions of an atom or group of atoms to the MDDF, the coordination number, or the site count at each distance, 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":"contributions/","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 = AtomSelection(protein,nmols=1)\nsolvent = AtomSelection(water,natomspermol=3)","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The MDDF calculation is executed with:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"trajectory = Trajectory(\"trajectory.dcd\",solute,solvent)\nresults = mddf(trajectory, Options(bulk_range=(8.0, 12.0)))","category":"page"},{"location":"contributions/#Atomic-contributions-in-the-result-data-structure","page":"Atomic and group contributions","title":"Atomic contributions in the result data structure","text":"","category":"section"},{"location":"contributions/","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 contributions can be retrieved using the contributions function, with the SoluteGroup and SolventGroup selectors.","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"For example, if the MDDF of water (solvent) relative to a solute was computed, and water has atom names OH2, H1, H2, one can retrieve the contributions of the oxygen atom with:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"OH2 = contributions(results, SolventGroup([\"OH2\"]))","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"or with, if OH2 is the first atom in the molecule,","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"OH2 = contributions(results, SolventGroup([1]))","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The contributions of the hydrogen atoms can be obtained, similarly, with:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"H = contributions(results, SolventGroup([\"H1\", \"H2\"]))","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"or with, if OH2 is the first atom in the molecule,","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"H = contributions(results, SolventGroup([2, 3]))","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Each of these calls will return a vector of the constributions of these atoms to the total MDDF. ","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"For example, here we plot the total MDDF and the Oxygen contributions: ","category":"page"},{"location":"contributions/","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, contributions(results, SolventGroup([\"OH2\"])), label=[\"OH2\"], linewidth=2)\nplot!(xlabel=\"Distance / Å\", ylabel=\"MDDF\")","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"page"},{"location":"contributions/#Contributions-to-coordination-numbers-or-site-counts","page":"Atomic and group contributions","title":"Contributions to coordination numbers or site counts","text":"","category":"section"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The keyword type defines the return type of the contribution:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"type=:mddf : the contribution of the group to the MDDF is returned (default).\ntype=:coordination_number : the contribution of the group to the coordination number, that is, the cumulative sum of counts at each distance, is returned.\ntype=:md_count : the contribution of the group to the site count at each distance is returned. ","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Example of the usage of the type option:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"ca_contributions = contributions(results, SoluteGroup([\"CA\"]); type=:coordination_number)","category":"page"},{"location":"contributions/#Using-PDBTools","page":"Atomic and group contributions","title":"Using PDBTools","text":"","category":"section"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"If the solute is a protein, or other complex molecule, selections defined with PDBTools can be used. For example, this will retrieve the contribution of the acidic residues of a protein to total MDDF:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"using PDBTools\natoms = readPDB(\"system.pdb\")\nacidic_residues = select(atoms, \"acidic\")\nacidic_contributions = contributions(results, SoluteGroup(acidic_residues))","category":"page"},{"location":"contributions/","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":"contributions/","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":"contributions/","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":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"charged_residues = PDBTools.select(atoms,\"charged\")\ncharged_contributions = contributions(results, SoluteGroup(charged_residues))\n\nneutral_residues = PDBTools.select(atoms,\"neutral\")\nneutral_contributions = contributions(atoms, SoluteGroup(neutral_residues))","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"The charged_contributions and neutral_contributions outputs are vectors containing the contributions of these residues to the total MDDF. The corresponding plot is: ","category":"page"},{"location":"contributions/","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":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Resulting in:","category":"page"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"","category":"page"},{"location":"contributions/","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":"contributions/#Reference-functions","page":"Atomic and group contributions","title":"Reference functions","text":"","category":"section"},{"location":"contributions/","page":"Atomic and group contributions","title":"Atomic and group contributions","text":"Modules = [ComplexMixtures]\nPages = [\"contributions.jl\"]","category":"page"},{"location":"contributions/#ComplexMixtures.ResidueContributions","page":"Atomic and group contributions","title":"ComplexMixtures.ResidueContributions","text":"ResidueContributions (data structure)\n\nConstructor function:\n\nResidueContributions(\n results::Result, atoms::AbstractVector{PDBTools.Atom};\n dmin=1.5, dmax=3.5,\n type=:mddf,\n)\n\nCompute the residue contributions to the solute-solvent pair distribution function. The function returns a ResidueContributions object that can be used to plot the residue contributions, or to perform arithmetic operations with other ResidueContributions objects.\n\nArguments\n\nresults::Result: The result object obtained from the mddf function.\natoms::AbstractVector{PDBTools.Atom}: The vector of atoms of the solute, or a part of it.\n\nOptional arguments\n\ndmin::Float64: The minimum distance to consider. Default is 1.5.\ndmax::Float64: The maximum distance to consider. Default is 3.5.\ntype::Symbol: The type of the pair distribution function (:mddf, :md_count, or :coordination_number). Default is :mddf.\nsilent::Bool: If true, the progress bar is not shown. Default is false.\n\nA structure of type ResultContributions can be used to plot the residue contributions to the solute-solvent pair distribution function, using the Plots.contourf function, and to perform arithmetic operations with other ResidueContributions objects, multiplying or dividing by a scalar, and slicing (see examples below).\n\nExamples\n\nConstructing a ResidueContributions object\n\njulia> using ComplexMixtures, PDBTools\n\njulia> using ComplexMixtures.Testing: data_dir; ComplexMixtures._testing_show_method[] = true; # testing mode\n\njulia> atoms = readPDB(data_dir*\"/NAMD/Protein_in_Glycerol/system.pdb\");\n\njulia> results = load(data_dir*\"/NAMD/Protein_in_Glycerol/protein_glyc.json\");\n\njulia> rc = ResidueContributions(results, select(atoms, \"protein\"); silent=true)\n\n Residue Contributions\n 3.51 █ █ █ █ █\n 3.27 █ █ █\n 3.03 █ █ █ █ █ █ █ █\n 2.79 █ ██ █ █ █ █ █ ██ █ █ █\n d 2.55 █ █ ██ █ █ █ █ ██ ██ █ █ █ █ █ █ █\n 2.31 █ █ ██ █ ███ █ ██ ██ ██ █ ██ █ ██ █ █ █\n 2.07 █ █ █ █ █████ █ ██ ██ ██ █ ██ █ █ ██ █ █\n 1.83 █ █ █ █ █████ █ ██ █ ██ █ ██ █ ██ █ █\n 1.59\n A1 T33 T66 S98 S130 T162 A194 H226 G258 \n\n\nPlotting\n\nusing ComplexMixtures, PDBTools, Plots\n...\nresult = mddf(traj, options)\nrc = ResidueContributions(result, select(atoms, \"protein\"))\ncontourf(rc) # plots a contour map\n\nSlicing\n\nSlicing, or indexing, the residue contributions returns a new ResidueContributions object with the selected residues:\n\nusing ComplexMixtures, PDBTools, Plots\n...\nresult = mddf(traj, options)\nrc = ResidueContributions(result, select(atoms, \"protein\"))\nrc_7 = rc[7] # contributions of residue 7\nrc_range = rc[10:50] # slice the residue contributions\ncontourf(rc_range) # plots a contour map of the selected residues\n\nArithmetic operations\n\nusing ComplexMixtures, PDBTools, Plots\n...\n# first simulation (for example, low temperature):\nresult1 = mddf(traj2, options)\nrc1 = ResidueContributions(result1, select(atoms, \"protein\"))\n# second simulation (for example, high temperature):\nresult2 = mddf(traj2, options)\nrc2 = ResidueContributions(result2, select(atoms, \"protein\"))\n# difference of the residue contributions between the two simulations:\nrc_diff = rc2 - rc1\ncontourf(rc_diff) # plots a contour map of the difference\n\ncompat: Compat\nSlicing, indexing, and multiplication and divison by scalars were introduces in v2.7.0.\n\n\n\n\n\n","category":"type"},{"location":"contributions/#ComplexMixtures.contributions-Tuple{Result, Union{SoluteGroup, SolventGroup}}","page":"Atomic and group contributions","title":"ComplexMixtures.contributions","text":"contributions(R::Result, group::Union{SoluteGroup,SolventGroup}; type = :mddf)\n\nReturns the contributions of the atoms of the solute or solvent to the MDDF, coordination number, or MD count.\n\nArguments\n\nR::Result: The result of a calculation.\ngroup::Union{SoluteGroup,SolventGroup}: The group of atoms to consider.\ntype::Symbol: The type of contributions to return. Can be :mddf (default), :coordination_number, or :md_count.\n\nExamples\n\njulia> using ComplexMixtures, PDBTools\n\njulia> dir = ComplexMixtures.Testing.data_dir*\"/Gromacs\";\n\njulia> atoms = readPDB(dir*\"/system.pdb\");\n\njulia> protein = select(atoms, \"protein\");\n\njulia> emim = select(atoms, \"resname EMI\"); \n\njulia> solute = AtomSelection(protein, nmols = 1)\nAtomSelection \n 1231 atoms belonging to 1 molecule(s).\n Atoms per molecule: 1231\n Number of groups: 1231\n\njulia> solvent = AtomSelection(emim, natomspermol = 20)\nAtomSelection \n 5080 atoms belonging to 254 molecule(s).\n Atoms per molecule: 20\n Number of groups: 20\n\njulia> results = load(dir*\"/protein_EMI.json\"); # load pre-calculated results\n\njulia> ca_cb = contributions(results, SoluteGroup([\"CA\", \"CB\"])); # contribution of CA and CB atoms to the MDDF\n\njulia> ca_cb = contributions(results, SoluteGroup([\"CA\", \"CB\"]); type=:coordination_number); # contribution of CA and CB atoms to the coordination number\n\n\n\n\n\n","category":"method"},{"location":"example1/#Protein-in-water/glycerol","page":"◦ Protein in water/glycerol","title":"Protein in water/glycerol","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/#Index","page":"◦ Protein in water/glycerol","title":"Index","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"Data, packages, and execution\nMDDF, KB integrals, and group contributions\n2D density map\n3D density map","category":"page"},{"location":"example1/#data-example1","page":"◦ Protein in water/glycerol","title":"Data, packages, and execution","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"The files required to run this example are:","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"system.pdb: The PDB file of the complete system.\nglyc50_traj.dcd: Trajectory file. This is a 1GB file, necessary for running from scratch the calculations.","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"To run the scripts, we suggest the following procedure:","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"Create a directory, for example example1.\nCopy the required data files above to this directory.\nLaunch julia in that directory, activate the directory environment, and install the required packages. This is done by launching Julia and executing:\nimport Pkg \nPkg.activate(\".\")\nPkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"EasyFit\"])\nexit()\nCopy the code of each script in to a file, and execute with:\njulia -t auto script.jl\nAlternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation. For a more advanced Julia usage, we suggest the VSCode IDE with the Julia Language Support extension. ","category":"page"},{"location":"example1/#mddf-example1","page":"◦ Protein in water/glycerol","title":"MDDF, KB integrals, and group contributions","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"Here we compute the minimum-distance distribution function, the Kirkwood-Buff integral, and the atomic contributions of the solvent to the density. This example illustrates the regular usage of ComplexMixtures, to compute the minimum distance distribution function, KB-integrals and group contributions. ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    Complete example code: click here!","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example1/script1.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"

    ","category":"page"},{"location":"example1/#Output","page":"◦ Protein in water/glycerol","title":"Output","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"The code above will produce the following plots, which contain the minimum-distance distribution of glycerol relative to the protein, and the corresponding KB integral:","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"and the same distribution function, decomposed into the contributions of the hydroxyl and aliphatic groups of glycerol:","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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(bulk_range=(10.0, 15.0), stride=5)\nmddf(trajectory, options)The complete set of options available is described here.","category":"page"},{"location":"example1/#2D-map-example1","page":"◦ Protein in water/glycerol","title":"2D density map","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"In this followup from the example above, we compute group contributions of the solute (the protein) to the MDDFs, split into the contributions each protein residue. This allows the observation of the penetration of the solvent on the structure, and the strength of the interaction of the solvent, or cossolvent, with each type of residue in the structure. The ResidueContributions and Plots.contourf auxiliary functions, documented here, are used: ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    Complete example code: click here!","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example1/script2.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"

    ","category":"page"},{"location":"example1/#Output-2","page":"◦ Protein in water/glycerol","title":"Output","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"The code above will produce the following plot, which contains, for each residue, the contributions of each residue to the distribution function of glycerol, within 1.5 to 3.5 mathrmAA of the surface of the protein.","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","category":"page"},{"location":"example1/#3D-map-example1","page":"◦ Protein in water/glycerol","title":"3D density map","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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. For further information about the grid3D function, go to the 3D grid map section of the manual.","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    Complete example code: click here!","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example1/script3.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"

    ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/#How-to-run-this-example:","page":"◦ Protein in water/glycerol","title":"How to run this example:","text":"","category":"section"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"Assuming that the input files are available in the script directory, just run the script with:","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"julia density3D.jl","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"This will create 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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"vmd -e grid.vmd","category":"page"},{"location":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","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":"example1/","page":"◦ Protein in water/glycerol","title":"◦ Protein in water/glycerol","text":"
    \n\n
    ","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 analysis 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, version 1.9 or greater is required. Using the juliaup tool is a highly recommended way of installing and keeping Julia up to date.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"Alternatively, you can install Julia by downloading the binaries directly from the Julia webpage.","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"note: Note\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\", \"PDBTools\", \"Plots\", \"EasyFit\", \"LaTeXStrings\"])","category":"page"},{"location":"installation/","page":"Installation","title":"Installation","text":"Here, PDBTools.jl is an auxiliary package to read PDB files and select atoms within them. The Plots, EasyFit and LaTeXStrings packages will help producing nice looking plots. ","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> import Pkg; Pkg.add([\"ComplexMixtures\",\"PDBTools\",\"Plots\", \"EasyFit\", \"LaTeXStrings\"])","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\nusing EasyFit\nusing LaTeXStrings\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 acronym. For example:import ComplexMixtures as CM\nCM.mddf(...)","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"CollapsedDocStrings = true","category":"page"},{"location":"mddf/#Computing-the-MDDF","page":"Computing the MDDF","title":"Computing the MDDF","text":"","category":"section"},{"location":"mddf/#Minimum-Distance-Distribution-Function","page":"Computing the MDDF","title":"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":"mddf","category":"page"},{"location":"mddf/#ComplexMixtures.mddf","page":"Computing the MDDF","title":"ComplexMixtures.mddf","text":"mddf(\n trajectory::Trajectory, \n options::Options; \n frame_weights = Float64[], \n coordination_number_only = false,\n low_memory = false,\n)\n\nComputes 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\nThe options parameter is optional. If not set, the default Options() structure will be used.\n\nOptional execution keywords\n\nThe frame_weights keyword is an array of weights for each frame of the trajectory. If this is provided, the MDDF will be computed as a weighted average of the MDDFs of each frame. This can be used to study the solvation dependency in perturbed ensembles. \n\nThe coordination_number_only, is a boolean that, if set to true, will compute only the site-counts and coordination numbers of the solvent molecules around the solute, and not the MDDF, RDF, or KB integrals. This is useful when the normalization of the distribution is not possible or needed, for instance when the bulk solutio is not properly defined. The computation is much faster in this case. \n\nThe low_memory can be set to true to reduce the memory requirements of the computation. This will parallelize the computation of the minimum distances at a lower level, reducing the memory requirements at the expense of some performance. \n\ncompat: Compat\nThe low_memory option was introduced in v2.4.0.\n\nExamples\n\njulia> using ComplexMixtures, PDBTools\n\njulia> using ComplexMixtures.Testing: data_dir\n\njulia> dir = \"$data_dir/NAMD\";\n\njulia> atoms = readPDB(\"$dir/structure.pdb\");\n\njulia> solute = AtomSelection(select(atoms, \"protein\"), nmols=1);\n\njulia> solvent = AtomSelection(select(atoms, \"resname TMAO\"), natomspermol=14);\n\njulia> trajectory = Trajectory(\"$dir/trajectory.dcd\",solute,solvent);\n\njulia> options = Options(lastframe=10, bulk_range=(10.0, 15.0));\n\njulia> results = mddf(trajectory, options)\n\n\n\n\n\n","category":"function"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"The mddf functions is run with, for example:","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"results = mddf(trajectory, Options(bulk_range=(10.0, 15.0))) ","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 bulk_range and stride. ","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, bulk_range=(10.0, 15.0))\nresults = mddf(trajectory, options)","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"note: Note\nbulk_range defines the subset of the system, as defined according to a range of distances from the solute, that are to be considered as the bulk solution. Within this range of distances, the user believes that the reference solute molecule does not significantly affect anymore the structure of the solvent. By default, all molecules above 10 Angstroms from the solute are considered bulk molecules (corresponding to Options(dbulk=10.0)), but it is highly recommended to use a manual definition of bulk_range.The definition of a range of distances within the system to compute the bulk density is adequate because this system subset is then an open system with a solvent molecule reservoir. The adequate choice of bulk_range can be inspected by the proper convergence of the distribution functions (which must converge to 1.0) and a proper convergence of the KB integrals.The bulk_range option was introduced in version 2.1.0.","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":"mddf/#Coordination-numbers-only","page":"Computing the MDDF","title":"Coordination numbers only","text":"","category":"section"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"The coordination_number function, called with the same arguments as the mddf function, can be used to compute coordination numbers without the normalization required for the MDDF:","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"coordination_number(::Trajectory, ::Options)","category":"page"},{"location":"mddf/#ComplexMixtures.coordination_number-Tuple{Trajectory, Options}","page":"Computing the MDDF","title":"ComplexMixtures.coordination_number","text":"coordination_number(\n trajectory::Trajectory, options::Options;\n kargs...\n)\n\nComputes the coordination numbers for each solute molecule in the trajectory, given the Trajectory. This is an auxiliary function of the ComplexMixtures package, which is used to compute coordination numbers when the normalization of the distribution is not possible or needed. \n\nThe output is a Result structure, which contains the data as the result of a call to mddf, except that all counters which require normalization of the distribution will be zero. In summary, this result data structure can be used to compute the coordination numbers, but not the MDDF, RDF, or KB integrals.\n\nThe keyword arguments are the same as for the mddf function, and are passed to it. This function is a wrapper around mddf with the coordination_number_only keyword set to true.\n\n\n\n\n\n","category":"method"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"This function can be useful if the normalization is not possible or meaningful. The computation is much faster if the normalization is not necessary.","category":"page"},{"location":"mddf/","page":"Computing the MDDF","title":"Computing the MDDF","text":"note: Note\nThe mddf, kb, and random count parameters will be empty when using this options, and are meaningless. ","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 N option, where N is the number of processes to be used. For example, to use 8 parallel processes, use:","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"julia -t 8 example.jl","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"The computation will use a number of parallel processes equal to N. Use -t auto to automatically pick the number of threads available in your computer. ","category":"page"},{"location":"parallel/#Optimal-number-of-threads","page":"Parallel execution","title":"Optimal number of threads","text":"","category":"section"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"The number of threads used for computation of the MDDF is the number of threads available to Julia. Many computers allow hyperthreading, and not necessarily this this beneficial for the execution of this package. The optimal number of threads may vary. Some newer CPUs have \"energy saving\" cores, which are also relatively slow.","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"Independently of the number of threads initialized with the -t command-line parameter, the number of processes launched by ComplexMixtures in any given computation can be adjusted by the Options(nthreads=N) option. This won't provide any speedup if the optional number of threads is greater than the number of threads available to Julia at runtime.","category":"page"},{"location":"parallel/#Memory-issues","page":"Parallel execution","title":"Memory issues","text":"","category":"section"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"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. ","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"The main reason for memory exhaustion is the annotation of the contributions of each atom of the solute molecules to the total counts. By default, in a parallel run, one copy of such data structures is saved for each thread. This might be an issue if the solute is molecular structure with many hundreds of thousand atoms, and if the number of CPUs available is very high, but memory is not as abundant.","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"There are different ways to deal with this issue:","category":"page"},{"location":"parallel/","page":"Parallel execution","title":"Parallel execution","text":"Use predefined groups, to reduce the size of the group array contributions.\nUse the low_memory=true option the call to mddf (for example with mddf(traj, options; low_memory=true). \nReduce the number of threads used (with Options(nthreads=N)).\nIncrease the frequency of garbage collection calls:\noptions = 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.3. ","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 = AtomSelection(atoms,\"protein\",nmols=1)\nsolvent = AtomSelection(atoms,\"resname TMAO\",natomspermol=14)\noptions = Options(bulk_range=(8.0, 12.0))\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, options))\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":"save/","page":"Save and load","title":"Save and load","text":"Modules = [ComplexMixtures]\nPages = [\"tools/write.jl\"]","category":"page"},{"location":"save/#Base.write-Tuple{Result, String}","page":"Save and load","title":"Base.write","text":"write(\n R::Result, filename::String;\n solute_group_names::Vector{String} = R.solute.group_names,\n solvent_group_names::Vector{String} = R.solvent.group_names,\n)\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 group names are defined in R, the solute_group_names and solvent_group_names arguments are not necessary. If they are not defined, the user can pass the names of the groups as strings in the solute_group_names and solvent_group_names arguments.\n\n\n\n\n\n","category":"method"},{"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 AtomSelection 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":"trajectory/#Reference-functions","page":"Loading the trajectory","title":"Reference functions","text":"","category":"section"},{"location":"trajectory/","page":"Loading the trajectory","title":"Loading the trajectory","text":"Modules = [ComplexMixtures]\nPages = [\"Trajectory.jl\"]","category":"page"},{"location":"trajectory/#ComplexMixtures.Trajectory","page":"Loading the trajectory","title":"ComplexMixtures.Trajectory","text":"Trajectory(filename::String, solute::AtomSelection, solvent::AtomSelection; 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":"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/#Basic-example","page":"Quick Guide","title":"Basic 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 with 14 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/#Input-files","page":"Quick Guide","title":"Input files","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"The files necessary to run this would be:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"system.pdb: a PDB file of the complete simulated system.\ntrajectory.dcd: the simulation trajectory, here exemplified in the DCD format.\nscript.jl: the Julia script, described below.","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"These files are not provided for this example. For complete running examples, please check our examples section.","category":"page"},{"location":"quickguide/#The-Julia-script","page":"Quick Guide","title":"The Julia script","text":"","category":"section"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/basic/script.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Given that this code is saved into a file named script.jl, it can be run within the Julia REPL with:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"julia> include(\"script.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 script.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\nSome newer CPUs have \"fast\" and \"slow\" cores, designed for performance or energy savings. Thus using all cores, with -t auto, may not be the best strategy for optimal performance. Experimenting with different number of cores using -t N where N is the number of cores used is always necessary for tunning performance.","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 cosolvent: 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 AtomSelection function to setup the structure required by the MDDF calculation:","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"solute = AtomSelection(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 = AtomSelection(tmao, natomspermol=14)","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, Options(bulk_range=(8.0, 12.0)))\n","category":"page"},{"location":"quickguide/","page":"Quick Guide","title":"Quick Guide","text":"Some optional parameters for the computation are available in the Options section. Depending on the number of atoms and trajectory length, this can take a while. Computing a MDDF is much more expensive than computing a regular radial distribution function, because the normalization requires the generation of an ideal distribution of the molecules in the system. ","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 / Å\", ylabel=\"mddf(d)\") \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 / Å\", ylabel=\"KB(d) / L / mol\") ","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":"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 by selecting subsets of atoms from the system. These subsets are defined by the AtomSelection data structures. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"To construct a AtomSelection data structure, one needs to provide, at least, the (1-based) indices of the atoms that belong to the selection, and either the number of atoms of each molecule or the number of molecules in the selection.","category":"page"},{"location":"selection/#Using-the-PDBTools-package","page":"Set solute and solvent","title":"Using the PDBTools package","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"The PDBTools package helps the construction of the solute and solvent data structures, by providing a convenient selection syntax. Additionally, it sets up the names of the atoms of the system in the data structure, which can be used to retrieve atom and and group contributions to MDDFs and coordination numbers. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"For example, here we define a protein of a system as the solute:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"julia> using ComplexMixtures, PDBTools\n\njulia> atoms = readPDB(ComplexMixtures.Testing.pdbfile);\n\njulia> protein = select(atoms, \"protein\");\n\njulia> solute = AtomSelection(protein, nmols=1)\nAtomSelection \n 1463 atoms belonging to 1 molecule(s).\n Atoms per molecule: 1463\n Number of groups: 1463 ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"We need to inform the AtomSelection 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":"Now, we define the solvent of the system as the water molecules:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"julia> water = select(atoms, \"water\"); \n\njulia> solvent = AtomSelection(water, natomspermol=3)\nAtomSelection \n 58014 atoms belonging to 19338 molecule(s).\n Atoms per molecule: 3\n Number of groups: 3","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. The PDBTools.jl (v1.0 or greater) package provides a simple wrapper to VMD that allows using the same syntax at it supports.","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":"using ComplexMixtures, PDBTools\n\natoms = readPDB(\"system.pdb\")\n\nindices, names = select_with_vmd(\"./system.pdb\", \"protein\", vmd=\"/usr/bin/vmd\")\n\nprotein = atoms[indices]\n\nsolute = AtomSelection(protein, 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 to be executed. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"The VMDSelect function also accepts an optional keyword parameter srcload, which can be used to load custom scripts within vmd before setting the selection. This allows the definition of tcl scripts with custom selection macros, for instance. The usage would be: ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"using PDBTools\n\nindices, names = select_with_vmd(\n \"file.pdb\", \n \"resname MYRES\"; \n srcload = [ \"mymacros1.tcl\", \"mymacros2.tcl\" ]\n)","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"Which corresponds to sourceing each of the macro files in VMD before defining the selection with the custom MYRES name.","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]. AtomSelections by type, name, segment, residue name, etc, won't be a problem.","category":"page"},{"location":"selection/#predefinition-of-groups","page":"Set solute and solvent","title":"Predefinition of atom groups","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"Importantly, this should be only a concern for the solvation analysis of systems in which individual molecules are very large. This feature was introduced in version 2.0 of the package to support the study of small molecule distribution in virus structures, of millions of atoms. ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"By default, the contribution of each type of atom to the coordination number counts is stored, to allow the decomposition of the final MDDFs into any group contribution. However, when a structure, like a virus, has millions of atoms, storing the contribution of each atom becomes prohibitive in terms of memory. Thus, one may need to predefine the groups in which the contributions will be analyzed.","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"Here, we illustrate this feature by presselecting the acidic and basic residues of a protein:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"julia> using ComplexMixtures, PDBTools\n\njulia> atoms = readPDB(ComplexMixtures.Testing.pdbfile);\n\njulia> protein = select(atoms, \"protein\");\n\njulia> acidic_residues = select(atoms, \"protein and acidic\");\n\njulia> basic_residues = select(atoms, \"protein and basic\");\n\njulia> solute = AtomSelection(\n protein, \n nmols=1,\n group_atom_indices = [ index.(acidic_residues), index.(basic_residues) ],\n group_names = [ \"acidic residues\", \"basic residues\" ]\n )\nAtomSelection \n 1463 atoms belonging to 1 molecule(s).\n Atoms per molecule: 1463\n Number of groups: 2 ","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"In this example, then, the solute AtomSelection has two groups. The indices of the atoms of the groups are stored in the group_atom_indices vector and the group names in the group_names vector. The atom_group auxiliary function is the most practical way to retrive the indices of the atoms of the group.","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"julia> atom_group(solute, \"acidic residues\")\n162-element Vector{Int64}:\n 24\n 25\n 26\n ⋮\n 1436\n 1437","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"With these group selections predefined, the contributions of these groups to the MDDF or coordination numbers can be retrived directly from the result data structure with, for example:","category":"page"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"julia> trajectory = Trajectory(trajectory_file, solute, solvent)\n\njulia> result = mddf(trajectory, Options(bulk_range=(8.0, 12.0)));\n\njulia> acidic_residue_contributions = contributions(result, SoluteGroup(\"acidic residues\"))","category":"page"},{"location":"selection/#Reference-functions","page":"Set solute and solvent","title":"Reference functions","text":"","category":"section"},{"location":"selection/","page":"Set solute and solvent","title":"Set solute and solvent","text":"Modules = [ComplexMixtures]\nPages = [\"AtomSelection.jl\"]","category":"page"},{"location":"selection/#ComplexMixtures.AtomSelection","page":"Set solute and solvent","title":"ComplexMixtures.AtomSelection","text":"struct AtomSelection\n\nStructure that contains the information about the solute and solvent molecules.\n\nnmols::Int64\nnatomspermol::Int64\nindices::Vector{Int64}\ncustom_groups::Bool\ngroup_atom_indices::Vector{Vector{Int64}}\ngroup_names::Vector{String}\n\n\n\n\n\n","category":"type"},{"location":"selection/#ComplexMixtures.AtomSelection-Tuple","page":"Set solute and solvent","title":"ComplexMixtures.AtomSelection","text":"AtomSelection constructors\n\nThe AtomSelection structure carries the information of the molecules that are going to be used to compute the MDDF. The structure can be initialized in different ways:\n\nInitialize the structure providing a vector of PDBTools.Atom(s).\n\n AtomSelection(\n atoms::AbstractVector{<:PDBTools.Atom}; \n nmols::Int = 0, \n natomspermol::Int = 0,\n group_atom_indices::Union{Nothing,Vector{Vector{Int}}} = nothing,\n group_names::Vector{String} = String[]\n ) \n\nThe indices of the atoms will be retrived from the indices of the atoms as defined in the PDB file, thus the PDB file must correspond to the same system as that of the simulation. \n\nEither the number of molecules (nmols) or the number of atoms per molecule (natomspermol) must be provided.\n\nIf group_atom_indices is nothing or group_names is empty, the names of the groups will be retrieved from the atom names, and in the coordination numbers of each individual atom will be stored.\n\nExample\n\njulia> using ComplexMixtures, PDBTools\n\njulia> pdbfile = ComplexMixtures.Testing.pdbfile;\n\njulia> atoms = PDBTools.readPDB(pdbfile, \"resname TMAO\");\n\njulia> atsel = AtomSelection(atoms, natomspermol=14)\nAtomSelection \n 2534 atoms belonging to 181 molecule(s).\n Atoms per molecule: 14\n Number of groups: 14 \n\njulia> atom_group_name(atsel, 1)\n\"N\"\n\njulia> atom_group_name(atsel, 5)\n\"O1\"\n\njulia> length(atom_group_names(atsel))\n14\n\nLower level: initialize the structure providing the index of atoms and groups.\n\n AtomSelection(\n indices::Vector{Int};\n nmols::Int = 0,\n natomspermol::Int = 0,\n group_atom_indices::Union{Nothing,Vector{Vector{Int}}} = nothing,\n group_names::Vector{String} = String[]\n )\n\nConstruct an AtomSelection structure from the most low-level information: the index of atoms and groups.\n\nEither the number of molecules (nmols) or the number of atoms per molecule (natomspermol) must be provided.\n\nGroups of atoms can be defined by providing a vector of vectors of atom indices (group_atom_indices), and a vector of group names (group_names). If group_atom_indices is set to nothing, the coordination numbers of each individual atoms wil be stored.\n\nExamples\n\njulia> using ComplexMixtures\n\njulia> AtomSelection([1,2,3], nmols=1)\nAtomSelection \n 3 atoms belonging to 1 molecule(s).\n Atoms per molecule: 3\n Number of groups: 3\n\njulia> AtomSelection([1,2,3], natomspermol=1)\nAtomSelection \n 3 atoms belonging to 3 molecule(s).\n Atoms per molecule: 1\n Number of groups: 1\n\njulia> AtomSelection([1,2,3], natomspermol=1, group_atom_indices=[[1,2],[3]], group_names=[\"G1\", \"G2\"])\nAtomSelection \n 3 atoms belonging to 3 molecule(s).\n Atoms per molecule: 1\n Number of groups: 2 \n\n\n\n\n\n","category":"method"},{"location":"selection/#ComplexMixtures.SoluteGroup","page":"Set solute and solvent","title":"ComplexMixtures.SoluteGroup","text":"SoluteGroup and SolventGroup data structures.\n\nThese structures are used to select groups of atoms to extract their contributions from the MDDF results. \n\nMost tipically, the groups are defined from a selection of atoms with the PDBTools package, or by providing directly the indices of teh atoms in the structure. \n\nAlternativelly, if the groups were predefined, the groups can be selected by group index or group name. \n\nThe possible constructors are:\n\nSoluteGroup(atoms::Vector{PDBTools.Atom})\nSoluteGroup(atom_indices::Vector{Int})\nSoluteGroup(atom_names::Vector{String})\nSoluteGroup(group_name::String)\nSoluteGroup(residue::PDBTools.Residue)\nSoluteGroup(atsel::AtomSelection)\n\nabove, each constructor can be replaced by SolventGroup. The resulting data structures are used as input parameters for the contributions function:\n\ncontributions(results::Result, group::Union{SoluteGroup, SolventGroup}; type=:mddf)\n\nSee the contributions help entry for additional information.\n\nExamples\n\nDefining solute groups with different input types:\n\njulia> using ComplexMixtures, PDBTools\n\njulia> atoms = PDBTools.readPDB(ComplexMixtures.Testing.pdbfile, \"protein\"); \n\njulia> SoluteGroup(select(atoms, \"protein and resname ASP\")) # vector of PDBTools.Atom(s)\nSoluteGroup defined by:\n atom_indices: [ 24, 25, ..., 1056, 1057 ] - 72 atoms\n\njulia> SoluteGroup(1:100) # atom indices (range or vector)\nSoluteGroup defined by:\n atom_indices: [ 1, 2, ..., 99, 100 ] - 100 atoms\n\njulia> SoluteGroup([\"N\", \"CA\", \"C\", \"O\"]) # vector of atom names\nSoluteGroup defined by:\n atom_names: [ N, CA, C, O ] - 4 atom names.\n \njulia> SoluteGroup(\"acidic residues\") # predefined group name\nSoluteGroup defined by:\n group_name: \"acidic residues\"\n\njulia> SoluteGroup(1) # predefined group index\nSoluteGroup defined by:\n group_index: 1\n\njulia> SoluteGroup(collect(eachresidue(atoms))[2]) # PDBTools.Residue(s)\nSoluteGroup defined by:\n atom_indices: [ 13, 14, ..., 22, 23 ] - 11 atoms\n\n\n\n\n\n\n","category":"type"},{"location":"selection/#ComplexMixtures.SolventGroup","page":"Set solute and solvent","title":"ComplexMixtures.SolventGroup","text":"SoluteGroup and SolventGroup data structures.\n\nThese structures are used to select groups of atoms to extract their contributions from the MDDF results. \n\nMost tipically, the groups are defined from a selection of atoms with the PDBTools package, or by providing directly the indices of teh atoms in the structure. \n\nAlternativelly, if the groups were predefined, the groups can be selected by group index or group name. \n\nThe possible constructors are:\n\nSoluteGroup(atoms::Vector{PDBTools.Atom})\nSoluteGroup(atom_indices::Vector{Int})\nSoluteGroup(atom_names::Vector{String})\nSoluteGroup(group_name::String)\nSoluteGroup(residue::PDBTools.Residue)\nSoluteGroup(atsel::AtomSelection)\n\nabove, each constructor can be replaced by SolventGroup. The resulting data structures are used as input parameters for the contributions function:\n\ncontributions(results::Result, group::Union{SoluteGroup, SolventGroup}; type=:mddf)\n\nSee the contributions help entry for additional information.\n\nExamples\n\nDefining solute groups with different input types:\n\njulia> using ComplexMixtures, PDBTools\n\njulia> atoms = PDBTools.readPDB(ComplexMixtures.Testing.pdbfile, \"protein\"); \n\njulia> SoluteGroup(select(atoms, \"protein and resname ASP\")) # vector of PDBTools.Atom(s)\nSoluteGroup defined by:\n atom_indices: [ 24, 25, ..., 1056, 1057 ] - 72 atoms\n\njulia> SoluteGroup(1:100) # atom indices (range or vector)\nSoluteGroup defined by:\n atom_indices: [ 1, 2, ..., 99, 100 ] - 100 atoms\n\njulia> SoluteGroup([\"N\", \"CA\", \"C\", \"O\"]) # vector of atom names\nSoluteGroup defined by:\n atom_names: [ N, CA, C, O ] - 4 atom names.\n \njulia> SoluteGroup(\"acidic residues\") # predefined group name\nSoluteGroup defined by:\n group_name: \"acidic residues\"\n\njulia> SoluteGroup(1) # predefined group index\nSoluteGroup defined by:\n group_index: 1\n\njulia> SoluteGroup(collect(eachresidue(atoms))[2]) # PDBTools.Residue(s)\nSoluteGroup defined by:\n atom_indices: [ 13, 14, ..., 22, 23 ] - 11 atoms\n\n\n\n\n\n\n","category":"type"},{"location":"selection/#ComplexMixtures.atom_group-Tuple{AtomSelection, Int64}","page":"Set solute and solvent","title":"ComplexMixtures.atom_group","text":"atom_group(atsel::AtomSelection, i::Int)\natom_group(atsel::AtomSelection, groupname::String)\n\natom_group(atsel::AtomSelection, i::Int)\natom_group(atsel::AtomSelection, groupname::String)\n\nReturn the indices of the atoms that belong to a given group.\n\nExample\n\njulia> using ComplexMixtures\n\njulia> atsel = AtomSelection([1,2,3], natomspermol=1, group_atom_indices=[[1,2],[3]], group_names=[\"G1\", \"G2\"])\nAtomSelection \n 3 atoms belonging to 3 molecule(s).\n Atoms per molecule: 1\n Number of groups: 2\n\njulia> atom_group(atsel, 1)\n2-element Vector{Int64}:\n 1\n 2\n\njulia> atom_group(atsel, \"G2\")\n1-element Vector{Int64}:\n 3\n\njulia> atom_group_name(atsel, 1)\n\"G1\"\n\n\n\n\n\n","category":"method"},{"location":"selection/#ComplexMixtures.atom_group_name-Tuple{AtomSelection, Int64}","page":"Set solute and solvent","title":"ComplexMixtures.atom_group_name","text":"atom_group_name(atsel::AtomSelection, i::Int)\natom_group_names(atsel::AtomSelection)\n\nReturn the name of the group of atoms with index i. The atom_group_names function returns a vector with the names of all the groups.\n\nExample\n\njulia> using ComplexMixtures\n\njulia> atsel = AtomSelection([1,2,3], natomspermol=1, group_atom_indices=[[1,2],[3]], group_names=[\"G1\", \"G2\"])\nAtomSelection \n 3 atoms belonging to 3 molecule(s).\n Atoms per molecule: 1\n Number of groups: 2\n\njulia> atom_group_name(atsel, 1)\n\"G1\"\n\njulia> atom_group_names(atsel)\n2-element Vector{String}:\n \"G1\"\n \"G2\"\n\n\n\n\n\n","category":"method"},{"location":"selection/#ComplexMixtures.atom_group_names-Tuple{Any}","page":"Set solute and solvent","title":"ComplexMixtures.atom_group_names","text":"atom_group_name(atsel::AtomSelection, i::Int)\natom_group_names(atsel::AtomSelection)\n\nReturn the name of the group of atoms with index i. The atom_group_names function returns a vector with the names of all the groups.\n\nExample\n\njulia> using ComplexMixtures\n\njulia> atsel = AtomSelection([1,2,3], natomspermol=1, group_atom_indices=[[1,2],[3]], group_names=[\"G1\", \"G2\"])\nAtomSelection \n 3 atoms belonging to 3 molecule(s).\n Atoms per molecule: 1\n Number of groups: 2\n\njulia> atom_group_name(atsel, 1)\n\"G1\"\n\njulia> atom_group_names(atsel)\n2-element Vector{String}:\n \"G1\"\n \"G2\"\n\n\n\n\n\n","category":"method"},{"location":"example4/#Glycerol/water-mixture","page":"◦ Water/Glycerol mixture","title":"Glycerol/water mixture","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"This example illustrates the use of ComplexMixtures.jl to study the solution structure of a crowded (1:1 molar fraction) solution of glycerol in water. Here, we compute the distribution function and atomic contributions associated to the inter-species interactions (water-glycerol) and the glycerol-glycerol auto-correlation function. This example aims to illustrate how to obtain a detailed molecular picture of the solvation structures in an homogeneous mixture.","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The system simulated consists of 1000 water molecules (red) and 1000 glycerol molecules (purple).","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"
    \n\n
    ","category":"page"},{"location":"example4/#Index","page":"◦ Water/Glycerol mixture","title":"Index","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"Data, packages, and execution\nGlycerol-Glycerol and Water-Glycerol distribution functions\nGlycerol group contributions to MDDFs\n2D map of group contributions","category":"page"},{"location":"example4/#data-example4","page":"◦ Water/Glycerol mixture","title":"Data, packages, and execution","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The files required to run this example are:","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"equilibrated.pdb: The PDB file of the complete system.\ntraj_Glyc.dcd: Trajectory file. This is a 200Mb file, necessary for running from scratch the calculations.","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"To run the scripts, we suggest the following procedure:","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"Create a directory, for example example4.\nCopy the required data files above to this directory.\nLaunch julia in that directory: activate the directory environment, and install the required packages. This launching Julia and executing:\nimport Pkg \nPkg.activate(\".\")\nPkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"EasyFit\"])\nexit()\nCopy the code of each script in to a file, and execute with:\njulia -t auto script.jl\nAlternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation.","category":"page"},{"location":"example4/#glyc_mddf-example4","page":"◦ Water/Glycerol mixture","title":"Glycerol-Glycerol and Water-Glycerol distribution functions","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The first and most simple analysis is the computation of the minimum-distance distribution functions between the components of the solution. In this example we focus on the distributions of the two components relative to the glycerol molecules. Thus, we display the glycerol auto-correlation function, and the water-glycerol correlation function in the first panel of the figure below. The second panel displays the KB integrals of the two components computed from each of these distributions.","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"
    Complete example code: click here!","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example4/script1.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"

    ","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"(Image: )","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"Both water and glycerol form hydrogen bonds with (other) glycerol molecules, as indicated by the peaks at ~1.8mathrmAA. The auto-correlation function of glycerol shows a more marked second peak corresponding to non-specific interactions, which (as we will show) are likely associated to interactions of its aliphatic groups.","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The KB integrals in the second panel show similar values water and glycerol, with the KB integral for water being slightly greater. This means that glycerol molecules are (sightly, if the result is considered reliable) preferentially hydrated from a macroscopic standpoint.","category":"page"},{"location":"example4/#glyc-groups-example4","page":"◦ Water/Glycerol mixture","title":"Glycerol group contributions to MDDFs","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"
    Complete example code: click here!","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example4/script2.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"

    ","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"(Image: )","category":"page"},{"location":"example4/#map-example4","page":"◦ Water/Glycerol mixture","title":"2D map of group contributions","text":"","category":"section"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The above distributions can be split into the contributions of each glycerol chemical group. The 2D maps below display this decomposition.","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"
    Complete example code: click here!","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example4/script3.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"

    ","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"(Image: )","category":"page"},{"location":"example4/","page":"◦ Water/Glycerol mixture","title":"◦ Water/Glycerol mixture","text":"The interesting result here is that the mathrmCH group of glycerol is protected from both solvents. There is a strong density augmentation at the vicinity of hydroxyl groups, and the second peak of the MDDFs is clearly associated to interactions with the mathrmCH_2 groups.","category":"page"},{"location":"example2/#Polyacrylamide-in-DMDF","page":"◦ Polyacrylamide in DMF","title":"Polyacrylamide in DMDF","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"In this example we illustrate how the solvation structure of a polymer can be studied with ComplexMixtures.jl. The system is a 5-mer segment of polyacrylamide (PAE - capped with methyl groups), solvated with dimethylformamide (DMF). The system is interesting because of the different functional groups and polarities involved in the interactions of DMF with PAE. A snapshot of the system is shown below.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    \n\n
    ","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The structures of DMF and of the polyacrylamide segment are:","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    \n\n\n\n\n\n\n\n\n
    DMFPolyacrylamide
    \n
    ","category":"page"},{"location":"example2/#Index","page":"◦ Polyacrylamide in DMF","title":"Index","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"Data, packages, and execution\nMDDF and KB integrals\nGroup contributions\n2D density map","category":"page"},{"location":"example2/#data-example2","page":"◦ Polyacrylamide in DMF","title":"Data, packages, and execution","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The files required to run this example are:","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"equilibrated.pdb: The PDB file of the complete system.\ntraj_Polyacry.dcd: Trajectory file. This is a 275Mb file, necessary for running from scratch the calculations.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"To run the scripts, we suggest the following procedure:","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"Create a directory, for example example2.\nCopy the required data files above to this directory.\nLaunch julia in that directory: activate the directory environment, and install the required packages. This launching Julia and executing:\nimport Pkg \nPkg.activate(\".\")\nPkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"EasyFit\"])\nexit()\nCopy the code of each script in to a file, and execute with:\njulia -t auto script.jl\nAlternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation.","category":"page"},{"location":"example2/#mddf-example2","page":"◦ Polyacrylamide in DMF","title":"MDDF and KB integrals","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"Here we compute the minimum-distance distribution function, the Kirkwood-Buff integral, and the atomic contributions of the solvent to the density. This example illustrates the regular usage of ComplexMixtures, to compute the minimum distance distribution function, KB-integrals and group contributions. ","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    Complete example code: click here!","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example2/script1.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"

    ","category":"page"},{"location":"example2/#Output","page":"◦ Polyacrylamide in DMF","title":"Output","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The distribution of DMF molecules around polyacrylamide is shown below. There is a peak at ~2.5Angs, indicating favorable non-specific interactions between the solvent molecules and the polymer. The peak is followed by a dip and diffuse peaks at higher distances. Thus, the DMF molecules are structured around the polymer, but essentially only in the first solvation shell. ","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"(Image: )","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The KB integral in a bicomponent mixture converges to the (negative of the) apparent molar volume of the solute. It is negative, indicating that the accumulation of DMF in the first solvation shell of the polymer is not enough to compensate the excluded volume of the solute. ","category":"page"},{"location":"example2/#groups-example2","page":"◦ Polyacrylamide in DMF","title":"Group contributions","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The MDDF can be decomposed into the contributions of the DMF chemical groups, and on the polyacrylamide chemical groups. In the first panel below we show the contributions of the DMF chemical groups to the distribution function.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    Complete example code: click here!","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example2/script2.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"

    ","category":"page"},{"location":"example2/#Output-2","page":"◦ Polyacrylamide in DMF","title":"Output","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The decomposition reveals that specific interactions peaking at distances slightly smaller than 2AA exist between the polymer and the carbonyl group of DMF. Thus, there hydrogen bonds between the polymer and this group, which dominate the interactions between the solute and the solvent at short distances. The non-specific interactions peak at 2.5Angs and are composed of contributions of all DMF chemical groups, but particularly of the methyl groups.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"(Image: )","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The decomposition of the same MDDF in the contributions of the chemical groups of the polymer is clearly associated to the DMF contributions. The specific, hydrogen-bonding, interactions, are associated to the polymer amine groups. The amine groups also contribute to the non-specific interactions at greater distances, but these are a sum of the contributions of all polymer groups, polar or aliphatic.","category":"page"},{"location":"example2/#2Dmap-example2","page":"◦ Polyacrylamide in DMF","title":"2D density map","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"We can decompose the MDDF into the contributions of each portion of the polymer chain. The map below displays the contributions of each chemical group of the polymer, now split into the mers of the polymer, to the MDDF.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    Complete example code: click here!","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example2/script3.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"

    ","category":"page"},{"location":"example2/#Output-3","page":"◦ Polyacrylamide in DMF","title":"Output","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The terminal methyl groups interact strongly with DMF, and strong local density augmentations are visible in particular on the amine groups. These occur at less than 2.0Angs and are characteristic of hydrogen-bond interactions. Interestingly, the DMF molecules are excluded from the aliphatic and carbonyl groups of the polymer, relative to the other groups.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"Finally, it is noticeable that the central mer is more weakly solvated by DMF than the mers approaching the extremes of the polymer chain. This is likely a result of the partial folding of the polymer, that protects that central mers from the solvent in a fraction of the polymer configurations.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"
    \n\n
    ","category":"page"},{"location":"example2/#References","page":"◦ Polyacrylamide in DMF","title":"References","text":"","category":"section"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"Molecules built with JSME: B. Bienfait and P. Ertl, JSME: a free molecule editor in JavaScript, Journal of Cheminformatics 5:24 (2013) http://biomodel.uah.es/en/DIY/JSME/draw.en.htm","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The system was built with Packmol.","category":"page"},{"location":"example2/","page":"◦ Polyacrylamide in DMF","title":"◦ Polyacrylamide in DMF","text":"The simulations were perfomed with NAMD, with CHARMM36 parameters. ","category":"page"},{"location":"example3/#POPC-membrane-in-water/ethanol","page":"◦ POPC membrane in water/ethanol","title":"POPC membrane in water/ethanol","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"In this example ComplexMixtures.jl is used to study the interactions of a POPC membrane with a mixture of 20%(mol/mol) ethanol in water. At this concentration ethanol destabilizes the membrane.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    \n\n
    ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"System image: a POPC membrane (center) solvated by a mixture of water (purple) and ethanol (green). The system is composed by 59 POPC, 5000 water, and 1000 ethanol molecules. ","category":"page"},{"location":"example3/#Index","page":"◦ POPC membrane in water/ethanol","title":"Index","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Data, packages, and execution\nMDDF and KB integrals\nGroup contributions\nInteraction of POPC groups with water\nInteraction of POPC groups with ethanol\nDensity map on POPC chains","category":"page"},{"location":"example3/#data-example3","page":"◦ POPC membrane in water/ethanol","title":"Data, packages, and execution","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The files required to run this example are:","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"equilibrated.pdb: The PDB file of the complete system.\ntraj_POPC.dcd: Trajectory file. This is a 365Mb file, necessary for running from scratch the calculations.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"To run the scripts, we suggest the following procedure:","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Create a directory, for example example3.\nCopy the required data files above to this directory.\nLaunch julia in that directory: activate the directory environment, and install the required packages. This launching Julia and executing:\nimport Pkg \nPkg.activate(\".\")\nPkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"EasyFit\"])\nexit()\nCopy the code of each script in to a file, and execute with:\njulia -t auto script.jl\nAlternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation.","category":"page"},{"location":"example3/#mddf-example3","page":"◦ POPC membrane in water/ethanol","title":"MDDF and KB integrals","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Here we show the distribution functions and KB integrals associated to the solvation of the membrane by water and ethanol. ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    Complete example code: click here!","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example3/script1.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"

    ","category":"page"},{"location":"example3/#Output","page":"◦ POPC membrane in water/ethanol","title":"Output","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The distribution functions are shown in the first panel of the figure below, and the KB integrals are shown in the second panel.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Clearly, both water and ethanol accumulate on the proximity of the membrane. The distribution functions suggest that ethanol displays a greater local density augmentation, reaching concentrations roughly 4 times higher than bulk concentrations. Water has a peak at hydrogen-bonding distances (~1.8mathrmAA) and a secondary peak at 2.5mathrmAA.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Despite the fact that ethanol displays a greater relative density (relative to its own bulk concentration) at short distances, the KB integral of water turns out to be greater (more positive) than that of ethanol. This implies that the membrane is preferentially hydrated.","category":"page"},{"location":"example3/#groups1-example3","page":"◦ POPC membrane in water/ethanol","title":"Ethanol group contributions","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The minimum-distance distribution function can be decomposed into the contributions of the ethanol molecule groups. ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    Complete example code: click here!","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example3/script2.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"

    ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"In the figure below we show the contributions of the ethanol hydroxyl and aliphatic chain groups to the total MDDF.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"As expected, the MDDF at hydrogen-bonding distances is composed by contributions of the ethanol hydroxyl group, and the non-specific interactions at ~2.5mathrmAA have a greater contribution of the aliphatic chain of the solvent molecules. It is interesting to explore the chemical complexity of POPC in what concerns these interactions.","category":"page"},{"location":"example3/#groups2-example3","page":"◦ POPC membrane in water/ethanol","title":"Interaction of POPC groups with water","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The MDDF can also be decomposed into the contributions of the solute atoms and chemical groups. First, we show the contributions of the POPC chemical groups to the water-POPC distribution.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    Complete example code: click here!","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example3/script3.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"

    ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Not surprisingly, water interactions occur majoritarily with the Phosphate and Choline groups of POPC molecules, that is, with the polar head of the lipid. The interactions at hydrogen-bonding distances are dominated by the phosphate group, and non-specific interaction occur mostly with the choline group. Some water molecules penetrate the membrane and interact with the glycerol and aliphatic chains of POPC, but these contributions are clearly secondary.","category":"page"},{"location":"example3/#groups3-example3","page":"◦ POPC membrane in water/ethanol","title":"Interaction of POPC groups with ethanol","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The interactions of ethanol molecules with the membrane are more interesting, because ethanol penetrates the membrane. Here we decompose the ethanol-POPC distribution function into the contributions of the POPC chemical groups.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    Complete example code: click here!","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example3/script4.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"

    ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Ethanol molecules interact with the choline and phosphate groups of POPC molecules, as do water molecules. The contributions to the MDDF at hydrogen-bonding distances come essentially from ethanol-phosphate interactions.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"However, ethanol molecules interact frequently with the glycerol and aliphatic chains of POPC. Interactions with the Oleoyl chain are slightly stronger than with the Palmitoyl chain. This means that ethanol penetrates the hydrophobic core of the membrane, displaying non-specific interactions with the lipids and with the glycerol group. These interactions are probably associated to the destabilizing role of ethanol in the membrane structure.","category":"page"},{"location":"example3/#map-example3","page":"◦ POPC membrane in water/ethanol","title":"Density map on POPC chains","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The MDDFs can be decomposed at more granular level, in which each chemical group of the aliphatic chains of the POPC molecules are considered independently. This allows the study of the penetration of the ethanol molecules in the membrane. In the figure below, the carbonyl following the glycerol group of the POPC molecules is represented in the left, and going to the right the aliphatic chain groups are sequentially shown.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"
    Complete example code: click here!","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`julia\n$(read(\"./assets/scripts/example3/script5.jl\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"

    ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Ethanol displays an important density augmentation at the vicinity of the carbonyl that follows the glycerol group, and accumulates on the proximity of the aliphatic chain. The density of ethanol decreases as one advances into the aliphatic chain, displaying a minimum around the insaturation in the Oleoyl chain. The terminal methyl group of both chains display a greater solvation by ethanol, suggesting the twisting of the aliphatic chain expose these terminal groups to membrane depth where ethanol is already abundant.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The equivalent maps for water are strikingly different, and show that water is excluded from the interior of the membrane:","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"(Image: )","category":"page"},{"location":"example3/#References","page":"◦ POPC membrane in water/ethanol","title":"References","text":"","category":"section"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Membrane built with the VMD membrane plugin. ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Water and ethanol layers added with Packmol.","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"The simulations were performed with NAMD, with CHARMM36 parameters. ","category":"page"},{"location":"example3/","page":"◦ POPC membrane in water/ethanol","title":"◦ POPC membrane in water/ethanol","text":"Density of the ethanol-water mixture from: https://wissen.science-and-fun.de/chemistry/chemistry/density-tables/ethanol-water-mixtures/","category":"page"},{"location":"tools/#Tools","page":"Tools","title":"Tools","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"Coordination numbers\n2D density map per residue\n3D density map around a macromolecule\nOverview of the solvent and solute properties\nComputing radial distribution functions","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"CollapsedDocStrings = true","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::Union{SoluteGroup, SolventGroup})","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/","page":"Tools","title":"Tools","text":"note: Note\nThere are some systems for which the normalization of the distributions is not necessary or possible. It is still possible to compute the coordination numbers, by running, instead of mddf, the coordination_number function:coordination_number(trajectory::Trajectory, options::Options)This call will return Result data structure but with all fields requiring normalization with zeros. In summary, this result data structure can be used to compute the coordination numbers, but not the MDDF, RDF, or KB integrals.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"compat: Compat\nThe independent computation of coordination numbers was introduced in version 1.1.","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 = AtomSelection(PDBTools.select(pdb, \"protein\"), nmols=1)\nresidue50 = PDBTools.select(pdb, \"residue 50\")\n# Compute the group contribution to the MDDF\nresidue50_contribution = contributions(R, SoluteGroup(residue50))\n# Now compute the coordination number\nresidue50_coordination = coordination_number(R, SoluteGroup(residue50))\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/","page":"Tools","title":"Tools","text":"Modules = [ComplexMixtures]\nPages = [\"coordination_number.jl\"]","category":"page"},{"location":"tools/#ComplexMixtures.coordination_number","page":"Tools","title":"ComplexMixtures.coordination_number","text":"coordination_number(R::Result) = R.coordination_number\ncoordination_number(R::Result, s::Union{SoluteGroup,SolventGroup})\n\nComputes the coordination number of a given group of atoms of the solute or solvent\n\natomic 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.AtomSelection)\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 indices, 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 = AtomSelection(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 = AtomSelection(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":"function"},{"location":"tools/#2D_per_residue","page":"Tools","title":"2D density map per residue","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, coordination numbers or minimum-distance counts. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"compat: Compat\nAll features described in this section are only available in v2.7.0 or greater.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The computation of the contributions of each residue can be performed with the convenience function ResidueContributions, which creates an object containing the contributions of the residues to the mddf (or coordination numbers, or minimum-distance counts), the residue names, and distances:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"ResidueContributions","category":"page"},{"location":"tools/#ComplexMixtures.ResidueContributions-tools","page":"Tools","title":"ComplexMixtures.ResidueContributions","text":"ResidueContributions (data structure)\n\nConstructor function:\n\nResidueContributions(\n results::Result, atoms::AbstractVector{PDBTools.Atom};\n dmin=1.5, dmax=3.5,\n type=:mddf,\n)\n\nCompute the residue contributions to the solute-solvent pair distribution function. The function returns a ResidueContributions object that can be used to plot the residue contributions, or to perform arithmetic operations with other ResidueContributions objects.\n\nArguments\n\nresults::Result: The result object obtained from the mddf function.\natoms::AbstractVector{PDBTools.Atom}: The vector of atoms of the solute, or a part of it.\n\nOptional arguments\n\ndmin::Float64: The minimum distance to consider. Default is 1.5.\ndmax::Float64: The maximum distance to consider. Default is 3.5.\ntype::Symbol: The type of the pair distribution function (:mddf, :md_count, or :coordination_number). Default is :mddf.\nsilent::Bool: If true, the progress bar is not shown. Default is false.\n\nA structure of type ResultContributions can be used to plot the residue contributions to the solute-solvent pair distribution function, using the Plots.contourf function, and to perform arithmetic operations with other ResidueContributions objects, multiplying or dividing by a scalar, and slicing (see examples below).\n\nExamples\n\nConstructing a ResidueContributions object\n\njulia> using ComplexMixtures, PDBTools\n\njulia> using ComplexMixtures.Testing: data_dir; ComplexMixtures._testing_show_method[] = true; # testing mode\n\njulia> atoms = readPDB(data_dir*\"/NAMD/Protein_in_Glycerol/system.pdb\");\n\njulia> results = load(data_dir*\"/NAMD/Protein_in_Glycerol/protein_glyc.json\");\n\njulia> rc = ResidueContributions(results, select(atoms, \"protein\"); silent=true)\n\n Residue Contributions\n 3.51 █ █ █ █ █\n 3.27 █ █ █\n 3.03 █ █ █ █ █ █ █ █\n 2.79 █ ██ █ █ █ █ █ ██ █ █ █\n d 2.55 █ █ ██ █ █ █ █ ██ ██ █ █ █ █ █ █ █\n 2.31 █ █ ██ █ ███ █ ██ ██ ██ █ ██ █ ██ █ █ █\n 2.07 █ █ █ █ █████ █ ██ ██ ██ █ ██ █ █ ██ █ █\n 1.83 █ █ █ █ █████ █ ██ █ ██ █ ██ █ ██ █ █\n 1.59\n A1 T33 T66 S98 S130 T162 A194 H226 G258 \n\n\nPlotting\n\nusing ComplexMixtures, PDBTools, Plots\n...\nresult = mddf(traj, options)\nrc = ResidueContributions(result, select(atoms, \"protein\"))\ncontourf(rc) # plots a contour map\n\nSlicing\n\nSlicing, or indexing, the residue contributions returns a new ResidueContributions object with the selected residues:\n\nusing ComplexMixtures, PDBTools, Plots\n...\nresult = mddf(traj, options)\nrc = ResidueContributions(result, select(atoms, \"protein\"))\nrc_7 = rc[7] # contributions of residue 7\nrc_range = rc[10:50] # slice the residue contributions\ncontourf(rc_range) # plots a contour map of the selected residues\n\nArithmetic operations\n\nusing ComplexMixtures, PDBTools, Plots\n...\n# first simulation (for example, low temperature):\nresult1 = mddf(traj2, options)\nrc1 = ResidueContributions(result1, select(atoms, \"protein\"))\n# second simulation (for example, high temperature):\nresult2 = mddf(traj2, options)\nrc2 = ResidueContributions(result2, select(atoms, \"protein\"))\n# difference of the residue contributions between the two simulations:\nrc_diff = rc2 - rc1\ncontourf(rc_diff) # plots a contour map of the difference\n\ncompat: Compat\nSlicing, indexing, and multiplication and divison by scalars were introduces in v2.7.0.\n\n\n\n\n\n","category":"type"},{"location":"tools/","page":"Tools","title":"Tools","text":"The output of ResidueContributions is by default shown as a simple unicode plot:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"
    \n\n
    ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The ResidueContribution object can be used to produce a high-quality contour plot using the Plots.contourf function:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Plots.contourf(::ResidueContributions)","category":"page"},{"location":"tools/#Plots.contourf-Tuple{ResidueContributions}","page":"Tools","title":"Plots.contourf","text":"contourf(\n rc::ResidueContributions; \n step::Int=1,\n oneletter=false,\n xlabel=\"Residue\",\n ylabel=\"r / Å\",\n)\n\nPlot the contribution of each residue to the solute-solvent pair distribution function as a contour plot. This function requires loading the Plots package.\n\nArguments\n\nrc::ResidueContributions: The residue contributions to the solute-solvent pair distribution function, as computed by the ResidueContributions function.\n\nOptional arguments\n\nstep: The step of the residue ticks in the x-axis of the plot. Default is 1.\noneletter::Bool: Use one-letter residue codes. Default is false. One-letter codes are only available for the 20 standard amino acids.\nxlabel and ylabel: Labels for the x and y axes. Default is \"Residue\" and \"r / Å\".\n\nThis function will set color limits and choose the scale automatically. These parameters can be set with the clims and color arguments of Plots.contourf. Other plot customizations can be done by passing other keyword arguments to this function, which will be passed to Plots.contourf.\n\nExample\n\njulia> using ComplexMixtures, Plots, PDBTools\n\njulia> results = load(\"mddf.json\")\n\njulia> atoms = readPDB(\"system.pdb\", \"protein\")\n\njulia> rc = ResidueContributions(results, atoms; oneletter=true)\n\njulia> plt = contourf(rc; step=5)\n\nThis will produce a plot with the contribution of each residue to the solute-solvent pair distribution function, as a contour plot, with the residues in the x-axis and the distance in the y-axis.\n\nTo customize the plot, use the Plot.contourf keyword parameters, for example:\n\njulia> plt = contourf(rc; step=5, size=(800,400), title=\"Title\", clims=(-0.1, 0.1))\n\ncompat: Compat\nThis function requires loading the Plots package and is available in ComplexMixtures v2.5.0 or greater.Support for all Plots.contourf parameters was introduced in ComplexMixtures v2.6.0.\n\n\n\n\n\n","category":"method"},{"location":"tools/","page":"Tools","title":"Tools","text":"A complete example of its usage can be seen here. ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The ResidueContributions object can be indexes and sliced, for the analysis of the contributions of specific residues or range of residues:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"rc = ResidueContributions(results1, select(atoms, \"protein\")); \nrc_7 = rc[7] # contributions of residue 7\nrc_range = rc[20:50] # contributions of a range of residues","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Slicing will return a new ResidueContributions object.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Additionally, these ResidueContributions objects can be subtracted, divided, summed, or multiplied, to compare contributions of residues among different simulations. Typically, if one wants to compare the solvation of residues in two different simulations, one can do:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"# first simulation (for example, low temperature)\nrc1 = ResidueContributions(results1, select(atoms, \"protein\")); \n\n# second simulation (for example, high temperature)\nrc2 = ResidueContributions(results2, select(atoms, \"protein\"));\n\n# difference in residue contributions to solvation\nrc_diff = rc2 - rc1\n\n# Plot difference\nusing Plots\ncontourf(rc_diff; title=\"Density difference\", step=2, colorbar=:left)","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Which will produce a plot similar to the one below (the data of this plot is just illustrative):","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"which will return a new ResidueContributions object.","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"
    \n\n
    ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Finally, it is also possible to renormalize the contributions by multiplication or division by scalars,","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"rc2 = rc / 15\nrc2 = 2 * rc","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"tip: Tip\nThis function is a convenience function only.Basically, we are extracting the contribution of each residue independently and building a matrix where each row represents a distance and each column a residue. Using PDBTools, this can be done with, for example: residues = collect(eachresidue(protein))\nresidue_contributions = zeros(length(R.d),length(residues))\nfor (i,residue) in pairs(residues)\n c = contributions(results, SoluteGroup(residue)) \n residue_contributions[:,i] .= c\nendThe 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. ","category":"page"},{"location":"tools/#grid3D","page":"Tools","title":"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":"A 3D density map is constructed with the grid3D function:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"Modules = [ComplexMixtures]\nPages = [\"tools/grid3D.jl\"]","category":"page"},{"location":"tools/#ComplexMixtures.grid3D","page":"Tools","title":"ComplexMixtures.grid3D","text":"grid3D(\n result::Result, atoms, output_file::Union{Nothing,String} = nothing; \n dmin=1.5, ddax=5.0, step=0.5, silent = false,\n)\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\nresult is a ComplexMixtures.Result object atoms is a vector of PDBTools.Atoms with all the atoms of the system. output_file is the name of the file where the grid will be written. If nothing, the grid is only returned as a matrix. \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\nsilent is a boolean to suppress the progress bar.\n\nThe output PDB has the following characteristics:\n\nThe positions of the atoms are grid points. \nThe identity of the atoms correspond to the identity of the protein atom contributing to the MDDF at that point (the closest protein atom). \nThe temperature-factor column (beta) contains the relative contribution of that atom to the MDDF at the corresponding distance. \nThe occupancy field contains the distance itself.\n\nExample\n\njulia> using ComplexMixtures, PDBTools\n\njulia> atoms = readPDB(\"./system.pdb\");\n\njulia> R = ComplexMixtures.load(\"./results.json\");\n\njulia> grid = grid3D(R, atoms, \"grid.pdb\");\n\nExamples of how the grid can be visualized are provided in the user guide of ComplexMixtures. \n\n\n\n\n\n","category":"function"},{"location":"tools/","page":"Tools","title":"Tools","text":"The call to grid3D 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 where: ","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"The positions of the atoms are grid points. \nThe identity of the atoms correspond to the identity of the protein atom contributing to the MDDF at that point (the closest protein atom). \nThe temperature-factor column (beta) contains the relative contribution of that atom to the MDDF at the corresponding distance. \nThe occupancy field contains the distance itself.","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/#radial_distribution","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/","page":"Tools","title":"Tools","text":"Modules = [ComplexMixtures]\nPages = [\"gr.jl\"]","category":"page"},{"location":"tools/#ComplexMixtures.gr-Tuple{Result}","page":"Tools","title":"ComplexMixtures.gr","text":"gr(R::Result) = gr(R.d,R.rdf_count,R.density.solvent_bulk,R.files[1].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":"tools/#ComplexMixtures.gr-Tuple{Vector{Float64}, Vector{Float64}, Float64, Float64}","page":"Tools","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":"tools/#overview","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":"...\n\njulia> results = mddf(trajectory, Options(bulk_range=(8.0, 12.0)))\n\njulia> results\n--------------------------------------------------------------------------------\nMDDF Overview - ComplexMixtures - Version 2.0.8\n--------------------------------------------------------------------------------\n\nSolvent properties:\n-------------------\n\nSimulation concentration: 0.49837225882780106 mol L⁻¹\nMolar volume: 2006.532230249041 cm³ mol⁻¹\n\nConcentration in bulk: 0.5182380507741433 mol L⁻¹\nMolar volume in bulk: 1929.6151614228274 cm³ mol⁻¹\n\nSolute properties:\n------------------\n\nSimulation Concentration: 0.002753437894076249 mol L⁻¹\nEstimated solute partial molar volume: 13921.98945754469 cm³ mol⁻¹\n\nBulk range: 8.0 - 12.0 Å\nMolar volume of the solute domain: 34753.1382279134 cm³ mol⁻¹\n\nAuto-correlation: false\n\nTrajectory files and weights:\n\n /home/user/NAMD/trajectory.dcd - w = 1.0\n\nLong range MDDF mean (expected 1.0): 1.0378896753018338 ± 1.0920172247127446\nLong range RDF mean (expected 1.0): 1.2147429551790854 ± 1.2081838161780682\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":"tools/#Legacy","page":"Tools","title":"Legacy","text":"","category":"section"},{"location":"tools/","page":"Tools","title":"Tools","text":"The legacy function contourf_per_residue provides a direct way to produce contour plots:","category":"page"},{"location":"tools/","page":"Tools","title":"Tools","text":"contourf_per_residue(::Result, ::AbstractVector{PDBTools.Atom})","category":"page"},{"location":"tools/#ComplexMixtures.contourf_per_residue-Tuple{Result, AbstractVector{Atom}}","page":"Tools","title":"ComplexMixtures.contourf_per_residue","text":"contourf_per_residue(\n results::Result, atoms::AbstractVector{PDBTools.Atom}; \n residue_range=nothing, \n dmin=1.5, dmax=3.5, \n oneletter=false,\n xlabel=\"Residue\",\n ylabel=\"r / Å\",\n type=:mddf,\n clims=nothing,\n colorscale=:tempo,\n)\n\nPlot the contribution of each residue to the solute-solvent pair distribution function as a contour plot. This function requires loading the Plots package.\n\nArguments\n\nresults::Result: The result of a mddf call.\natoms::AbstractVector{Atom}: The atoms of the solute.\n\nOptional arguments\n\nresidue_range: The range of residues to plot. Default is all residues. Use a step to plot every n residues, e.g., 1:2:30.\ndmin::Real: The minimum distance to plot. Default is 1.5.\ndmax::Real: The maximum distance to plot. Default is 3.5.\noneletter::Bool: Use one-letter residue codes. Default is false. One-letter codes are only available for the 20 standard amino acids.\nxlabel and ylabel: Labels for the x and y axes. Default is \"Residue\" and \"r / Å\".\ntype::Symbol: That data to plot. Default is :mddf for MDDF contributions. Options are :coordination_number, and :mddf_count.\nclims: The color limits for the contour plot.\ncolorscale: The color scale for the contour plot. Default is :tempo. We suggest :bwr if the zero is at the middle of the color scale (use clims to adjust the color limits).\n\nExample\n\njulia> using ComplexMixtures, Plots, PDBTools\n\njulia> results = load(\"mddf.json\")\n\njulia> atoms = readPDB(\"system.pdb\", \"protein\")\n\njulia> plt = contourf_per_residue(results, atoms; oneletter=true)\n\nThis will produce a plot with the contribution of each residue to the solute-solvent pair distribution function, as a contour plot, with the residues in the x-axis and the distance in the y-axis.\n\nThe resulting plot can customized using the standard mutating plot! function, for example, \n\njulia> plot!(plt, size=(800, 400), title=\"Contribution per residue\")\n\ncompat: Compat\nThis function requires loading the Plots package and is available in ComplexMixtures v2.2.0 or greater.The type and clims arguments, and the support for a step in xticks_range were introduced in ComplexMixtures v2.3.0.\n\n\n\n\n\n","category":"method"},{"location":"updating_scripts/#updating-scripts","page":"Updating scripts","title":"Updating scripts from v1 to v2","text":"","category":"section"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"The syntax chances necessary to update script from version 1.X to 2.X of the package are:","category":"page"},{"location":"updating_scripts/#Atom-selections","page":"Updating scripts","title":"Atom selections","text":"","category":"section"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"The previous Selection structure was renamed to AtomSelection for clarity.","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Before:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"water = Selection(water; natomspermol=3)","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Now:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"water = AtomSelection(water; natomspermol=3)","category":"page"},{"location":"updating_scripts/#Group-contributions-syntax","page":"Updating scripts","title":"Group contributions syntax","text":"","category":"section"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"The syntax to computing group contributions is improved. Previously, the contrib or contributions functions required three somewhat redundant parameters. ","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Before:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"The call to contributions required 3 parameters: the Selection structure, the matrix of contributions, and the indexes of the atoms for which the contributions were desired:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"h_contributions = contributions(solvent, R.solvent_atom, h_indexes)","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Now:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"The contributions are extracted from the Result data structure, by providing either a SoluteGroup or SolventGroup object, which are setup with the group names, group indexes, atom names, or atom indexes:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"h_contributions = contributions(R, SolventGroup(h_indexes))","category":"page"},{"location":"updating_scripts/#Frame-weights","page":"Updating scripts","title":"Frame weights","text":"","category":"section"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"frame_weights is now an option of the mddf execution. That is previously, they were defined in the Options data structure, and now they are passed to the mddf function.","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Before:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"options = Options(frame_weights=[1.0, 2.0], bulk_range=(8.0, 12.0))\nresults = mddf(trajectory, options)","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"Now:","category":"page"},{"location":"updating_scripts/","page":"Updating scripts","title":"Updating scripts","text":"results = mddf(trajectory, options; frame_weights=[1.0, 2.0])","category":"page"},{"location":"examples/#examples","page":"Examples:","title":"Examples","text":"","category":"section"},{"location":"examples/#List-of-examples","page":"Examples:","title":"List of examples","text":"","category":"section"},{"location":"examples/","page":"Examples:","title":"Examples:","text":"Protein in water/glycerol\nPolyacrylamide in DMDF\nPOPC membrane in water/ethanol\nGlycerol/water mixture","category":"page"},{"location":"examples/#How-to-run-these-examples","page":"Examples:","title":"How to run these examples","text":"","category":"section"},{"location":"examples/","page":"Examples:","title":"Examples:","text":"1 Download and install Julia","category":"page"},{"location":"examples/","page":"Examples:","title":"Examples:","text":"To run the scripts, we suggest the following procedure:","category":"page"},{"location":"examples/","page":"Examples:","title":"Examples:","text":"Create a directory, for example example1.\nCopy the required data files, indicated in each example.\nLaunch julia in that directory, activate the directory environment, and install the required packages. This is done by launching Julia and executing:\nimport Pkg \nPkg.activate(\".\")\nPkg.add([\"ComplexMixtures\", \"PDBTools\", \"Plots\", \"LaTeXStrings\", \"EasyFit\"])\nexit()\nCopy the code of each script in to a file, and execute with:\njulia -t auto script.jl\nAlternativelly (and perhaps preferrably), copy line by line the content of the script into the Julia REPL, to follow each step of the calculation. For a more advanced Julia usage, we suggest the VSCode IDE with the Julia Language Support extension. ","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, bulk_range=(8.0, 12.0))\nresults = mddf(trajectory, options)","category":"page"},{"location":"options/#Frame-ranges-and-histogram-properties","page":"Options","title":"Frame ranges and histogram properties","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"These are common options that the regular user might want to set in their calculation.","category":"page"},{"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":"bulk_range: This parameter defines the range of distances from the solute that will be considered as the bulk region of the solution. The density of the bulk solution is estimated by counting the number of molecules of the solvent in this region, and by performing a numerical integration of its volume. Set this range to a region of the solution where the MDDF is converged to 1 for practical purposes. Tuning this parameter is crucial for a proper convergence of the MDDFs and KB integrals. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"compat: Compat\nThe bulk_range option was introduced in version 2.1.0.","category":"page"},{"location":"options/#Lower-level-options","page":"Options","title":"Lower level options","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"These will probably never be set by the user, unless if dealing with some special system (large very large, or very low density system).","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. By default, all molecules at distances greater than 10.0 Angstroms are considered bulk molecules. However, the definition of bulk_range is highly encouraged. ","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. The definition of bulk_range instead is highly encouraged. ","category":"page"},{"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":"options/#Frame-statistical-reweighing","page":"Options","title":"Frame statistical reweighing","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"compat: Compat\nFrame reweighing is available in ComplexMixtures 2.0.0 or greater.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"Most times the weights of each frame of the trajectory are the same, resulting from some standard MD simulation. If, for some reason, the frames have different statistical weights, the weights can be passed to the as an optional parameter frame_weights.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"For example:","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"julia> results = mddf(trajectory, options; frame_weights=[0.0, 1.0, 2.0])","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"The code above will assign a larger weight to the third frame of the trajectory. These weights are relative (meaning that [0.0, 1.0, 2.0] would produce the same result). What will happen under the hood is that the distance counts of the frames will be multiplied by each frame weight, and normalized for the sum of the weights.","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"Important: The length of the frame_weights vector must be at least equal to the number of the last frame read from the trajectory. That is, if lastframe is not set, and all the frames will be read, the length of frame_weights must be equal to the length of the trajectory (the stride parameter will skip the information both of the frames and its weights). If lastframe is set, then the length of frame_weights must be at least lastframe (it can be greater, and further values will be ignored). Importantly, the indices of the elements in frame_weights are assumed to correspond to the indices of the frames in the original trajectory file.","category":"page"},{"location":"options/#Compute-coordination-number-only","page":"Options","title":"Compute coordination number only","text":"","category":"section"},{"location":"options/","page":"Options","title":"Options","text":"For some systems, it may be impossible, or to expensive, to compute the normalization of the minimum-distance distribution function. Nevertheless, the coordination number may still be an interesting information to be retrieved from the simulations. To run the computation to compute coordination numbers only, do:","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"julia> results = mddf(trajectory, options; coordination_number_only = true)","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"note: Note\nWith coordination_number_only set to true, the arrays associated to MDDFs and KB integrals will be empty in the output data structure. ","category":"page"},{"location":"options/","page":"Options","title":"Options","text":"Modules = [ComplexMixtures]\nPages = [\"Options.jl\"]","category":"page"},{"location":"options/#ComplexMixtures.Options-Tuple{}","page":"Options","title":"ComplexMixtures.Options","text":"Options(;\n firstframe::Int = 1,\n lastframe::Int = -1,\n stride::Int = 1,\n irefatom::Int = -1,\n n_random_samples::Int = 10,\n binstep::Float64 = 0.02,\n dbulk::Union{Nothing,Real} = nothing,\n cutoff::Union{Nothing,Real} = nothing,\n usecutoff::Union{Nothing,Bool} = nothing,\n bulk_range=nothing,\n lcell::Int = 1,\n GC::Bool = true,\n GC_threshold::Float64 = 0.3,\n seed::Int = 321,\n StableRNG::Bool = false,\n nthreads::Int = 0,\n silent::Bool = false\n)\n\nCreate an Options object with the specified options. \n\n\n\n\n\n","category":"method"},{"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 choosing 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 glycerol (green) and water, at a concentration of 50%vv.","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/#Example","page":"From Python","title":"Example","text":"","category":"section"},{"location":"python/#Index","page":"From Python","title":"Index","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"Data, packages, and execution\nMinimum-Distance Distribution function\nMDDF and KB integrals\nAtomic contributions to the MDDF","category":"page"},{"location":"python/#data-pythonexample","page":"From Python","title":"Data, packages, and execution","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"The files required to run this example are:","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"system.pdb: The PDB file of the complete system.\nglyc50_sample.dcd: A 30Mb sample trajectory file. The full trajectory can also be used, but it is a 1GB file.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"To start, create a directory and copy the ComplexMixtures.py file to it. Navigate into this directory, and, to start, set the number of threads that Julia will use, to run the calculations in parallel. Typically, in bash, this means defining teh following environment variable:","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"export JULIA_NUM_THREADS=8","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"where 8 is the number of CPU cores available in your computer. For further information about Julia multi-threading, and on setting this environment variable in other systems, please read this section of the Julia manual.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"Finally, each script can be executed with, for example:","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"python3 script.py","category":"page"},{"location":"python/#script1-python","page":"From Python","title":"Minimum-Distance Distribution function","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"
    Complete example code: click here!","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`python\n$(read(\"./assets/scripts/python/script1.py\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"

    ","category":"page"},{"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":"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(bulk_range=(8.0, 12.0))\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/#python-plotting1","page":"From Python","title":"MDDF and KB integrals","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"The following python script will produce the typical MDDF and KB integral plot, for the sample system. The noise in the figures is because the trajectory sample is small.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"
    Complete example code: click here!","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`python\n$(read(\"./assets/scripts/python/script2.py\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"

    ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"(Image: )","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"In the top plot, we see that glycerol and water display clear solvation shells around the protein, with glycerol having a greater peak. This accumulation leads to a greater (less negative) KB integral for glycerol than water, as shown in the second plot. This indicates that the protein is preferentially solvated by glycerol in this system (assuming that sampling is adequate in this small trajectory).","category":"page"},{"location":"python/#python-plotting2","page":"From Python","title":"Atomic contributions to the MDDF","text":"","category":"section"},{"location":"python/","page":"From Python","title":"From Python","text":"The following script produces a plot of the group contributions of Glycerol to the total MDDF function. The Glycerol MDDF is split into the contributions of the hydroxyl and aliphatic groups.","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"
    Complete example code: click here!","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"using Markdown\ncode = Markdown.parse(\"\"\"\n\\`\\`\\`python\n$(read(\"./assets/scripts/python/script3.py\", String))\n\\`\\`\\`\n\"\"\")","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"

    ","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"(Image: )","category":"page"},{"location":"python/","page":"From Python","title":"From Python","text":"Despite the low sampling, it is clear that hydroxyl groups contribute to the greter peak of the distribution, at hydrogen-bonding distances, as expected. The contributions of the aliphatic groups to the MDDF occurs at longer distances, associated to non-specific interactions. ","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":"","page":"Introduction","title":"Introduction","text":"compat: Compat\nImportant: This manual refers to version 2 of ComplexMixtures.jl. There are syntax changes relative to the 1.X series, and analysis scripts written for the previous versions won't work. The list of changes necessary to updated the scripts is described here.","category":"page"},{"location":"#Help!","page":"Introduction","title":"Help!","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Please ask for help if having any difficulty using the package. Reach us by:","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Asking a question on the Julia Discourse forum. Please mark @lmiq on your post, otherwise we may miss it! This may be very effective to get help from many Julia users on questions not directly related to physical-chemistry.\nOpening an issue if you think you found a problem in the package. Even documentation problems can be reported.\nJoining us at Zulip-chat in the m3g stream of the Julia Zulip forum.\nSending an e-mail to: lmartine@unicamp.br.","category":"page"},{"location":"#Features","page":"Introduction","title":"Features","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Check out our examples, 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":"#1.-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":"#2.-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 cosolvents, 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":"Please cite the following articles if the package was useful to you:","category":"page"},{"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. 347, 117945, 2022. [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":"V. Piccoli, L. Martínez, Competitive Effects of Anions on Protein Solvation by Aqueous Ionic Liquids. J. Phys. Chem. B 2024. [Full Text]\nA. F. Pereira, L. Martínez, Helical Content Correlations and Hydration Structures of the Folding Ensemble of the B Domain of Protein A. J. Chem. Inf. Model. 64, 3350-3359, 2024. [Full Text]\nA. 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/v2.7.2/selection/index.html b/v2.7.2/selection/index.html index 3ce6f173..e8f73fa0 100644 --- a/v2.7.2/selection/index.html +++ b/v2.7.2/selection/index.html @@ -59,7 +59,7 @@ julia> result = mddf(trajectory, Options(bulk_range=(8.0, 12.0))); -julia> acidic_residue_contributions = contributions(result, SoluteGroup("acidic residues"))

    Reference functions

    ComplexMixtures.AtomSelectionType
    struct AtomSelection

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

    • nmols::Int64

    • natomspermol::Int64

    • indices::Vector{Int64}

    • custom_groups::Bool

    • group_atom_indices::Vector{Vector{Int64}}

    • group_names::Vector{String}

    source
    ComplexMixtures.AtomSelectionMethod

    AtomSelection constructors

    The AtomSelection structure carries the information of the molecules that are going to be used to compute the MDDF. The structure can be initialized in different ways:

    1. Initialize the structure providing a vector of PDBTools.Atom(s).
        AtomSelection(
    +julia> acidic_residue_contributions = contributions(result, SoluteGroup("acidic residues"))

    Reference functions

    ComplexMixtures.AtomSelectionType
    struct AtomSelection

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

    • nmols::Int64

    • natomspermol::Int64

    • indices::Vector{Int64}

    • custom_groups::Bool

    • group_atom_indices::Vector{Vector{Int64}}

    • group_names::Vector{String}

    source
    ComplexMixtures.AtomSelectionMethod

    AtomSelection constructors

    The AtomSelection structure carries the information of the molecules that are going to be used to compute the MDDF. The structure can be initialized in different ways:

    1. Initialize the structure providing a vector of PDBTools.Atom(s).
        AtomSelection(
             atoms::AbstractVector{<:PDBTools.Atom}; 
             nmols::Int = 0, 
             natomspermol::Int = 0,
    @@ -108,7 +108,7 @@
     AtomSelection 
         3 atoms belonging to 3 molecule(s).
         Atoms per molecule: 1
    -    Number of groups: 2 
    source
    ComplexMixtures.SoluteGroupType

    SoluteGroup and SolventGroup data structures.

    These structures are used to select groups of atoms to extract their contributions from the MDDF results.

    Most tipically, the groups are defined from a selection of atoms with the PDBTools package, or by providing directly the indices of teh atoms in the structure.

    Alternativelly, if the groups were predefined, the groups can be selected by group index or group name.

    The possible constructors are:

    SoluteGroup(atoms::Vector{PDBTools.Atom})
    +    Number of groups: 2 
    source
    ComplexMixtures.SoluteGroupType

    SoluteGroup and SolventGroup data structures.

    These structures are used to select groups of atoms to extract their contributions from the MDDF results.

    Most tipically, the groups are defined from a selection of atoms with the PDBTools package, or by providing directly the indices of teh atoms in the structure.

    Alternativelly, if the groups were predefined, the groups can be selected by group index or group name.

    The possible constructors are:

    SoluteGroup(atoms::Vector{PDBTools.Atom})
     SoluteGroup(atom_indices::Vector{Int})
     SoluteGroup(atom_names::Vector{String})
     SoluteGroup(group_name::String)
    @@ -140,7 +140,7 @@
     julia> SoluteGroup(collect(eachresidue(atoms))[2]) # PDBTools.Residue(s)
     SoluteGroup defined by:
         atom_indices: [ 13, 14, ..., 22, 23 ] - 11 atoms
    -
    source
    ComplexMixtures.SolventGroupType

    SoluteGroup and SolventGroup data structures.

    These structures are used to select groups of atoms to extract their contributions from the MDDF results.

    Most tipically, the groups are defined from a selection of atoms with the PDBTools package, or by providing directly the indices of teh atoms in the structure.

    Alternativelly, if the groups were predefined, the groups can be selected by group index or group name.

    The possible constructors are:

    SoluteGroup(atoms::Vector{PDBTools.Atom})
    +
    source
    ComplexMixtures.SolventGroupType

    SoluteGroup and SolventGroup data structures.

    These structures are used to select groups of atoms to extract their contributions from the MDDF results.

    Most tipically, the groups are defined from a selection of atoms with the PDBTools package, or by providing directly the indices of teh atoms in the structure.

    Alternativelly, if the groups were predefined, the groups can be selected by group index or group name.

    The possible constructors are:

    SoluteGroup(atoms::Vector{PDBTools.Atom})
     SoluteGroup(atom_indices::Vector{Int})
     SoluteGroup(atom_names::Vector{String})
     SoluteGroup(group_name::String)
    @@ -172,7 +172,7 @@
     julia> SoluteGroup(collect(eachresidue(atoms))[2]) # PDBTools.Residue(s)
     SoluteGroup defined by:
         atom_indices: [ 13, 14, ..., 22, 23 ] - 11 atoms
    -
    source
    ComplexMixtures.atom_groupMethod
    atom_group(atsel::AtomSelection, i::Int)
     atom_group(atsel::AtomSelection, groupname::String)
     
     atom_group(atsel::AtomSelection, i::Int)
    @@ -194,7 +194,7 @@
      3
     
     julia> atom_group_name(atsel, 1)
    -"G1"
    source
    ComplexMixtures.atom_group_nameMethod
    atom_group_name(atsel::AtomSelection, i::Int)
     atom_group_names(atsel::AtomSelection)

    Return the name of the group of atoms with index i. The atom_group_names function returns a vector with the names of all the groups.

    Example

    julia> using ComplexMixtures
     
     julia> atsel = AtomSelection([1,2,3], natomspermol=1, group_atom_indices=[[1,2],[3]], group_names=["G1", "G2"])
    @@ -209,7 +209,7 @@
     julia> atom_group_names(atsel)
     2-element Vector{String}:
      "G1"
    - "G2"
    source
    ComplexMixtures.atom_group_namesMethod
    atom_group_name(atsel::AtomSelection, i::Int)
     atom_group_names(atsel::AtomSelection)

    Return the name of the group of atoms with index i. The atom_group_names function returns a vector with the names of all the groups.

    Example

    julia> using ComplexMixtures
     
     julia> atsel = AtomSelection([1,2,3], natomspermol=1, group_atom_indices=[[1,2],[3]], group_names=["G1", "G2"])
    @@ -224,4 +224,4 @@
     julia> atom_group_names(atsel)
     2-element Vector{String}:
      "G1"
    - "G2"
    source
    + "G2"source diff --git a/v2.7.2/tools/index.html b/v2.7.2/tools/index.html index d8ede2b1..b1af729b 100644 --- a/v2.7.2/tools/index.html +++ b/v2.7.2/tools/index.html @@ -40,7 +40,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

    2D density map per residue

    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:

    +residue50_coordination[findlast(<(5), R.d)]source

    2D density map per residue

    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:

    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, coordination numbers or minimum-distance counts.

    Compat

    All features described in this section are only available in v2.7.0 or greater.

    The computation of the contributions of each residue can be performed with the convenience function ResidueContributions, which creates an object containing the contributions of the residues to the mddf (or coordination numbers, or minimum-distance counts), the residue names, and distances:

    ComplexMixtures.ResidueContributionsType
    ResidueContributions (data structure)

    Constructor function:

    ResidueContributions(
         results::Result, atoms::AbstractVector{PDBTools.Atom};
    @@ -87,7 +87,7 @@
     rc2 = ResidueContributions(result2, select(atoms, "protein"))
     # difference of the residue contributions between the two simulations:
     rc_diff = rc2 - rc1
    -contourf(rc_diff) # plots a contour map of the difference
    Compat

    Slicing, indexing, and multiplication and divison by scalars were introduces in v2.7.0.

    source

    The output of ResidueContributions is by default shown as a simple unicode plot:

    +contourf(rc_diff) # plots a contour map of the difference
    Compat

    Slicing, indexing, and multiplication and divison by scalars were introduces in v2.7.0.

    source

    The output of ResidueContributions is by default shown as a simple unicode plot:

    The ResidueContribution object can be used to produce a high-quality contour plot using the Plots.contourf function:

    Plots.contourfMethod
    contourf(
         rc::ResidueContributions; 
    @@ -103,7 +103,7 @@
     
     julia> rc = ResidueContributions(results, atoms; oneletter=true)
     
    -julia> plt = contourf(rc; step=5)

    This will produce a plot with the contribution of each residue to the solute-solvent pair distribution function, as a contour plot, with the residues in the x-axis and the distance in the y-axis.

    To customize the plot, use the Plot.contourf keyword parameters, for example:

    julia> plt = contourf(rc; step=5, size=(800,400), title="Title", clims=(-0.1, 0.1))
    Compat

    This function requires loading the Plots package and is available in ComplexMixtures v2.5.0 or greater.

    Support for all Plots.contourf parameters was introduced in ComplexMixtures v2.6.0.

    source

    A complete example of its usage can be seen here.

    The ResidueContributions object can be indexes and sliced, for the analysis of the contributions of specific residues or range of residues:

    rc = ResidueContributions(results1, select(atoms, "protein")); 
    +julia> plt = contourf(rc; step=5)

    This will produce a plot with the contribution of each residue to the solute-solvent pair distribution function, as a contour plot, with the residues in the x-axis and the distance in the y-axis.

    To customize the plot, use the Plot.contourf keyword parameters, for example:

    julia> plt = contourf(rc; step=5, size=(800,400), title="Title", clims=(-0.1, 0.1))
    Compat

    This function requires loading the Plots package and is available in ComplexMixtures v2.5.0 or greater.

    Support for all Plots.contourf parameters was introduced in ComplexMixtures v2.6.0.

    source

    A complete example of its usage can be seen here.

    The ResidueContributions object can be indexes and sliced, for the analysis of the contributions of specific residues or range of residues:

    rc = ResidueContributions(results1, select(atoms, "protein")); 
     rc_7 = rc[7] # contributions of residue 7
     rc_range = rc[20:50] # contributions of a range of residues

    Slicing will return a new ResidueContributions object.

    Additionally, these ResidueContributions objects can be subtracted, divided, summed, or multiplied, to compare contributions of residues among different simulations. Typically, if one wants to compare the solvation of residues in two different simulations, one can do:

    # first simulation (for example, low temperature)
     rc1 = ResidueContributions(results1, select(atoms, "protein")); 
    @@ -133,11 +133,11 @@
     
     julia> R = ComplexMixtures.load("./results.json");
     
    -julia> grid = grid3D(R, atoms, "grid.pdb");

    Examples of how the grid can be visualized are provided in the user guide of ComplexMixtures.

    source

    The call to grid3D 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 where:

    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.

    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.

    +julia> grid = grid3D(R, atoms, "grid.pdb");

    Examples of how the grid can be visualized are provided in the user guide of ComplexMixtures.

    source

    The call to grid3D 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 where:

    • The positions of 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.
    • The occupancy field contains the distance itself.

    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.

    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.

    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.

    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.

    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.

    Computing radial distribution functions

    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.

    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:

    g, kb = ComplexMixtures.gr(R)

    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:

    g, kb = ComplexMixtures.gr(r,count,density,binstep)

    where:

    ParameterDefinitionResult structure output data to provide
    rVector of distancesThe d vector
    countNumber of site counts at each rThe rdf or mddf vectors
    densityBulk densityThe density.solvent_bulk or density.solvent densities.
    binstepThe histogram stepThe options.binstep

    Example:

    ...
     R = mddf(trajectory, options)
    -g, kb = ComplexMixtures.gr(R.d,R.rdf_count,R.density.solvent_bulk,R.options.binstep)
    ComplexMixtures.grMethod
    gr(R::Result) = gr(R.d,R.rdf_count,R.density.solvent_bulk,R.files[1].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

    Overview of the solvent and solute properties

    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:

    ...
    +g, kb = ComplexMixtures.gr(R.d,R.rdf_count,R.density.solvent_bulk,R.options.binstep)
    ComplexMixtures.grMethod
    gr(R::Result) = gr(R.d,R.rdf_count,R.density.solvent_bulk,R.files[1].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

    Overview of the solvent and solute properties

    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:

    ...
     
     julia> results = mddf(trajectory, Options(bulk_range=(8.0, 12.0)))
     
    @@ -192,4 +192,4 @@
     
     julia> atoms = readPDB("system.pdb", "protein")
     
    -julia> plt = contourf_per_residue(results, atoms; oneletter=true)

    This will produce a plot with the contribution of each residue to the solute-solvent pair distribution function, as a contour plot, with the residues in the x-axis and the distance in the y-axis.

    The resulting plot can customized using the standard mutating plot! function, for example,

    julia> plot!(plt, size=(800, 400), title="Contribution per residue")
    Compat

    This function requires loading the Plots package and is available in ComplexMixtures v2.2.0 or greater.

    The type and clims arguments, and the support for a step in xticks_range were introduced in ComplexMixtures v2.3.0.

    source
    +julia> plt = contourf_per_residue(results, atoms; oneletter=true)

    This will produce a plot with the contribution of each residue to the solute-solvent pair distribution function, as a contour plot, with the residues in the x-axis and the distance in the y-axis.

    The resulting plot can customized using the standard mutating plot! function, for example,

    julia> plot!(plt, size=(800, 400), title="Contribution per residue")
    Compat

    This function requires loading the Plots package and is available in ComplexMixtures v2.2.0 or greater.

    The type and clims arguments, and the support for a step in xticks_range were introduced in ComplexMixtures v2.3.0.

    source
    diff --git a/v2.7.2/trajectory/index.html b/v2.7.2/trajectory/index.html index 4f4b5545..a3fd21b0 100644 --- a/v2.7.2/trajectory/index.html +++ b/v2.7.2/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 AtomSelection 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")

    Reference functions

    ComplexMixtures.TrajectoryType
    Trajectory(filename::String, solute::AtomSelection, solvent::AtomSelection; 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
    +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 AtomSelection 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")

    Reference functions

    ComplexMixtures.TrajectoryType
    Trajectory(filename::String, solute::AtomSelection, solvent::AtomSelection; 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
    diff --git a/v2.7.2/updating_scripts/index.html b/v2.7.2/updating_scripts/index.html index d6dfd310..2bdb46bf 100644 --- a/v2.7.2/updating_scripts/index.html +++ b/v2.7.2/updating_scripts/index.html @@ -1,3 +1,3 @@ Updating scripts · ComplexMixtures.jl

    Updating scripts from v1 to v2

    The syntax chances necessary to update script from version 1.X to 2.X of the package are:

    Atom selections

    The previous Selection structure was renamed to AtomSelection for clarity.

    • Before:
    water = Selection(water; natomspermol=3)
    • Now:
    water = AtomSelection(water; natomspermol=3)

    Group contributions syntax

    The syntax to computing group contributions is improved. Previously, the contrib or contributions functions required three somewhat redundant parameters.

    • Before:

    The call to contributions required 3 parameters: the Selection structure, the matrix of contributions, and the indexes of the atoms for which the contributions were desired:

    h_contributions = contributions(solvent, R.solvent_atom, h_indexes)
    • Now:

    The contributions are extracted from the Result data structure, by providing either a SoluteGroup or SolventGroup object, which are setup with the group names, group indexes, atom names, or atom indexes:

    h_contributions = contributions(R, SolventGroup(h_indexes))

    Frame weights

    frame_weights is now an option of the mddf execution. That is previously, they were defined in the Options data structure, and now they are passed to the mddf function.

    • Before:
    options = Options(frame_weights=[1.0, 2.0], bulk_range=(8.0, 12.0))
    -results = mddf(trajectory, options)
    • Now:
    results = mddf(trajectory, options; frame_weights=[1.0, 2.0])
    +results = mddf(trajectory, options)
    • Now:
    results = mddf(trajectory, options; frame_weights=[1.0, 2.0])