diff --git a/doc/moltemplate_manual.pdf b/doc/moltemplate_manual.pdf index ac15b1c8..4d698efd 100644 Binary files a/doc/moltemplate_manual.pdf and b/doc/moltemplate_manual.pdf differ diff --git a/doc/moltemplate_manual_src/moltemplate_manual.tex b/doc/moltemplate_manual_src/moltemplate_manual.tex index ad2c2511..e7cd01f8 100644 --- a/doc/moltemplate_manual_src/moltemplate_manual.tex +++ b/doc/moltemplate_manual_src/moltemplate_manual.tex @@ -97,7 +97,7 @@ \subsection*{\textit{All-atom simulations}} type descriptions in that file, the one which most closely matches that atom. (Its partial charge may also need to be adjusted.) %Moltemplate comes with examples of simple molecules built this way. -This is not difficult for simple organic molecules like polyethelene or benzene, +This is not difficult for simple organic molecules like polyethylene or benzene, but it is not trivial for complex molecules like proteins and many ligands. Unlike other molecule builders, moltemplate does not infer atom types @@ -881,7 +881,7 @@ \subsection{Moltemplate commands} \\ \hline \textbf{replace} \{ \textit{oldvariable} \textit{newvariable} \} & -Allow alternate names for the same variable. This replaces all instances of \textit{oldvariable} with \textit{newvariable}. Both variable names must have a ``@'' prefix. This is typically used to reduce the length of long variables, for example to allow the shorthand ``@atom:C2'' to refer to ``@atom:C2\_bC2\_aC\_dC\_iC'' +Allow alternate names for the same variable. This replaces all instances of \textit{oldvariable} with \textit{newvariable}. Both variable names must have a ``@'' prefix. This is typically used to reduce the length of long variables, for example to allow the shorthand ``@atom:C2'' to refer to ``@atom:C2\_bC2\_aC\_dC\_iC'' (See section \ref{sec:replace_command}.) \\ \hline \textbf{\#}\textit{commented text} & @@ -1339,7 +1339,7 @@ \subsection{moltemplate.sh command line arguments:} \hline -molc & Helpful additional post-processing for users of the \textbf{MOLC} -coarse-grained model. +coarse-grained model \\ \hline \begin{tabular}[t]{l} @@ -2478,20 +2478,38 @@ \subsubsection*{Building a simple polymer} %specific to the atom types in different monomers.} +\section{Force Fields} +\label{sec:force_fields} + +This is a short chapter describing the features of the +moltemplate language that enable users to create and store their own +custom force-fields in LT format. + +This is not a tutorial explaining how to use popular all-atom force-fields +(like OPLSAA or GAFF2) in your simulation. +\textit{(Perhaps later, I will add more information on this worthy topic. +For now, the best way to learn to build realistic all-atom +simulations is to download moltemplate and its examples. +Then modify an example which is similar to what you want to simulate.)} + %(More examples are welcome. Users are encouraged to submit of molecules + % they created for inclusion with moltemplate.) + + \subsection{Bonded interactions \textit{by type}} \label{sec:nbody_by_type_intro} -In this example we did \textit{not} provide a list of all 3-body -and 4-body angle forces between bonded atoms in the polymer. -Moltemplate allows you to manually list all of these interactions -(using the ``write\_once("Data Angles")'' command -from section \ref{sec:spce_example}, -\textit{or} -the ``write\_once("Data Dihedrals")'', -or ``write\_once("Data Impropers")'' commands). -However there are usually many of them. -For this reason, it is often more convenient to provide -moltemplate with instructions to help it automatically figure out +In the polymer example in the previous chapter, +we did \textit{not} provide a list of all the +angle, dihedral, and improper forces acting on the atoms in the polymer. + %Moltemplate allows you to manually list all of these interactions + %(using the ``write("Data Angles")'' command + %from section \ref{sec:spce_example}, + %\textit{or} + %the ``write("Data Dihedrals")'', + %or ``write("Data Impropers")'' commands). +We \textit{could} have listed them, however there are usually many of them. +It is often more convenient to provide +moltemplate with instructions to help it automatically determine which atoms participate in 3-body and 4-body angle interactions, and what force field parameters to assign to them. We will do that below using the following commands: @@ -2502,15 +2520,18 @@ \subsection{Bonded interactions \textit{by type}} %Moltemplate can detect consecutively bonded atoms and %determine the forces between them based on atom type (and bond type). -Furthermoree, since many different kinds molecules often share +Furthermore, since many different kinds molecules often share the same rules for creating 3-body and 4-body angle interactions, it is convenient to organize all of this information -together into one place (eg an object named ``ForceField''). -A ``ForceField'' object will typically include many -``write\_once("Data Angles By Type")'' -commands, as well as force field parameters and related atom type properties. -We also typically store that information in a separate file -(eg ``forcefield.lt'', ``oplsaa.lt'', ``gaff2.lt'', ``compass.lt'', etc...). +together into one place (for example, an object named ``ForceField''). +A ``ForceField'' object will typically include a long list of +``write\_once("Data Angles/Dihedrals/Impropers By Type")'' +commands, +as well as force field parameters and related atom type properties. +It's also a good idea to store force-field objects in a separate file +(eg ``forcefield.lt'', ``oplsaa.lt'', ``gaff2.lt'', ``compass.lt'', etc...) +so that these rules and parameters can be be applied to different molecules +more easily (by using the \textit{import} command to load the file when needed). \begin{verbatim} # -- file "forcefield.lt" -- @@ -2548,7 +2569,7 @@ \subsection{Bonded interactions \textit{by type}} # By convention, in this file we keep track of all of the possible # interactions which could exist between these atoms: - # Rules for determining 3-body (angle) interactions by atom & bond type: + # Rules for determining 3-body (angle) interactions by atom and bond type: # angle-type atomType1 atomType2 atomType3 bondType1 bondType2 write_once("Data Angles By Type") { @@ -2566,15 +2587,16 @@ \subsection{Bonded interactions \textit{by type}} angle_coeff @angle:Sidechain 30.00 132 } - # 4-body interactions in this example are listed by atomType - # Rules for determining 4-body (dihedral) interactions by atom & bond type: + # 4-body interactions in this example are listed by atom type and (optionally) + # by bond type. (You can use wildcards * to accept all bond types.) + # + # dihedralType atmType1 atmType2 atmType3 atmType4 bondType1 bType2 bType3 write_once("Data Dihedrals By Type") { - # dihedralType atmType1 atmType2 atmType3 atmType4 bondType1 bType2 bType3 @dihedral:CCCC @atom:CA @atom:CA @atom:CA @atom:CA @bond:* @bond:* @bond:* @dihedral:RCCR @atom:R @atom:CA @atom:CA @atom:R @bond:* @bond:* @bond:* } - # The forumula used is: + # The forumula used in this example is: # # Udihedral(phi) = K * (1 + cos(n*phi - d)) # @@ -2603,7 +2625,7 @@ \subsection{Bonded interactions \textit{by type}} Any molecule that wants to access this information can use the ``inherits ForceField'' keyword. \textit{(...as we did in the ``monomer.lt'' and ``polymer.lt'' files in theexample above. - Note: the ``import forcefield'' statement was also necessary because the + Note: the ``import forcefield.lt'' statement was also necessary because the information is located in a separate file: ``forcefield.lt''.} %\textit{(Note: You can also generate \textbf{improper} interactions % %between any 4-atoms bonded together in a T-shaped topology @@ -2613,6 +2635,248 @@ \subsection{Bonded interactions \textit{by type}} by altering the bond topology search rules and atom type symmetry. See appendix \ref{sec:nbody_by_type_custom} for details.)} + +\subsection{Wildcards} +Star (*) and question mark (?) characters are multi and single-character +wildcards. +They can appear in any of the +``pair\_coeff'', ``bond\_coeff'', ``angle\_coeff'', +``dihedral\_coeff'', or ``improper\_coeff'' commands. +For example, the following excerpt tells moltemplate to assign nonbonded +pair parameters ``0.10 2.0'' to \textit{all} pairs of atoms whose +atom type strings begin with the letter ``C'' +\begin{verbatim} +write_once("In Settings") { + pair_coeff @atom:C* @atom:C* 0.10 2.0 +} +\end{verbatim} +Wildcards can also appear in any of the @atom or @bond type names +in the ``By Type'' sections. +The following rule will generate a dihedral angle interaction +(of type ``@angle:CCR'') between any triplet of atoms if the last +atom's type name ends with ``R''. +\begin{verbatim} +write_once("Data Angles By Type") { + @angle:CCR @atom:* @atom:* @atom:*R +} +\end{verbatim} +In this way, a small number of these rules can describe +a large number of atom type combinations. +Force fields like OPLSAA and COMPASS use this strategy to reduce the size +of the entries in the ``Angles By Type'' section (and elsewhere). +Note that rules with wildcards typically appear near the beginning of the +``Data Angles By Type'' section (and other ``By Type'' sections). +Rules describing angles between specific atom type combinations +should appear later in the list so that they can override the +more general rules containing wildcards that appeared earlier. + +\textit{(Note: Regex based atom-type-name matching +has been implemented, but this feature has not yet been tested. +See section \ref{sec:regex}. -Andrew 2020-8-09)} + + +\subsection{``Data Bonds By Type'' and ``Data Bond List''} +It is also possible to determine \textit{bond type} from \textit{atom type}, +by specifying a ``Data Bonds By Type'' section: +\begin{verbatim} +write_once("Data Bonds By Type") { + @bond:Backbone @atom:CA @atom:CA + @bond:Sidechain @atom:CA @atom:R +} +\end{verbatim} +We can also put this information in the ``ForceField'' object. Later, in the +``Monomer'' and ``Polymer'' objects, we can omit the @bond types. +For example, we could replace the ``Data Bonds'' section in the ``Polymer'' +with a ``Data Bond List'' section: +\begin{verbatim} +write_once("Data Bond List") { + $bond:backbone1 $atom:mon1/ca $atom:mon2/ca + $bond:backbone2 $atom:mon2/ca $atom:mon3/ca + : : : +} +\end{verbatim} +Notice that we did not specify the ``@bond:SideChain'' and ``@bond:Backbone'' +bond type information which would normally appear in the 2nd column +of the ``Data Bonds'' section. While not very useful in this example, +many all-atom force fields (eg. OPLSAA, GAFF, COMPASS) assign bond types +by atom type. For this reason, molecules that use these force fields +typically contain a ``Data Bond List'' section, instead of a +``Data Bonds'' section. + + + +\subsection{The \textit{replace} command} +\label{sec:replace_command} + +The ``replace'' command is useful for people who want to publish their own +custom force fields in moltemplate (LT) format. +This command is typically used to simplify the names of atom types +in modern force fields. In some force fields (eg, COMPASS, OPLSAA), +atom type names are complicated by the the way they are used to +lookup force field parameters. @atom type names can be quite long +and difficult to type (such as ``@atom:h1h\_ph1h\_bh1h\_ah1\_dh1\_ih1''). + %Note that some force fields (like COMPASS) are currently implemented using + %very long atom names which could be difficult for users to type correctly + %(such as ``@atom:h1h\_ph1h\_bh1h\_ah1\_dh1\_ih1''). +The ``replace'' command allows \textit{the people who use your force field} to +refer to these atoms in their molecules with short names instead of long ones. +Consider the following example: +\begin{verbatim} +replace{ @atom:C4 @atom:C4_aC4 } +replace{ @atom:H1 @atom:H1_aH1 } +replace{ @atom:C4o @atom:C4o_aC4 } +replace{ @atom:H1o @atom:H1o_aH1 } +\end{verbatim} +In this example, ``@atom:C4'' and ``@atom:H1'' are shorthand +referring to ``@atom:C4\_aC4'' and ``@atom:H1\_aH1'', respectively. +\textit{(The ``replace'' command works with all @-style variables, not + just @atom type names. It does not work with \$-style variables.)} + +These longer atom names are often used in combination with ``By Type'' rules +for generating angle and dihedral interactions. For example, consider a force +field which uses the following rules for generating angle interactions: +\begin{verbatim} +write_once("Data Angles By Type") { + @angle:HCH @atom:*_ah1 @atom:*_ac4 @atom:*_ah1 + @angle:CCH @atom:*_ac4 @atom:*_ac4 @atom:*_ah1 +} +\end{verbatim} +Through the use of wildcard characters (*), these two rules only depend +on the portion of the atom type name following the ``\_a'' character +(``h1'', or ``c4''). Since multiple atom types share the same ``h1'' and ``c4'' +name suffixes, this significantly reduces the number of ``Angles By Type'' +rules needed for the carbon and hydrogen atoms in this example. (And this +reduction becomes even more dramatic as the number of atom types increases.) + +The ``replace'' command is useful because it allows users to refer to these +long atoms by their short names (``@atom:C4'' and ``@atom:H1'') +when creating molecules. For example: +\begin{verbatim} +# atom-id mol-id atom-type charge x y z +write("Data Atoms") { + $atom:c $mol:. @atom:C4 -0.18 0.0000 0.0000 0.0000 + $atom:h1 $mol:. @atom:H1 0.06 0.0000 0.6310 0.8924 + $atom:h2 $mol:. @atom:H1 0.06 0.0000 0.6310 -0.8924 + $atom:h3 $mol:. @atom:H1 0.06 -0.8924 -0.6310 0.0000 + : : : +} +\end{verbatim} + + + + + +\subsection{``In Charges''} +\label{sec:in_charges} +Recall that moltemplate was designed for simulating coarse grained molecular +models. It's not uncommon for coarse grained models to use big particles +containing many atoms, whole proteins, or even larger complexes. It often +does not make sense to assign charge to particles in this size range, and +moltemplate does not force you to use a charge-bearing particle representation. +But if you want to assign charges to particles, there are several ways to do +that. + +Modern molecule-builder tools typically assign partial charges to atoms +using sophisticated ab initio physics-based calculations. +Moltemplate does not do this. +However moltemplate does supports several optional methods +allowing you to assign particle charge according to atom type (@atom). + %Some force fields (such as the current implementation of OPLSAA and LOPLSAA) + %assign atom charge according to atom type. +For example, here is an excerpt +from the ``loplsaa.lt'' file (on 2020-8-09): +\begin{verbatim} +write_once("In Charges") { + set type @atom:80L charge -0.222 # "Alkane CH3- (LOPLS)" + set type @atom:81L charge -0.148 # "Alkane -CH2- (LOPLS)" + : +} +\end{verbatim} +This will set the charge of \textit{all} atoms of type ``@atom:80L'' to -0.222, +(regardless of who they are bonded to). + +Confusingly, the charge information is \textbf{not} written to the DATA +file created by moltemplate.sh. Instead the charges are written to a +file whose name ends in ``.in.charges'' (eg. ``system.in.charges''). +Later when you run LAMMPS, you must remember to use the LAMMPS ``include'' +command to load this file after you read the data file. For example: +\begin{verbatim} +read_data "system.data" +include "system.in.charges" +\end{verbatim} + +Note that any charge information specified in the ``Data Atoms'' section +of your molecule (which ends up in ``system.data'') will be ignored. +If you want to customize the charge of individual atoms in your molecule, +add an ``In Charges'' section to the \textit{end} of your molecule definition. +For the carbon atoms in an alkane polymer (for example), +you might use something like this: +\begin{verbatim} +write("In Charges") { + set atom $atom:monomer[0]/c charge -0.222 + set atom $atom:monomer[1]/c charge -0.148 + : +} +\end{verbatim} +\textit{(For reference, the LAMMPS' ``set'' command is explained here: + \url{https://lammps.sandia.gov/doc/set.html}.)} + + + + + + + +\subsection{``Data Charge By Bond''} +\label{sec:charge_by_bond} + +The ``Data Charge by Bond'' section allows partial charges can be assigned +to atoms according to the other atoms they are bonded to and their types. +Here is a (slightly modified) excerpt from the ``compass\_published.lt'' file: +\begin{verbatim} +write_once("Data Bonds By Type") { + @atom:h1 @atom:si4 -0.1260 0.1260 + @atom:*bc4* @atom:*bsi4* -0.1350 0.1350 +} +\end{verbatim} +Each bond between atoms contributes to the partial charge of those atoms. +The first line tells moltemplate that any bond between atoms of type +``@atom:h1'' and ``@atom:si4'' modifies their charge by +-0.1260 and 0.1260, respectively. +The wildcard characters (``*'') in the second line cause moltemplate to modify +the partial charges of any bonded pair of atoms by -/+0.1350 if the first atom +type contains the string ``bc4'' and the second atom type contains the string +``bsi4''. +The final charge of each atom is determined by adding the contribution to its +charge from each of the atoms it is bonded to. + +Again, these charges will not be written to your DATA file. As explained above, +after you load the DATA file, you must remember to use the LAMMPS ``include'' +command to load the file containing the charge information. +(For example: ``include system.in.charges''.) +Again, if you need to, you can customize the +charge of individual atoms in your molecule by placing an +``write("In Charges")'' section at the \textit{end} of your molecule definition +(as shown above). + + +\subsection{The \textit{force\_fields} directory} +\label{sec:moltemplate_path} +Files containing popular force fields (like ``oplsaa.lt'' and ``gaff2.lt'') +and molecule models (like ``spce.lt'') are stored in the ``force\_fields/'' +subdirectory distributed with moltemplate. (This directory is included when +you download moltemplate using either git or pip.) +You can load the contents of any of these files using the \textit{import} +statement. They do not need to be located in your local directory. +You can add your own LT files there as well. This is a convenient +way for many different examples to share the same force fields. +If a shell environment variable named ``TTREE\_PATH'' is defined, +the directories listed there (delimited by ``:'') are also searched. +\textit{(Note: If a file you want to import can be found in multipl locations, +the file in your local directory has priority.)} + + + %\subsubsection*{\textit{(Advanced)} Order matters when sets overlap} %Bonded-interactions are generated in the order they appear in the LT file. %Interactions which are declared later may override the settings of @@ -2647,6 +2911,8 @@ \subsection{Bonded interactions \textit{by type}} %\end{verbatim} + + \section{Arrays, slices, and coordinate transformations} \label{sec:arrays} Moltemplate supports 1-dimensional, and multi-dimensional arrays. @@ -4478,7 +4744,8 @@ \section{Bonded interactions ``By Type''} Note: The 2nd and 3rd lines in this example will generate new interactions which may override any angle interactions assigned earlier. -\subsection*{Regular expressions} +\subsection{Regular expressions} +\label{sec:regex} Regular-expressions can also be used to match potential atom and bond types. To use regular expressions, the first 3 characters following ``:'' should be ``re.'', and the variable name should be enclosed in curly brackets, \{\}. @@ -6202,7 +6469,132 @@ \subsection{Custom bond topologies} -\section{Variable syntax details} + +\section{Moltemplate Grammar} +\label{sec:grammar} + +Moltemplate.sh is a script which invokes a python program program (\textit{ttree.py}) to parse and interpret the moltemplate language. An overview of the grammar of that language is provided below. The grammer shown here is not comprehensive. The syntax of some lesser-used language features (such as varialble shortcuts, and paths containing ``../'' and ``...'') is omitted here +(but discussed later in appendix \ref{sec:adv_variable_syntax}). + +Note that the current language parser (\textit{ttree.py}) was written by hand. (It was not generated by a compiler-compiler.) So it is unfortunately possible that some valid inputs may exist which satisfy the rules of the grammar and yet cause moltemplate to return an error message. However most moltemplate commands are short and simple. Several years of heavy usage have passed since I have received a report of this kind of error. + +\subsubsection*{Explanation of Terminals:} + +Terminals are the indivisible words and symbols in a language. +Terminals in the moltemplate language fall into several categories. + +\begin{verbatim} +Terminals ::= Integer | Number | String +\end{verbatim} + +\begin{itemize} +\item \textbf{Integer}: A nonnegative integer + +\item \textbf{Number}: A floating point number + +\item \textbf{String}: A string. (A sequence of characters.) +\end{itemize} + +Strings fall into several categories: + +\begin{verbatim} +String ::= InstanceName | ObjectTypeName | FileName | CategoryName | OtherStr +\end{verbatim} + +\begin{itemize} +\item \textbf{InstanceName}: is a string referring to one of the child nodes at the current level in the instance tree. Typically it is the unique name of one of the molecules you have instantiated, but it can also be the name of one of the atoms or bonded interactions within these molecules. + +\item \textbf{ObjectTypeName}: is a string that refers to the name of one of the child nodes at the current level in the static tree. That node typically refers to a type of molecule or a type of atom or bonded interaction, or an object containing force field information (like ``TraPPE'' or ``OPLSAA''). + +\item \textbf{CategoryName}: is a type of counter variable \textit{category}. Typical categories are ``@atom'', ``\$atom'', ``@bond'', ``\$bond'', ``@angle'', etc... However user-created categories are also possible using the "category" command. (See below.) In principle, each category is associated with a node in the static tree (@) or instance tree (\$) which limits the scope of the counter to children of that node. However in practice most categories (eg ``@atom'', ``\$bond'', ...) are associated with the root node (``/'') by default, and are thus global in scope. The syntax for creating custom categories and referring to them later is explained in appendix \ref{sec:custom_categories}. + +\item \textbf{FileName}: Strings refering to the names of files. + +\item \textbf{OtherStr}: Strings which do not fall into any of these categories +\end{itemize} + +See appendix \ref{sec:adv_variable_syntax} for details explaining the syntax of +\$ and @-style variables, including \textbf{CategoryNames} and node references. + + +\subsection*{Production Rules} + +Moltemplate LT files contain lists of commands. + +\begin{verbatim} +CommandList ::= "" | Command CommandList +\end{verbatim} + +...where + +\begin{verbatim} +Command ::= ObjectDef | InstanceCommand | DeleteCommand | WriteC | WriteOC | + ImportCommand | CategoryDef | InstanceMod | ObjectTypeMod | + ObjectDefMod | ReplaceCommand | UsingCommand | PushXform + +ObjectDef ::= ObjectTypeName ClassParents "{" CommandList "}" +ClassParents ::= "" | "inherits" ParentList +ParentList ::= StaticNode | StaticNode ParentList +StaticNode ::= ObjectTypeName | ObjectTypeName "/" StaticNode + +InstanceCommand ::= InstanceName "=" "new" InstanceExpr +InstanceExpr ::= InstanceName RangeNDX +RangeNDX ::= "" | RangeX RangeNDX +RangeX ::= "[" IntRange "]" Xforms +IntRange ::= Integer | Integer ":" Integer | "*" +Xforms ::= "" | Xform Xforms +Xform ::= MoveXform | RotXform | ScaleXform +MoveXform ::= ".move(" Number "," Number "," Number ")" +RotXform ::= ".rot(" Number "," Number "," Number "," Number ")" +ScaleXform ::= ".scale(" Number "," Number "," Number ")" +\end{verbatim} + + +\subsubsection*{\textit{Deleting or modifying existing instances}} + +\begin{verbatim} +InstanceMod ::= InstanceSelection XformsNE +DeleteCommand ::= "delete" InstanceSelection +InstanceSelection ::= InstanceNode RangeND +InstanceNode ::= InstanceName | InstanceNode "/" InstanceName +RangeND ::= "" | Range RangeND +Range ::= "[" IntRange "]" +XformsNE ::= Xform Xforms +\end{verbatim} + +\subsubsection*{\textit{Writing text containing counter variables}} +\begin{verbatim} +WriteC ::= "write(" FileName ")" "{" TemplateText "}" +TemplText ::= "" | String TemplText | StatVar TemplText | InstVar TemplText +InstVar ::= "$"CategoryName":"InstanceNode +StatVar ::= "@"CategoryName":"StaticNode + +WriteOC ::= "write_once(" FileName ")" "{" TemplateTextStat "}" +TemplTextStat ::= "" | String TemplTextStat | StatVar TemplTextStat +\end{verbatim} + +\subsubsection*{\textit{Miscellaneous}} + +\begin{verbatim} +ImportCommand ::= "import" FileName + +ReplaceCommand ::= "replace" { StatVar StatVar } + +CategoryCommand ::= CatCommandStat | CatCommandInst +CatCommandStat ::= "category" "@"CategoryName"(" Integer "," Integer ")" +CatCommandInst ::= "category" "$"CategoryName"(" Integer "," Integer ")" + +ObjectTypeMod ::= ObjectTypeName XformsNE +ObjectDefMod ::= ObjectTypeName "=" ObjectTypeName XformsNE + +UsingCommand ::= "using" "namespace" ObjectTypeName + +PushXform := "push(" XformsNE ")" CommandList "pop()" +\end{verbatim} + + + +\subsection{Counter variable syntax} \label{sec:adv_variable_syntax} Counter variables have names like: