def _get_angle_type(self, atom_types, warn=False): """Get a particular angle_type between `atom_types` from this ForceField""" if len(atom_types) != 3: raise ValueError( f"AngleType potential can only " f"be extracted for three atoms. Provided {len(atom_types)}") forward = FF_TOKENS_SEPARATOR.join(atom_types) reverse = FF_TOKENS_SEPARATOR.join(reversed(atom_types)) match = None if forward in self.angle_types: match = self.angle_types[forward] if reverse in self.angle_types: match = self.angle_types[reverse] msg = f"AngleType between atoms {atom_types[0]}, {atom_types[1]} " \ f"and {atom_types[2]} is missing from the ForceField" if match: return match elif warn: warnings.warn(msg) return None else: raise MissingPotentialError(msg)
def _get_improper_type(self, atom_types, warn=False): """Get a particular improper_type between `atom_types` from this ForceField.""" if len(atom_types) != 4: raise ValueError( f"ImproperType potential can only " f"be extracted for four atoms. Provided {len(atom_types)}" ) forward = FF_TOKENS_SEPARATOR.join(atom_types) reverse = FF_TOKENS_SEPARATOR.join( [atom_types[0], atom_types[2], atom_types[1], atom_types[3]] ) if forward is self.improper_types: return self.improper_types[forward] if reverse in self.improper_types: return self.improper_types[reverse] match = None for i in range(1, 5): forward_patterns = mask_with(atom_types, i) reverse_patterns = mask_with( [atom_types[0], atom_types[2], atom_types[1], atom_types[3]], i ) for forward_pattern, reverse_pattern in zip( forward_patterns, reverse_patterns ): forward_match_key = FF_TOKENS_SEPARATOR.join(forward_pattern) reverse_match_key = FF_TOKENS_SEPARATOR.join(reverse_pattern) if forward_match_key in self.dihedral_types: match = self.dihedral_types[forward_match_key] break if reverse_match_key in self.dihedral_types: match = self.dihedral_types[reverse_match_key] break if match: break msg = ( f"ImproperType between atoms {atom_types[0]}, {atom_types[1]}, " f"{atom_types[2]} and {atom_types[3]} is missing from the ForceField." ) if match: return match elif warn: warnings.warn(msg) return None else: raise MissingPotentialError(msg)
def _get_atom_type(self, atom_type, warn=False): """Get a particular atom_type with given `atom_type` from this ForceField""" if isinstance(atom_type, list): atom_type = atom_type[0] if not self.atom_types.get(atom_type): msg = f"AtomType {atom_type} is not present in the ForceField" if warn: warnings.warn(msg) else: raise MissingPotentialError(msg) return self.atom_types.get(atom_type)
def _get_bond_type(self, atom_types, warn=False): """Get a particular bond_type between `atom_types` from this ForceField""" if len(atom_types) != 2: raise ValueError( f"BondType potential can only " f"be extracted for two atoms. Provided {len(atom_types)}") forward = FF_TOKENS_SEPARATOR.join(atom_types) reverse = FF_TOKENS_SEPARATOR.join(reversed(atom_types)) if forward in self.bond_types: return self.bond_types[forward] if reverse in self.bond_types: return self.bond_types[reverse] msg = f"BondType between atoms {atom_types[0]} and {atom_types[1]} " \ f"is missing from the ForceField" if warn: warnings.warn(msg) return None else: raise MissingPotentialError(msg)