The :mod:`parmed.charmm` package
===================================

The :mod:`charmm` package contains classes that can parse a variety of CHARMM
files, including PSF files, parameter files, and coordinate files.
Parameter files (PAR), stream files (STR), CHARMM coordinate files, and CHARMM
restart files.

It is beyond the scope of this site to discuss the details of these file
formats, so you are instead forwarded to `the CHARMM documentation
<http://www.charmm.org/documentation/c32b2/>`_.

The Protein Structure File (PSF)
--------------------------------

The PSF file is the heart of the CHARMM workflow, representing a molecular
system and its topology. It contains a list of all atoms with (most of) their
atomic properties, and then a list of the covalent bonds and valence bonded
terms (e.g., angles, torsions, improper torsions, and coupled-torsions). There
are a number of dialects of the PSF file, including that used by CHARMM, those
generated by `VMD's autopsf tool <http://www.ks.uiuc.edu/Research/vmd/>`_,
so-called *XPLOR* PSFs, etc.

The :class:`CharmmPsfFile` class is capable of parsing all PSF file formats that
I have encountered (excluding those with virtual sites and Drude particles,
currently).

.. currentmodule:: parmed.charmm
.. autosummary::
    :toctree: charmmobj/

    CharmmPsfFile

This class is a subclass of :class:`Structure <parmed.structure.Structure>`,
and as such contains the corresponding topology arrays :attr:`atoms
<CharmmPsfFile.atoms>`, :attr:`bonds <CharmmPsfFile.bonds>`, ... etc. An example
demonstrating the use of :class:`CharmmPsfFile` to parse ``dhfr_cmap_pbc.psf``
(a sample PSF file in the ParmEd unit test suite) is shown below::

    >>> psf = CharmmPsfFile('dhfr_cmap_pbc.psf')
    >>> len(psf.atoms)
    56057
    >>> len(psf.bonds)
    56091
    >>> len(psf.angles)
    22417
    >>> len(psf.impropers)
    418

CHARMM Parameter Sets
---------------------

CHARMM parameters are spread across three different types of files: *Residue
topology files* (RTF), *Parameter files* (PAR), and *stream files* (STR). A
:class:`CharmmParameterSet` (described briefly below) will build a parameter
database from collections of all three of these files.

.. currentmodule:: parmed.charmm
.. autosummary::
    :toctree: charmmobj/

    CharmmParameterSet

To instantiate a parameter set, you can pass a list of file names (any iterable
will suffice) to the :class:`CharmmParameterSet` constructor, and the format
will be determined from the file name itself. File type recognition follows the
rules summarized in the table below:

+-----------------+-------------------------------------------+
| Filename suffix | File type                                 |
+=================+===========================================+
| ``.rtf, .top``  | Residue topology file                     |
+-----------------+-------------------------------------------+
| ``.par, .prm``  | Parameter file                            |
+-----------------+-------------------------------------------+
| ``.str``        | Stream file                               |
+-----------------+-------------------------------------------+
| ``.inp``        | Parameter file if ``par`` is in the name, |
|                 | RTF if ``top`` is in the file name.       |
|                 | Otherwise ``ValueError`` is raised.       |
+-----------------+-------------------------------------------+

If your file name does not match one of the patterns above, you need to either
rename your file or use alternate ways to read in each file (see
:meth:`CharmmParameterSet.load_set` as well as the sections below).

An example is shown processing the sample CHARMM 22 force field files provided
in the ParmEd unit test files::

    >>> from parmed.charmm import CharmmParameterSet
    >>> params = CharmmParameterSet('par_all22_prot.inp', 'top_all22_prot.inp')
    >>> params.bond_types[('CE1', 'CE1')]
    <BondType; k=440.000, Req=1.340>
    >>> params.angle_types[('H', 'NH2', 'CT1')]
    <AngleType; k=50.000, THETAeq=1.937>
    >>> # Note that the reverse is an equivalent angle
    >>> params.angle_types[('CT1', 'NH2', 'H')]
    <AngleType; k=50.000, THETAeq=1.937>
    >>> params.improper_types[('CE1', 'CPB', 'X', 'X')]
    <ImproperType; k=90.000, PSIeq=0.000>

Notice that the dictionaries have keys matching all permutations of the atom
types defining a parameter. In the example above, the angle type keys ``('H',
'NH2', 'CT1')`` and ``('CT1', 'NH2', 'H')`` both point to the same
:class:`AngleType <parmed.topologyobjects.AngleType>`. In fact, they point to
the exact same *object*, so that if you modify that angle type, it is changed
for both keys::

    >>> params.angle_types[('CT1', 'NH2', 'H')].k = 60.0
    >>> params.angle_types[('CT1', 'NH2', 'H')]
    <AngleType; k=60.000, THETAeq=1.937>
    >>> params.angle_types[('H', 'NH2', 'CT1')]
    <AngleType; k=60.000, THETAeq=1.937>

Notice how the force constant has changed from 50 to 60 for *both* keys.

One thing I'll point out is that for older force fields (like CHARMM 22, for
instance), the various force field atom types (e.g., those for *prot*\ teins,
*carb*\ ohydrates, etc.) are incompatible with each other---you must pick *one*
pair of parameter and topology files and use that.

For the newer force fields, (e.g., CHARMM 36), you should load all of the
parameter files that are relevant for your system (e.g., both the lipid and
protein force fields, along with the water and ion stream file, for a lipid
bilayer with an embedded protein).

Residue Topology File (RTF)
~~~~~~~~~~~~~~~~~~~~~~~~~~~

The RTF file contains a library of residue templates (residue names, the atoms
within the residues, their connectivity, and a standard internal coordinate
representation of their orientation). It also describes various *patches* (i.e.,
small fragments meant to adorn or modify the more typical residues) that are
used to modify the residues. This information is *not* currently processed by
:class:`CharmmParameterSet`. The only information that the RTF file contains
that :class:`CharmmParameterSet` makes use of is the listing of atom types.

As of the CHARMM 36 parameter set, however, this information is now stored in
the parameter files, so the RTF files are not strictly required by the
:class:`CharmmParameterSet` for these newer force fields.

When they *are* required, however, they must be loaded into the
:class:`CharmmParameterSet` *before* the corresponding parameter file, since the
atom types need to be defined before they can be used.

To specifically load a topology file, use
:meth:`CharmmParameterSet.read_topology_file`. Note, this should only be
necessary when adding on to an existing parameter set or when the default name
recognition does not appropriately classify your file as an RTF.

Parameter File (PAR)
~~~~~~~~~~~~~~~~~~~~

The PAR file contains a database with all of the different parameter types
defined between specific atom type names. For newer force fields, they also
include the atom type name to type index mapping as well as atom masses.

To specifically load a parameter file, use
:meth:`CharmmParameterSet.read_parameter_file`.

Stream Files (STR)
~~~~~~~~~~~~~~~~~~

Stream files contain *extra* information and CHARMM directives. The CHARMM
directives are ignored, but any *rtf* or *par* sections will be read to augment
a parameter set with additional atom types and parameters.

To specifically load a stream file, use
:meth:`CharmmParameterSet.read_stream_file`.

Add to an existing parameter set
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you have an existing :class:`CharmmParameterSet` instance and want to read in
another parameter, topology, and/or stream file(s), you can use the
:meth:`CharmmParameterSet.load_set` as a shortcut for reading parameter, RTF,
and stream files separately.

CHARMM coordinate files
-----------------------

ParmEd provides classes to parse two kinds of CHARMM coordinate files---standard
coordinate files and restart files, summarized below.

.. currentmodule:: parmed.charmm
.. autosummary::
    :toctree: charmmobj/

    CharmmCrdFile
    CharmmRstFile

Both of these file types are read-only and can be instantiated directly via the
constructor. The coordinates (and for restarts, velocities, accelerations, and
old coordinates) are available as attributes to the objects.
