def fetch(self): """Creates a cell initializer object. Note that the cell can be initialized from the lengths of the sides and the angles between them instead of by a vector, as specified by the 'abc' or 'abcABC' modes. """ mode = self.mode.fetch() ibase = super(InputInitCell, self).fetch() if mode == "abc" or mode == "abcABC": h = io_xml.read_array(np.float, ibase.value) if mode == "abc": if h.size != 3: raise ValueError( "If you are initializing cell from cell side lengths you must pass the 'cell' tag an array of 3 floats." ) else: h = mt.abc2h(h[0], h[1], h[2], np.pi / 2, np.pi / 2, np.pi / 2) elif mode == "abcABC": if h.size != 6: raise ValueError( "If you are initializing cell from cell side lengths and angles you must pass the 'cell' tag an array of 6 floats." ) else: h = mt.abc2h( h[0], h[1], h[2], h[3] * np.pi / 180.0, h[4] * np.pi / 180.0, h[5] * np.pi / 180.0, ) h.shape = (9, ) ibase.value = h mode = "manual" if mode == "manual": h = ibase.value if h.size != 9: raise ValueError( "Cell objects must contain a 3x3 matrix describing the cell vectors." ) if not (h[3] == 0.0 and h[6] == 0.0 and h[7] == 0.0): warning( "Cell vector matrix must be upper triangular, all elements below the diagonal being set to zero.", verbosity.low, ) h[3] = h[6] = h[7] = 0 ibase.value = h return self._initclass(value=ibase.value, mode=mode, units=self.units.fetch())
def read_json(filedesc, **kwargs): """Reads a JSON-style file with i-pi style comments and creates an Atoms and Cell object. Args: filedesc: An open readable file object from a json formatted file with i-PI header comments. Returns: An Atoms object with the appropriate atom labels, masses and positions. A Cell object. """ try: line = json.loads(filedesc.readline()) except ValueError: raise EOFError("The file descriptor hit EOF.") atoms = Atoms(line[0]) atoms.q = np.asarray(line[8]) atoms.names = np.asarray(line[9], dtype='|S4') atoms.m = np.asarray(map(Elements.mass, atoms.names)) a = float(line[1]) b = float(line[2]) c = float(line[3]) alpha = float(line[4]) * np.pi / 180 beta = float(line[5]) * np.pi / 180 gamma = float(line[6]) * np.pi / 180 h = mt.abc2h(a, b, c, alpha, beta, gamma) cell = Cell(h) return {"atoms": atoms, "cell": cell}
def test_process_units_object(units_preparation): natoms, frames, comment, conver_xyz, conver_cell = units_preparation output = "objects" filedesc, xyz, atom_names = xyz_gen.xyz_traj_filedesc( natoms, frames, comment) cell = mt.abc2h(1.0, 1.0, 1.0, np.pi / 2.0, np.pi / 2.0, np.pi / 2.0) masses = [] _count = 0 for _at in atom_names: print(Elements.mass(_at), _count, _at) masses.append(Elements.mass(_at)) _count += 1 masses = np.array(masses) res = testing.process_units( comment, cell.copy(), xyz.copy(), np.array(atom_names).copy(), np.array(masses).copy(), output=output, ) npt.assert_array_almost_equal(res["atoms"].q, xyz * conver_xyz, 5) npt.assert_array_almost_equal(res["atoms"].m, masses, 5) npt.assert_array_almost_equal(res["cell"].h, cell * conver_cell, 5) npt.assert_array_equal(res["atoms"].names, atom_names, 5)
def test_process_units_noobj(units_preparation): natoms, frames, comment, conver_xyz, conver_cell = units_preparation output = "noobj" filedesc, xyz, atom_names = xyz_gen.xyz_traj_filedesc( natoms, frames, comment) cell = mt.abc2h(1.0, 1.0, 1.0, np.pi / 2.0, np.pi / 2.0, np.pi / 2.0) masses = [] _count = 0 print("atom_names", atom_names) for _at in atom_names: print(Elements.mass(_at), _count, _at) masses.append(Elements.mass(_at)) _count += 1 masses = np.array(masses) type(masses) res = testing.process_units( comment, cell.copy(), xyz.copy(), np.array(atom_names).copy(), np.array(masses).copy(), output=output, ) print(xyz, res["data"]) npt.assert_array_almost_equal(res["data"], xyz * conver_xyz, 5) npt.assert_array_almost_equal(res["masses"], masses, 5) npt.assert_array_almost_equal(res["cell"], cell * conver_cell, 5) npt.assert_array_equal(res["names"], atom_names, 5) assert res["natoms"] == natoms
def test_process_units_noobj(units_preparation): natoms, frames, comment, conver_xyz, conver_cell = units_preparation output = 'noobj' filedesc, xyz, atom_names = xyz_gen.xyz_traj_filedesc(natoms, frames, comment) cell = mt.abc2h(1.0, 1.0, 1.0, np.pi/2.0, np.pi/2.0, np.pi/2.0) masses = [] _count = 0 print 'atom_names', atom_names for _at in atom_names: print Elements.mass(_at), _count, _at masses.append(Elements.mass(_at)) _count += 1 masses = np.array(masses) type(masses) res = testing.process_units(comment, cell.copy(), xyz.copy(), np.array(atom_names).copy(), np.array(masses).copy(), output=output) print xyz,res['data'] npt.assert_array_almost_equal(res['data'], xyz * conver_xyz, 5) npt.assert_array_almost_equal(res['masses'], masses, 5) npt.assert_array_almost_equal(res['cell'], cell * conver_cell, 5) npt.assert_array_equal(res['names'], atom_names, 5) assert res['natoms'] == natoms
def test_process_units_noobj(units_preparation): natoms, frames, comment, conver_xyz, conver_cell = units_preparation output = 'noobj' filedesc, xyz, atom_names = xyz_gen.xyz_traj_filedesc(natoms, frames, comment) cell = mt.abc2h(1.0, 1.0, 1.0, np.pi / 2.0, np.pi / 2.0, np.pi / 2.0) masses = [] _count = 0 print 'atom_names', atom_names for _at in atom_names: print Elements.mass(_at), _count, _at masses.append(Elements.mass(_at)) _count += 1 masses = np.array(masses) type(masses) res = testing.process_units(comment, cell.copy(), xyz.copy(), np.array(atom_names).copy(), np.array(masses).copy(), output=output) print xyz, res['data'] npt.assert_array_almost_equal(res['data'], xyz * conver_xyz, 5) npt.assert_array_almost_equal(res['masses'], masses, 5) npt.assert_array_almost_equal(res['cell'], cell * conver_cell, 5) npt.assert_array_equal(res['names'], atom_names, 5) assert res['natoms'] == natoms
def test_process_units_object(units_preparation): natoms, frames, comment, conver_xyz, conver_cell = units_preparation output = 'objects' filedesc, xyz, atom_names = xyz_gen.xyz_traj_filedesc(natoms, frames, comment) cell = mt.abc2h(1.0, 1.0, 1.0, np.pi / 2.0, np.pi / 2.0, np.pi / 2.0) masses = [] _count = 0 for _at in atom_names: print Elements.mass(_at), _count, _at masses.append(Elements.mass(_at)) _count += 1 masses = np.array(masses) res = testing.process_units(comment, cell.copy(), xyz.copy(), np.array(atom_names).copy(), np.array(masses).copy(), output=output) npt.assert_array_almost_equal(res['atoms'].q, xyz * conver_xyz, 5) npt.assert_array_almost_equal(res['atoms'].m, masses, 5) npt.assert_array_almost_equal(res['cell'].h, cell * conver_cell, 5) npt.assert_array_equal(res['atoms'].names, atom_names, 5)
def read_json(filedesc): """Reads a JSON-style file with i-pi style comments and creates an Atoms and Cell object. Args: filedesc: An open readable file object from a json formatted file with i-PI header comments. Returns: An Atoms object with the appropriate atom labels, masses and positions. A Cell object. """ try: line = filedesc.readline() data = json.loads(line) except ValueError: raise EOFError("The file descriptor hit EOF.") line.strip("\n") natoms = data['natoms'] qatoms = np.asarray(data['q'], dtype=float) names = np.asarray(data['labels'], dtype='|S4') title = data['title'] masses = np.zeros(len(names)) a, b, c, alpha, beta, gamma = data['cell'] alpha *= np.pi / 180. beta *= np.pi / 180. gamma *= np.pi / 180. cell = mt.abc2h(a, b, c, alpha, beta, gamma) return (title, cell, qatoms, names, masses)
def read_pdb(filedesc, **kwargs): """Reads a PDB-style file and creates an Atoms and Cell object. Args: filedesc: An open readable file object from a pdb formatted file. Returns: An Atoms object with the appropriate atom labels, masses and positions, and a Cell object with the appropriate cell dimensions and an estimate of a reasonable cell mass. """ header = filedesc.readline() comment = '' if "TITLE" in header: # skip the comment field comment = copy.copy(header) header = filedesc.readline() if 'positions{' not in comment: comment = comment.strip() comment += ' positions{angstrom}\n' if 'cell{' not in comment: comment = comment.strip() comment += ' cell{angstrom}\n' if header == "": raise EOFError("End of file or empty header in PDB file") a = float(header[6:15]) b = float(header[15:24]) c = float(header[24:33]) alpha = float(header[33:40]) beta = float(header[40:47]) gamma = float(header[47:54]) alpha *= np.pi / 180.0 beta *= np.pi / 180.0 gamma *= np.pi / 180.0 h = mt.abc2h(a, b, c, alpha, beta, gamma) cell = h natoms = 0 body = filedesc.readline() qatoms = [] names = [] masses = [] while (body.strip() != "" and body.strip() != "END"): natoms += 1 name = body[12:16].strip() names.append(name) masses.append(Elements.mass(name)) x = float(body[31:39]) y = float(body[39:47]) z = float(body[47:55]) qatoms.append(x) qatoms.append(y) qatoms.append(z) body = filedesc.readline() return comment, cell, np.asarray(qatoms), np.asarray( names, dtype='|S4'), np.asarray(masses)
def read_pdb(filedesc): """Takes a pdb-style file and creates an Atoms and Cell object. Args: filedesc: An open readable file object from a pdb formatted file. Returns: An Atoms object with the appropriate atom labels, masses and positions, and a Cell object with the appropriate cell dimensions and an estimate of a reasonable cell mass. """ header = filedesc.readline() if "TITLE" in header: header = filedesc.readline() # skip the comment field if header == "": raise EOFError("End of file or empty header in PDB file") a = float(header[6:15]) b = float(header[15:24]) c = float(header[24:33]) alpha = float(header[33:40]) beta = float(header[40:47]) gamma = float(header[47:54]) alpha *= np.pi/180.0 beta *= np.pi/180.0 gamma *= np.pi/180.0 h = mt.abc2h(a, b, c, alpha, beta, gamma) cell = Cell(h) natoms = 0 body = filedesc.readline() qatoms = [] names = [] masses = [] while (body.strip() != "" and body.strip() != "END"): natoms += 1 name = body[12:16].strip() names.append(name) masses.append(Elements.mass(name)) x = float(body[31:39]) y = float(body[39:47]) z = float(body[47:55]) qatoms.append(x) qatoms.append(y) qatoms.append(z) body = filedesc.readline() atoms = Atoms(natoms) atoms.q = np.asarray(qatoms) atoms.names = np.asarray(names,dtype='|S4') atoms.m = np.asarray(masses) return atoms, cell
def fetch(self): """Creates a cell initializer object. Note that the cell can be initialized from the lengths of the sides and the angles between them instead of by a vector, as specified by the 'abc' or 'abcABC' modes. """ mode = self.mode.fetch() ibase = super(InputInitCell,self).fetch() if mode == "abc" or mode == "abcABC": h = io_xml.read_array(np.float, ibase.value) if mode == "abc": if h.size != 3: raise ValueError("If you are initializing cell from cell side lengths you must pass the 'cell' tag an array of 3 floats.") else: h = mt.abc2h(h[0], h[1], h[2], np.pi/2, np.pi/2, np.pi/2) elif mode == "abcABC": if h.size != 6: raise ValueError("If you are initializing cell from cell side lengths and angles you must pass the 'cell' tag an array of 6 floats.") else: h = mt.abc2h(h[0], h[1], h[2], h[3]*np.pi/180.0, h[4]*np.pi/180.0, h[5]*np.pi/180.0) h.shape = (9,) ibase.value = h mode = "manual" if mode == "manual": h = ibase.value if h.size != 9: raise ValueError("Cell objects must contain a 3x3 matrix describing the cell vectors.") if not (h[3] == 0.0 and h[6] == 0.0 and h[7] == 0.0): warning("Cell vector matrix must be upper triangular, all elements below the diagonal being set to zero.", verbosity.low) h[3] = h[6] = h[7] = 0 ibase.value = h return self._initclass(value=ibase.value, mode=mode, units=self.units.fetch())
# default_cell_mat = mt.abc2h(-1.0, -1.0, -1.0, np.pi/2.0, np.pi/2.0, np.pi/2.0) # After changing the "input standard" default_cell_mat = np.eye(3) * -1.0 deg2rad = np.pi / 180.0 test_read_file_prms = [ #natoms, nframes, comment, output_type, file_type, expected_cell, unit_conv_cell, unit_conv_q (1, 1, 'asdasd', 'objects', 'xyz', default_cell_mat, 1, 1), (2, 1, 'asdasd', 'objects', 'xyz', default_cell_mat, 1, 1), (1, 2, 'asdasd', 'objects', 'xyz', default_cell_mat, 1, 1), (10, 10, 'cell{angstrom} positions{angstrom}', 'objects', 'xyz', default_cell_mat, 1.8897261, 1.8897261), (10, 10, ' positions{angstrom} cell{angstrom} 100 aaa # CELL(abcABC): 5.1 5.2 5.0 91.0 89 90 100 aaa', 'objects', 'xyz', mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad), 1.8897261, 1.8897261), (1, 1, 'asdasd', 'array', 'xyz', default_cell_mat, 1, 1), (2, 1, 'asdasd', 'array', 'xyz', default_cell_mat, 1, 1), (1, 2, 'asdasd', 'array', 'xyz', default_cell_mat, 1, 1), (10, 10, 'cell{angstrom} positions{angstrom}', 'array', 'xyz', default_cell_mat, 1.8897261, 1.8897261), (10, 10, ' positions{angstrom} cell{angstrom} 100 aaa # CELL(abcABC): 5.1 5.2 5.0 91.0 89 90 100 aaa', 'array', 'xyz', mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad), 1.8897261, 1.8897261), ] @pytest.fixture(params=test_read_file_prms) def prepare_read_file(request):
import ipi_tests.xyz_generator as xyz_gen # default_cell_mat = mt.abc2h(-1.0, -1.0, -1.0, np.pi/2.0, np.pi/2.0, np.pi/2.0) # After changing the input standard default_cell_mat = np.eye(3) * -1 deg2rad = np.pi / 180.0 test_init_file_prms = [ (1, 1, 'asdasd', default_cell_mat, 1., 1.), (2, 1, 'asdasd', default_cell_mat, 1., 1.), (1, 2, 'asdasd', default_cell_mat, 1., 1.), (10, 10, 'dsadsa', default_cell_mat, 1., 1.), (5, 1, 'asdasd positions{angstrom} 100 aaa cell{angstrom} asdasd ', default_cell_mat, 1.8897261, 1.8897261), (5, 1, 'asdasd positions{angstrom} 100 aaa cell{angstrom} 100 aaa # CELL(abcABC): 5.1 5.2 5.0 91.0 89 90 100 aaa asdasd ', mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad), 1.8897261, 1.8897261), ] @pytest.fixture(params=test_init_file_prms) def create_xyz_sample_file(request): """ Create a fake xyz file and build the atoms and cell object from it. """ natoms, frames, comment, expected_cell, units_conv_at, units_conv_cell = request.param filedesc, xyz, atoms_names = xyz_gen.xyz_traj_filedesc(natoms, frames, comment) # init_file needs to read from a real file... tmp_file = tmp.NamedTemporaryFile(mode='wr', prefix='ipi_testing-tmp', delete=False)
import ipi_tests.xyz_generator as xyz_gen import ipi.utils.io.backends.io_xyz as io_xyz import ipi.utils.mathtools as mt from ipi.engine.atoms import Atoms from ipi.engine.cell import Cell from ipi.utils.units import Elements ####################### # Testing reading xyz # ####################### deg2rad = np.pi / 180.0 cell_string = ' '.join([ str(x) for x in mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad).flatten() ]) #default_cell_mat = mt.abc2h(-1.0, -1.0, -1.0, np.pi/2.0, np.pi/2.0, np.pi/2.0) # After changing the input standard default_cell_mat = np.eye(3) * -1 # natoms, frames, comment, expected_cell, precision tests_read_xyz = [ (1, 1, 'just a string plus few numbers: 1.10 2 .1', default_cell_mat, 5), (2, 1, 'another random comment', default_cell_mat, 5), (1, 2, 'random comment', default_cell_mat, 5), (2, 2, 'random comment', default_cell_mat, 5), (10, 2, 'random comment', default_cell_mat, 5), (10, 10, 'random comment', default_cell_mat, 5), (2, 3, '# CELL(abcABC): 5.1 5.2 5.0 91.0 89 90', mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad), 5), (2, 3, '# CELL[GENH]: ' + cell_string,
#!/usr/bin/env python2 import mock import pytest from pytest_mock import mocker import numpy as np import numpy.testing as npt import ipi_tests.xyz_generator as xyz_gen import ipi.utils.io as io import ipi.utils.mathtools as mt default_cell_mat = mt.abc2h(1.0, 1.0, 1.0, np.pi/2.0, np.pi/2.0, np.pi/2.0) deg2rad = np.pi/180.0 test_read_file_prms = [ #natoms, nframes, comment, output_type, file_type, expected_cell, unit_conv_cell, unit_conv_q (1, 1, 'asdasd', 'objects', 'xyz', default_cell_mat, 1, 1), (2, 1, 'asdasd', 'objects', 'xyz', default_cell_mat, 1, 1), (1, 2, 'asdasd', 'objects', 'xyz', default_cell_mat, 1, 1), (10, 10, '{angstrom} positions{angstrom}', 'objects', 'xyz', default_cell_mat, 1.8897261, 1.8897261), (10, 10, ' positions{angstrom} {angstrom} 100 aaa # CELL(abcABC): 5.1 5.2 5.0 91.0 89 90 100 aaa', 'objects', 'xyz', mt.abc2h(5.1, 5.2, 5.0, 91*deg2rad, 89*deg2rad, 90*deg2rad), 1.8897261, 1.8897261), (1, 1, 'asdasd', 'array', 'xyz', default_cell_mat, 1, 1), (2, 1, 'asdasd', 'array', 'xyz', default_cell_mat, 1, 1), (1, 2, 'asdasd', 'array', 'xyz', default_cell_mat, 1, 1), (10, 10, '{angstrom} positions{angstrom}', 'array', 'xyz', default_cell_mat, 1.8897261, 1.8897261),
import os import numpy as np import tempfile as tmp import numpy.testing as npt import ipi.engine.initializer as initializer import ipi.utils.mathtools as mt from ipi.utils.units import Elements from ipi.engine.atoms import Atoms from ipi.engine.cell import Cell import ipi_tests.xyz_generator as xyz_gen default_cell_mat = mt.abc2h(1.0, 1.0, 1.0, np.pi / 2.0, np.pi / 2.0, np.pi / 2.0) deg2rad = np.pi / 180.0 test_init_file_prms = [ (1, 1, 'asdasd', default_cell_mat, 1., 1.), (2, 1, 'asdasd', default_cell_mat, 1., 1.), (1, 2, 'asdasd', default_cell_mat, 1., 1.), (10, 10, 'dsadsa', default_cell_mat, 1., 1.), (5, 1, 'asdasd positions{angstrom} 100 aaa {angstrom} asdasd ', default_cell_mat, 1.8897261, 1.8897261), (5, 1, 'asdasd positions{angstrom} 100 aaa {angstrom} 100 aaa # CELL(abcABC): 5.1 5.2 5.0 91.0 89 90 100 aaa asdasd ', mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad), 1.8897261, 1.8897261), ]
def read_xyz(filedesc): """Reads an XYZ-style file with i-PI style comments and returns data in raw format for further units transformation and other post processing. Args: filedesc: An open readable file object from a xyz formatted file with i-PI header comments. Returns: i-Pi comment line, cell array, data (positions, forces, etc.), atoms names and masses """ try: natoms = int(filedesc.next()) except (StopIteration, ValueError): raise EOFError comment = filedesc.next() # Extracting cell cell = [key.search(comment) for key in cell_re] usegenh = False if cell[0] is not None: # abcABC a, b, c = [float(x) for x in cell[0].group(1).split()[:3]] alpha, beta, gamma = [float(x) * deg2rad for x in cell[0].group(1).split()[3:6]] h = mt.abc2h(a, b, c, alpha, beta, gamma) elif cell[1] is not None: # GENH h = np.array(cell[1].group(1).split()[:9], float) h.resize((3, 3)) elif cell[2] is not None: # H genh = np.array(cell[2].group(1).split()[:9], float) genh.resize((3, 3)) invgenh = np.linalg.inv(genh) # convert back & forth from abcABC representation to get an upper triangular h h = mt.abc2h(*mt.genh2abc(genh)) usegenh = True else: # defaults to unit box h = np.array([[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]]) cell = h qatoms = np.zeros(3 * natoms) names = np.zeros(natoms, dtype='|S4') masses = np.zeros(natoms) # Extracting a time-frame information atom_counter = 0 for iat, line in enumerate(filedesc): body = line.split() names[iat], masses[iat] = body[0], Elements.mass(body[0]) x, y, z = float(body[1]), float(body[2]), float(body[3]) # TODO: The following in matrices would use vectorial computaiton if usegenh: # must convert from the input cell parameters to the internal convention u = np.array([x, y, z]) us = np.dot(u, invgenh) u = np.dot(h, us) x, y, z = u qatoms[3 * iat], qatoms[3 * iat + 1], qatoms[3 * iat + 2] = x, y, z atom_counter += 1 if atom_counter == natoms: break if natoms != len(names): raise ValueError("The number of atom records does not match the header of the xyz file.") return comment, cell, qatoms, names, masses
import ipi.utils.io as io import ipi.utils.mathtools as mt # default_cell_mat = mt.abc2h(-1.0, -1.0, -1.0, np.pi/2.0, np.pi/2.0, np.pi/2.0) # After changing the "input standard" default_cell_mat = np.eye(3) * -1.0 deg2rad = np.pi / 180.0 test_read_file_prms = [ # natoms, nframes, comment, output_type, file_type, expected_cell, unit_conv_cell, unit_conv_q (1, 1, 'asdasd', 'objects', 'xyz', default_cell_mat, 1, 1), (2, 1, 'asdasd', 'objects', 'xyz', default_cell_mat, 1, 1), (1, 2, 'asdasd', 'objects', 'xyz', default_cell_mat, 1, 1), (10, 10, 'cell{angstrom} positions{angstrom}', 'objects', 'xyz', default_cell_mat, 1.8897261, 1.8897261), (10, 10, ' positions{angstrom} cell{angstrom} 100 aaa # CELL(abcABC): 5.1 5.2 5.0 91.0 89 90 100 aaa', 'objects', 'xyz', mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad), 1.8897261, 1.8897261), (1, 1, 'asdasd', 'array', 'xyz', default_cell_mat, 1, 1), (2, 1, 'asdasd', 'array', 'xyz', default_cell_mat, 1, 1), (1, 2, 'asdasd', 'array', 'xyz', default_cell_mat, 1, 1), (10, 10, 'cell{angstrom} positions{angstrom}', 'array', 'xyz', default_cell_mat, 1.8897261, 1.8897261), (10, 10, ' positions{angstrom} cell{angstrom} 100 aaa # CELL(abcABC): 5.1 5.2 5.0 91.0 89 90 100 aaa', 'array', 'xyz', mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad), 1.8897261, 1.8897261), ] @pytest.fixture(params=test_read_file_prms) def prepare_read_file(request): natoms, nframes, comment, output_type, file_type, expected_cell, unit_conv_cell, unit_conv_q = request.param filedesc, xyz, atom_names = xyz_gen.xyz_traj_filedesc(natoms, nframes, comment)
import ipi_tests.xyz_generator as xyz_gen import ipi.utils.io.backends.io_xyz as io_xyz import ipi.utils.mathtools as mt from ipi.engine.atoms import Atoms from ipi.engine.cell import Cell from ipi.utils.units import Elements # # Testing reading xyz # # deg2rad = np.pi / 180.0 cell_string = ' '.join([str(x) for x in mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad).flatten()]) # default_cell_mat = mt.abc2h(-1.0, -1.0, -1.0, np.pi/2.0, np.pi/2.0, np.pi/2.0) # After changing the input standard default_cell_mat = np.eye(3) * -1 # natoms, frames, comment, expected_cell, precision tests_read_xyz = [ (1, 1, 'just a string plus few numbers: 1.10 2 .1', default_cell_mat, 5), (2, 1, 'another random comment', default_cell_mat, 5), (1, 2, 'random comment', default_cell_mat, 5), (2, 2, 'random comment', default_cell_mat, 5), (10, 2, 'random comment', default_cell_mat, 5), (10, 10, 'random comment', default_cell_mat, 5),
import ipi_tests.xyz_generator as xyz_gen import ipi.utils.io.backends.io_xyz as io_xyz import ipi.utils.mathtools as mt from ipi.engine.atoms import Atoms from ipi.engine.cell import Cell from ipi.utils.units import Elements ####################### # Testing reading xyz # ####################### deg2rad = np.pi / 180.0 cell_string = ' '.join([ str(x) for x in mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad).flatten() ]) default_cell_mat = mt.abc2h(1.0, 1.0, 1.0, np.pi / 2.0, np.pi / 2.0, np.pi / 2.0) # natoms, frames, comment, expected_cell, precision tests_read_xyz = [ (1, 1, 'just a string plus few numbers: 1.10 2 .1', default_cell_mat, 5), (2, 1, 'another random comment', default_cell_mat, 5), (1, 2, 'random comment', default_cell_mat, 5), (2, 2, 'random comment', default_cell_mat, 5), (10, 2, 'random comment', default_cell_mat, 5), (10, 10, 'random comment', default_cell_mat, 5), (2, 3, '# CELL(abcABC): 5.1 5.2 5.0 91.0 89 90', mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad), 5), (2, 3, '# CELL[GENH]: ' + cell_string,
(2, 1, "asdasd", default_cell_mat, 1.0, 1.0), (1, 2, "asdasd", default_cell_mat, 1.0, 1.0), (10, 10, "dsadsa", default_cell_mat, 1.0, 1.0), ( 5, 1, "asdasd positions{angstrom} 100 aaa cell{angstrom} asdasd ", default_cell_mat, 1.8897261, 1.8897261, ), ( 5, 1, "asdasd positions{angstrom} 100 aaa cell{angstrom} 100 aaa # CELL(abcABC): 5.1 5.2 5.0 91.0 89 90 100 aaa asdasd ", mt.abc2h(5.1, 5.2, 5.0, 91 * deg2rad, 89 * deg2rad, 90 * deg2rad), 1.8897261, 1.8897261, ), ] @pytest.fixture(params=test_init_file_prms) def create_xyz_sample_file(request): """ Create a fake xyz file and build the atoms and cell object from it. """ ( natoms, frames, comment,
def read_xyz(filedesc): """Reads an XYZ-style file with i-PI style comments and returns data in raw format for further units transformation and other post processing. Args: filedesc: An open readable file object from a xyz formatted file with i-PI header comments. Returns: i-Pi comment line, cell array, data (positions, forces, etc.), atoms names and masses """ try: natoms = int(filedesc.next()) except (StopIteration, ValueError): raise EOFError comment = filedesc.next() # Extracting cell cell = [key.search(comment) for key in cell_re] usegenh = False if cell[0] is not None: # abcABC a, b, c = [float(x) for x in cell[0].group(1).split()[:3]] alpha, beta, gamma = [float(x) * deg2rad for x in cell[0].group(1).split()[3:6]] h = mt.abc2h(a, b, c, alpha, beta, gamma) elif cell[1] is not None: # H h = np.array(cell[1].group(1).split()[:9], float) h.resize((3, 3)) elif cell[2] is not None: # GENH genh = np.array(cell[2].group(1).split()[:9], float) genh.resize((3, 3)) invgenh = np.linalg.inv(genh) # convert back & forth from abcABC representation to get an upper triangular h h = mt.abc2h(*mt.genh2abc(genh)) usegenh = True else: # defaults to unit box h = np.array([[-1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [0.0, 0.0, -1.0]]) cell = h qatoms = np.zeros(3 * natoms) names = np.zeros(natoms, dtype='|S4') masses = np.zeros(natoms) # Extracting a time-frame information atom_counter = 0 for iat, line in enumerate(filedesc): body = line.split() names[iat], masses[iat] = body[0], Elements.mass(body[0]) x, y, z = float(body[1]), float(body[2]), float(body[3]) if usegenh: # must convert from the input cell parameters to the internal convention u = np.array([x, y, z]) us = np.dot(u, invgenh) u = np.dot(h, us) x, y, z = u qatoms[3 * iat], qatoms[3 * iat + 1], qatoms[3 * iat + 2] = x, y, z atom_counter += 1 if atom_counter == natoms: break if natoms != len(names): raise ValueError("The number of atom records does not match the header of the xyz file.") return comment, cell, qatoms, names, masses