def testTwoAtoms(self): """Asserts correct atoms returned from two atom input.""" param = [['2'], [], ['N*', '1.0', '0.1', '-.2', '+0.553'], ['H4', '0.523', '-100.12', '5.5', '-0.27']] test_output = fileio.GetAtomsFromXyzq(param) ref_output = [ molecule.Atom('N*', [1.0, 0.1, -0.2], 0.553), molecule.Atom('H4', [0.523, -100.12, 5.5], -0.27) ] test.assertObjectArrayEqual(self, test_output, ref_output)
def testOneAtom(self): """Asserts correct atom returned from one atom input.""" param = [['1'], ['ignored', 'comment'], ['H', '0.0', '0.0', '0.0', '0.0']] test_output = fileio.GetAtomsFromXyzq(param) ref_output = [molecule.Atom('H', [0.0, 0.0, 0.0], 0.0)] test.assertObjectArrayEqual(self, test_output, ref_output)
def GetAtomFromXyzq(row): """Parses and validates a row of input from xyzq file into an Atom object. Args: row (str*): Array of strings from row of xyzq file. Returns: atom (mmlib.molecule.Atom): Atom object. Raises: IndexError: If insufficient number of fields. ValueError: If incorrect data type of any field. """ if len(row) < 2+const.NUMDIM: raise IndexError('Insufficient columns to parse xyzq file row into Atom ' 'object: %s' % ' '.join(row)) type_ = row[0] coords = row[1:1+const.NUMDIM] charge = row[1+const.NUMDIM] if not type_ or not type_[0].isalpha(): raise ValueError('Atom type must begin with letter: %s' % type_) if not _AreAllType(float, coords): raise ValueError( 'Atomic coordinates must be numeric values: %s' % ' '.join(coords)) if not _IsType(float, charge): raise ValueError('Atomic charge must be numeric value: %s' % charge) return molecule.Atom(type_, numpy.fromiter(coords, float), float(charge))
def GetGeom(mol): """Read in molecular geometry data from molecule xyzq file. Parse 2-d array of strings from xyzq file into atomic data. First line contains (int) number of atoms. Second line is ignored comment. Each line after (3 to [n+2]) contains atom type, (float) 3 xyz cartesian coordinates [Angstrom], and (float) charge [e]. Args: mol (mmlib.molecule.Molecule): molecule with an associated xyzq input file. """ infile_array = _GetFileStringArray(mol.infile) mol.n_atoms = int(infile_array[0][0]) for i in range(mol.n_atoms): at_type = infile_array[i+2][0] at_coords = numpy.array( list(map(float, infile_array[i+2][1:1+const.NUMDIM]))) at_charge = float(infile_array[i+2][4]) at_element = GetElement(at_type) at_mass = param.GetAtMass(at_element) at_ro, at_eps = param.GetVdwParam(at_type) atom = molecule.Atom(at_type, at_coords, at_charge, at_ro, at_eps, at_mass) atom.SetCovRad(param.GetCovRad(at_element)) mol.atoms.append(atom) mol.mass += at_mass
def get_atom(mol, record): """Parse atom record into an atom object and append to molecule. Appends mmlib.molecule.Atom object to mmlib.molecule.Molecule object. Contents of atom object include (float*) xyz cartesian coordinates [Angstrom], (float) partial charge [e], (float) van der Waals radius [Angstrom], (float) van der Waals epsilon [kcal/mol], (str) atom type, (str) atomic element, (float) covalent radius, [Angstrom], and (float) mass [amu]. Args: mol (mmlib.molecule.Molecule): Molecule to append atom. record (str*): Array of strings from line of prm file. """ at_type = record[2] at_coords = numpy.zeros(3) for j in range(3): at_coords[j] = float(record[j+3]) at_charge, at_ro, at_eps = (float(record[6]), float(record[7]), float(record[8])) at_element = (at_type[0:2].capitalize() if at_type[-1].islower() else at_type[0]) at_mass = param.get_at_mass(at_element) atom = molecule.Atom(at_type, at_coords, at_charge, at_ro, at_eps, at_mass) atom.set_covrad(param.get_cov_rad(at_element)) mol.atoms.append(atom) mol.mass += at_mass
def get_geom(mol): """Read in molecular geometry data from molecule xyzq file. Parse 2-d array of strings from xyzq file into atomic data. First line contains (int) number of atoms. Second line is ignored comment. Each line after (3 to [n+2]) contains atom type, (float) 3 xyz cartesian coordinates [Angstrom], and (float) charge [e]. Args: mol (mmlib.molecule.Molecule): molecule with an associated xyzq input file. """ infile_array = get_file_string_array(mol.infile) mol.n_atoms = int(infile_array[0][0]) mol.bond_lenths = [{} for i in range(mol.n_atoms)] for i in range(mol.n_atoms): at_type = infile_array[i+2][0] at_coords = numpy.zeros(3) for j in range(3): at_coords[j] = float(infile_array[i+2][j+1]) at_charge = float(infile_array[i+2][4]) at_element = (at_type[0:2].capitalize() if at_type[-1].islower() else at_type[0]) at_mass = param.get_at_mass(at_element) at_ro, at_eps = param.get_vdw_param(at_type) new_atom = molecule.Atom(at_type, at_coords, at_charge, at_ro, at_eps, at_mass) new_atom.set_covrad(param.get_cov_rad(at_element)) mol.atoms.append(new_atom) mol.mass += at_mass
def GetAtomFromPrm(record): """Parses atom record into an Atom object. Args: record (str*): Array of strings from line of prm file. Returns: atom (mmlib.molecule.Atom): Atom object with attributes from record. """ type_ = record[2] coords = numpy.array(tuple(map(float, record[3:3 + const.NUMDIM]))) charge, ro, eps = tuple( map(float, record[3 + const.NUMDIM:6 + const.NUMDIM])) return molecule.Atom(type_, coords, charge, ro, eps)
def GetAtoms(records): """Parses atom records into an array of Atom objects. Args: records (str**): 2d array of strings from lines of prm file. Returns: atoms (mmlib.molecule.Atom*): Array of Atom object with parameters from records. """ atoms = [] for record in records: if not record[0].upper() == 'ATOM': continue at_type = record[2] at_coords = numpy.array(list(map(float, record[3:3 + const.NUMDIM]))) at_charge, at_ro, at_eps = list(map(float, record[6:9])) atoms.append( molecule.Atom(at_type, at_coords, at_charge, at_ro, at_eps)) return atoms
def GetAtomsFromXyzq(input_rows): """Reads in molecular geometry data from molecule xyzq file. First line contains (int) number of atoms. Second line is ignored comment. Each line afterward (3 to [n+2]) contains atom type, (float) 3 xyz Cartesian coordinates [Angstrom], and (float) charge [e]. Args: input_file (str**): 2d array of string from xyzq input file. Returns: atoms (mmlib.molecule.Atom*): Array of molecule's Atom objects. """ atoms = [] n_atoms = int(input_rows[0][0]) for row in input_rows[2:n_atoms + 2]: at_type = row[0] at_coords = numpy.array(list(map(float, row[1:1 + const.NUMDIM]))) at_charge = float(row[1 + const.NUMDIM]) atoms.append(molecule.Atom(at_type, at_coords, at_charge)) return atoms
def _GetAtom(mol, record): """Parse atom record into an atom object and append to molecule. Appends mmlib.molecule.Atom object to mmlib.molecule.Molecule object. Contents of atom object include (float*) xyz cartesian coordinates [Angstrom], (float) partial charge [e], (float) van der Waals radius [Angstrom], (float) van der Waals epsilon [kcal/mol], (str) atom type, (str) atomic element, (float) covalent radius, [Angstrom], and (float) mass [amu]. Args: mol (mmlib.molecule.Molecule): Molecule to append atom. record (str*): Array of strings from line of prm file. """ at_type = record[2] at_coords = numpy.array(list(map(float, record[3:3+const.NUMDIM]))) at_charge, at_ro, at_eps = list(map(float, record[6:9])) at_element = GetElement(at_type) at_mass = param.GetAtMass(at_element) atom = molecule.Atom(at_type, at_coords, at_charge, at_ro, at_eps, at_mass) atom.SetCovRad(param.GetCovRad(at_element)) mol.atoms.append(atom) mol.mass += at_mass
def GetAtomFromPrm(row): """Parses atom row into an Atom object. Args: row (str*): Array of strings from line of prm file. Returns: atom (mmlib.molecule.Atom): Atom object with attributes from row. Raises: IndexError: If insufficient number of fields. ValueError: If incorrect data type of any field. """ if len(row) < 6+const.NUMDIM: raise IndexError('Insufficient columns to parse prm file row into Atom ' 'object: %s' % ' '.join(row)) type_ = row[2] coords = row[3:3+const.NUMDIM] charge, ro, eps = row[3+const.NUMDIM:6+const.NUMDIM] if not type_ or not type_[0].isalpha(): raise ValueError('Atom type must begin with letter: %s' % type_) if not _AreAllType(float, coords): raise ValueError( 'Atomic coordinates must be numeric values: %s' % ' '.join(coords)) if not _IsType(float, charge): raise ValueError('Atomic charge must be numeric value: %s' % charge) if not _IsType(float, ro) or not float(ro) > 0.0: raise ValueError( 'Atomic vdw radius must be positive numeric value: %s' % ro) if not _IsType(float, eps) or not float(eps) >= 0.0: raise ValueError( 'Atomic epsilon must be non-negative numeric value: %s' % eps) return molecule.Atom(type_, numpy.fromiter(coords, float), float(charge), float(ro), float(eps))
def testArbitrary(self): """Asserts correct output for arbitrary Atom inputs.""" param = ['N*', '999.9', '-0.0001', '2.0', '-0.52'] output = molecule.Atom('N*', [999.9, -0.0001, 2.0], -0.52) test.assertObjectEqual(self, fileio.GetAtomFromXyzq(param), output)
def testZeroValues(self): """Asserts correct output for zero value numeric inputs.""" param = ['OW', '0.0', '0.0', '0.0', '0.0'] output = molecule.Atom('OW', [0.0, 0.0, 0.0], 0.0) test.assertObjectEqual(self, fileio.GetAtomFromXyzq(param), output)
def testArbitrary(self): """Asserts correct Atom object for arbitrary input parameters.""" param = ['ATOM', '7', 'NA', '1.1', '2.2', '3.3', '4.4', '5.5', '6.6'] test.assertObjectEqual( self, fileio.GetAtomFromPrm(param), molecule.Atom('NA', [1.1, 2.2, 3.3], 4.4, 5.5, 6.6))
def testZeroValues(self): """Asserts correct Atom object for zero value numeric inputs.""" param = ['ATOM', '6', 'X', '0.', '0.', '0.', '0.', '0.1', '0.'] test.assertObjectEqual(self, fileio.GetAtomFromPrm(param), molecule.Atom('X', [0., 0., 0.], 0., 0.1, 0.))