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