Example #1
0
def energy_decomposition_system(structure,
                                system,
                                platform=None,
                                nrg=u.kilocalories_per_mole):
    """
    This function computes the energy contribution for all of the different
    force groups.

    Parameters
    ----------
    structure : Structure
        The Structure with the coordinates for this system
    system : mm.System
        The OpenMM System object to get decomposed energies from
    platform : str
        The platform to use. Options are None (default), 'CPU', 'Reference',
        'CUDA', and 'OpenCL'. None will pick default OpenMM platform for this
        installation and computer
    nrg : energy unit, optional
        The unit to convert all energies into. Default is kcal/mol

    Returns
    -------
    energies : list of tuple
        Each entry is a tuple with the name of the force followed by its
        contribution
    """
    import simtk.openmm as mm
    # First get all of the old force groups so we can restore them
    old_groups = [f.getForceGroup() for f in system.getForces()]
    old_recip_group = []

    def _ene(context, grp):
        st = context.getState(getEnergy=True, groups=1 << grp)
        return (type(system.getForce(grp)).__name__,
                st.getPotentialEnergy().value_in_unit(nrg))

    try:
        for i, f in enumerate(system.getForces()):
            if isinstance(f, mm.NonbondedForce):
                old_recip_group.append(f.getReciprocalSpaceForceGroup())
                f.setReciprocalSpaceForceGroup(i)
            f.setForceGroup(i)
        if platform is None:
            con = mm.Context(system, mm.VerletIntegrator(0.001))
        else:
            con = mm.Context(system, mm.VerletIntegrator(0.001),
                             mm.Platform.getPlatformByName(platform))
        con.setPositions(structure.positions)
        if structure.box is not None:
            con.setPeriodicBoxVectors(*structure.box_vectors)

        return list(map(lambda x: _ene(con, x), range(system.getNumForces())))
    finally:
        idx = 0
        for grp, force in zip(old_groups, system.getForces()):
            if isinstance(force, mm.NonbondedForce):
                force.setReciprocalSpaceForceGroup(old_recip_group[idx])
                idx += 1
            force.setForceGroup(grp)
Example #2
0
def energy_decomposition_system(structure, system, platform=None,
                                nrg=u.kilocalories_per_mole):
    """
    This function computes the energy contribution for all of the different
    force groups.

    Parameters
    ----------
    structure : Structure
        The Structure with the coordinates for this system
    system : mm.System
        The OpenMM System object to get decomposed energies from
    platform : str
        The platform to use. Options are None (default), 'CPU', 'Reference',
        'CUDA', and 'OpenCL'. None will pick default OpenMM platform for this
        installation and computer
    nrg : energy unit, optional
        The unit to convert all energies into. Default is kcal/mol

    Returns
    -------
    energies : list of tuple
        Each entry is a tuple with the name of the force followed by its
        contribution
    """
    import simtk.openmm as mm
    # First get all of the old force groups so we can restore them
    old_groups = [f.getForceGroup() for f in system.getForces()]
    old_recip_group = []
    def _ene(context, grp):
        st = context.getState(getEnergy=True, groups=1<<grp)
        return (type(system.getForce(grp)).__name__,
                st.getPotentialEnergy().value_in_unit(nrg))

    try:
        for i, f in enumerate(system.getForces()):
            if isinstance(f, mm.NonbondedForce):
                old_recip_group.append(f.getReciprocalSpaceForceGroup())
                f.setReciprocalSpaceForceGroup(i)
            f.setForceGroup(i)
        if platform is None:
            con = mm.Context(system, mm.VerletIntegrator(0.001))
        else:
            con = mm.Context(system, mm.VerletIntegrator(0.001),
                             mm.Platform.getPlatformByName(platform))
        con.setPositions(structure.positions)
        if structure.box is not None:
            con.setPeriodicBoxVectors(*structure.box_vectors)

        return list(map(lambda x: _ene(con, x), range(system.getNumForces())))
    finally:
        idx = 0
        for grp, force in zip(old_groups, system.getForces()):
            if isinstance(force, mm.NonbondedForce):
                force.setReciprocalSpaceForceGroup(old_recip_group[idx])
                idx += 1
            force.setForceGroup(grp)
Example #3
0
    def from_leaprc(cls, fname, search_oldff=False):
        """ Load a parameter set from a leaprc file

        Parameters
        ----------
        fname : str or file-like
            Name of the file or open file-object from which a leaprc-style file
            will be read

        search_oldff : bool, optional, default=False
            If True, search the oldff directories in the main Amber leap
            folders. Default is False

        Notes
        -----
        This does not read all parts of a leaprc file -- only those pertinent to
        defining force field information. For instance, the following sections
        and commands are processed:

        - addAtomTypes
        - loadAmberParams
        - loadOFF
        - loadMol2
        - loadMol3
        """
        params = cls()
        if isinstance(fname, string_types):
            f = genopen(fname, 'r')
            own_handle = True
        else:
            f = fname
            own_handle = False
        # To make parsing easier, and because leaprc files are usually quite
        # short, I'll read the whole file into memory
        def joinlines(lines):
            newlines = []
            composite = []
            for line in lines:
                if line.endswith('\\\n'):
                    composite.append(line[:-2])
                    continue
                else:
                    composite.append(line)
                newlines.append(''.join(composite))
                composite = []
            if composite:
                newlines.append(''.join(composite))
            return newlines
        lines = joinlines(map(lambda line:
                    line if '#' not in line else line[:line.index('#')], f))
        text = ''.join(lines)
        if own_handle: f.close()
        lowertext = text.lower() # commands are case-insensitive
        # Now process the parameter files
        def process_fname(fname):
            if fname[0] in ('"', "'"):
                fname = fname[1:-1]
            fname = fname.replace('_BSTOKEN_', r'\ ').replace(r'\ ', ' ')
            return fname
        for line in lines:
            line = line.replace(r'\ ', '_BSTOKEN_')
            if _loadparamsre.findall(line):
                fname = process_fname(_loadparamsre.findall(line)[0])
                params.load_parameters(_find_amber_file(fname, search_oldff))
            elif _loadoffre.findall(line):
                fname = process_fname(_loadoffre.findall(line)[0])
                params.residues.update(
                    AmberOFFLibrary.parse(_find_amber_file(fname, search_oldff))
                )
            elif _loadmol2re.findall(line):
                (resname, fname), = _loadmol2re.findall(line)
                residue = Mol2File.parse(_find_amber_file(fname, search_oldff))
                if isinstance(residue, ResidueTemplateContainer):
                    warnings.warn('Multi-residue mol2 files not supported by '
                                  'tleap. Loading anyway using names in mol2',
                                  AmberWarning)
                    for res in residue:
                        params.residues[res.name] = res
                else:
                    params.residues[resname] = residue
        # Now process the addAtomTypes
        try:
            idx = lowertext.index('addatomtypes')
        except ValueError:
            # Does not exist in this file
            atom_types_str = ''
        else:
            i = idx + len('addatomtypes')
            while i < len(text) and text[i] != '{':
                if text[i] not in '\r\n\t ':
                    raise ParameterError('Unsupported addAtomTypes syntax in '
                                         'leaprc file')
                i += 1
            if i == len(text):
                raise ParameterError('Unsupported addAtomTypes syntax in '
                                     'leaprc file')
            # We are at our first brace
            chars = []
            nopen = 1
            i += 1
            while i < len(text):
                char = text[i]
                if char == '{':
                    nopen += 1
                elif char == '}':
                    nopen -= 1
                    if nopen == 0: break
                elif char == '\n':
                    char = ' '
                chars.append(char)
                i += 1
            atom_types_str = ''.join(chars).strip()
        for _, name, symb, hyb in _atomtypere.findall(atom_types_str):
            if symb not in AtomicNum:
                raise ParameterError('%s is not a recognized element' % symb)
            if name in params.atom_types:
                params.atom_types[name].atomic_number = AtomicNum[symb]
        return params