def __init__(self, filename=None, name=None, rtf=None, prm=None, netcharge=None, method=FFTypeMethod.CGenFF_2b6, qm=None, outdir="./", mol=None, acCharges=None): if filename is not None and not filename.endswith('.mol2'): raise ValueError('Input file must be mol2 format') if mol is None: super().__init__(filename=filename, name=name) else: for v in mol.__dict__: self.__dict__[v] = deepcopy(mol.__dict__[v]) # Guess bonds if len(self.bonds) == 0: logger.warning('No bonds found! Guessing them...') self.bonds = self._guessBonds() # Guess angles and dihedrals self.angles, self.dihedrals = guessAnglesAndDihedrals(self.bonds, cyclicdih=True) # Detect equivalent atoms equivalents = detectEquivalents(self) self._equivalent_atom_groups = equivalents[0] # List of groups of equivalent atoms self._equivalent_atoms = equivalents[1] # List of equivalent atoms, indexed by atom self._equivalent_group_by_atom = equivalents[2] # Mapping from atom index to equivalent atom group # Detect rotatable dihedrals self._rotatable_dihedrals = detectSoftDihedrals(self, equivalents) # Set total charge if netcharge is None: self.netcharge = int(round(np.sum(self.charge))) else: self.netcharge = int(round(netcharge)) # Canonicalise the names self._rename() # Assign atom types, charges, and initial parameters self.method = method if rtf and prm: # If the user has specified explicit RTF and PRM files go ahead and load those self._rtf = RTF(rtf) self._prm = PRM(prm) logger.info('Reading FF parameters from %s and %s' % (rtf, prm)) elif method == FFTypeMethod.NONE: pass # Don't assign any atom types else: # Otherwise make atom types using the specified method fftype = FFType(self, method=self.method, acCharges=acCharges) logger.info('Assigned atom types with %s' % self.method.name) self._rtf = fftype._rtf self._prm = fftype._prm if hasattr(self, '_rtf'): self.atomtype[:] = [self._rtf.type_by_name[name] for name in self.name] self.charge[:] = [self._rtf.charge_by_name[name] for name in self.name] self.impropers = np.array(self._rtf.impropers) # Set atom masses # TODO: maybe move to molecule if self.masses.size == 0: if hasattr(self, '_rtf'): self.masses[:] = [self._rtf.mass_by_type[self._rtf.type_by_index[i]] for i in range(self.numAtoms)] else: self.masses[:] = [vdw.massByElement(element) for element in self.element] self.qm = qm if qm else Psi4() self.outdir = outdir
def _guessMass(element): from htmd.molecule import vdw return vdw.massByElement(element)
def __init__(self, filename=None, name=None, rtf=None, prm=None, netcharge=None, method=FFTypeMethod.CGenFF_2b6, qm=None, outdir="./", mol=None, acCharges=None): if filename is not None and not filename.endswith('.mol2'): raise ValueError('Input file must be mol2 format') if mol is None: super().__init__(filename=filename, name=name) else: for v in mol.__dict__: self.__dict__[v] = deepcopy(mol.__dict__[v]) # Guess bonds if len(self.bonds) == 0: logger.warning('No bonds found! Guessing them...') self.bonds = self._guessBonds() # Guess angles and dihedrals self.angles, self.dihedrals = guessAnglesAndDihedrals(self.bonds, cyclicdih=True) # Detect equivalent atoms equivalents = detectEquivalents(self) self._equivalent_atom_groups = equivalents[ 0] # List of groups of equivalent atoms self._equivalent_atoms = equivalents[ 1] # List of equivalent atoms, indexed by atom self._equivalent_group_by_atom = equivalents[ 2] # Mapping from atom index to equivalent atom group # Detect rotatable dihedrals self._rotatable_dihedrals = detectSoftDihedrals(self, equivalents) # Set total charge if netcharge is None: self.netcharge = int(round(np.sum(self.charge))) else: self.netcharge = int(round(netcharge)) # Canonicalise the names self._rename() # Assign atom types, charges, and initial parameters self.method = method if rtf and prm: # If the user has specified explicit RTF and PRM files go ahead and load those self._rtf = RTF(rtf) self._prm = PRM(prm) logger.info('Reading FF parameters from %s and %s' % (rtf, prm)) elif method == FFTypeMethod.NONE: pass # Don't assign any atom types else: # Otherwise make atom types using the specified method fftype = FFType(self, method=self.method, acCharges=acCharges) logger.info('Assigned atom types with %s' % self.method.name) self._rtf = fftype._rtf self._prm = fftype._prm if hasattr(self, '_rtf'): self.atomtype[:] = [ self._rtf.type_by_name[name] for name in self.name ] self.charge[:] = [ self._rtf.charge_by_name[name] for name in self.name ] self.impropers = np.array(self._rtf.impropers) # Check if atom type names are compatible for type_ in self._rtf.types: if re.match(FFMolecule._ATOM_TYPE_REG_EX, type_): raise ValueError( 'Atom type %s is incompatable. It cannot finish with "x" + number!' % type_) # Set atom masses # TODO: maybe move to molecule if self.masses.size == 0: if hasattr(self, '_rtf'): self.masses[:] = [ self._rtf.mass_by_type[self._rtf.type_by_index[i]] for i in range(self.numAtoms) ] else: self.masses[:] = [ vdw.massByElement(element) for element in self.element ] self.qm = qm if qm else Psi4() self.outdir = outdir