def test_methods(): tr = crys.Trajectory(coords=rand(100, 10, 3), cell=rand(100, 3, 3), symbols=['H'] * 10) st = crys.Structure(coords=rand(10, 3), cell=rand(3, 3), symbols=['H'] * 10) for obj, indices in [(st, [0, 1, 2]), (tr, [0, 0, 1, 2])]: if obj.is_traj: v0 = obj.coords[indices[0], indices[1], ...] v1 = obj.coords[indices[0], indices[2], ...] v2 = obj.coords[indices[0], indices[3], ...] else: v0 = obj.coords[indices[0], ...] v1 = obj.coords[indices[1], ...] v2 = obj.coords[indices[2], ...] # use eps=0 since the new system is not orthogonal, only test API o1 = crys.align_cart(obj, x=v1 - v0, y=v2 - v0, eps=0) o2 = crys.align_cart(obj, vecs=np.array([v0, v1, v2]), eps=0) o3 = crys.align_cart(obj, indices=indices, eps=0) tools.assert_dict_with_all_types_almost_equal(o1.__dict__, o2.__dict__, keys=o1.attr_lst) tools.assert_dict_with_all_types_almost_equal(o1.__dict__, o3.__dict__, keys=o1.attr_lst)
def test_pbc_wrap(): coords_frac_orig = np.array([[1.1, 0.9, -0.1], [-0.8, 0.5, 0.0]]) st = crys.Structure(coords_frac=coords_frac_orig, cell=np.identity(3) * 2, symbols=['H'] * 2) st_wrap = crys.pbc_wrap(st) # pbc_wrap() makes a copy by default, make sure the original st is unchanged assert (st.coords_frac == coords_frac_orig).all() assert (st.coords == coords_frac_orig * 2.0).all() coords_frac_wrap = np.array([[0.1, 0.9, 0.9], [0.2, 0.5, 0.]]) assert np.allclose(coords_frac_wrap, st_wrap.coords_frac) assert np.allclose(coords_frac_wrap, st_wrap.coords / 2.0) coords_frac_wrap = np.random.rand(20, 100, 3) plus = np.random.randint(-1, 1, coords_frac_wrap.shape) coords_frac_orig = coords_frac_wrap + plus tr = crys.Trajectory(coords_frac=coords_frac_orig, cell=np.identity(3) * 2.0, symbols=['H'] * 100) tr_wrap = crys.pbc_wrap(tr, xyz_axis=-1) assert (tr.coords_frac == coords_frac_orig).all() assert (tr.coords == coords_frac_orig * 2.0).all() assert np.allclose(coords_frac_orig[plus == 0], tr_wrap.coords_frac[plus == 0]) assert np.allclose(coords_frac_orig[plus == -1] + 1, tr_wrap.coords_frac[plus == -1]) assert np.allclose(coords_frac_orig[plus == 1] - 1, tr_wrap.coords_frac[plus == 1]) assert np.allclose(coords_frac_wrap, tr_wrap.coords_frac) assert np.allclose(coords_frac_wrap, tr_wrap.coords / 2.0) tr_wrap = crys.pbc_wrap(tr, mask=[True, True, False], xyz_axis=-1) assert np.allclose(tr.coords_frac[..., 2], tr_wrap.coords_frac[..., 2])
rand = np.random.rand # Cubic box with random points and L=20, so rmax_auto=10. We randomly choose # some atoms to be O, the rest H, which lets us test 2 selections. # # For rpdf(), g(r) goes to zero for r > 10 b/c the minimum image convention is # violated. VMD is correct up to 2*sqrt(0.5)*rmax_auto b/c they apply their # "spherical cap"-correction. # # norm_vmd: For debugging, we also calculate with norm_vmd=True, which results # in slightly wrong g(r) for the all-all case, while num_int is always correct. # # The blue curves rpdf(..., norm_vmd=False) are correct up to rmax_auto. t1 = crys.Trajectory(coords_frac=rand(100, 20, 3), cell=np.identity(3) * 20, symbols=['O'] * 5 + ['H'] * 15) sy = np.array(t1.symbols) dr = 0.1 rmax = 25 dct = { 'amask': [[sy == 'O', sy == 'H'], None], 'sel': [['name O', 'name H'], ['all', 'all']] } plots = [] for ii in range(2): amask = dct['amask'][ii] sel = dct['sel'][ii] title = sel[0] + ',' + sel[1]
def test_rpdf(): have_vmd = os.system('which vmd > /dev/null 2>&1') == 0 for name in ['rand_3d', 'aln_ibrav0_sc', 'aln_ibrav2_sc']: print(("name: %s" % name)) dd = 'files/rpdf' if name == 'rand_3d': # 2 Trajectory = 2 selections cell = np.loadtxt(pj(dd, name + '.cell.txt')) coords_frac = [ load_old(pj(dd, name + '.coords0.txt')), load_old(pj(dd, name + '.coords1.txt')) ] trajs = [ crys.Trajectory(coords_frac=cf, cell=cell) for cf in coords_frac ] for tr in trajs: assert tr.coords_frac.shape == (20, 10, 3) assert tr.nstep == 20 assert tr.natoms == 10 else: # one Structure struct = parse.CifFile(pj(dd, name + '.cif')).get_struct() trajs = [struct] cell = struct.cell ret = crys.rpdf(trajs, rmax=5.0, dr=0.05, pbc=True) # rpdf() -- compere w/ ref results = { 'rad': ret[:, 0], 'hist': ret[:, 1], 'num_int': ret[:, 2], 'rmax_auto': np.array(crys.rmax_smith(cell)), } for key, val in results.items(): print((" key: %s" % key)) ref_fn = pj(dd, "result.%s.%s.txt" % (key, name)) print((" reference file: %s" % ref_fn)) ref = np.loadtxt(ref_fn) if doplot: plt.figure() plt.plot(ref, '.-', label='ref') plt.plot(val, '.-', label='val') plt.legend() plt.title(key) else: # decimal=3 b/c ref data created w/ older implementation, # slight numerical noise np.testing.assert_array_almost_equal(ref, val, decimal=3) print((" key: %s ... ok" % key)) # API if name.startswith('aln_'): sy = np.array(trajs[0].symbols) ret1 = crys.rpdf(trajs, dr=0.1, amask=[sy == 'Al', sy == 'N']) ret2 = crys.rpdf(trajs, dr=0.1, amask=['Al', 'N']) aae(ret1, ret2) # API: # [traj, traj] # [traj] # traj traj = crys.Trajectory(coords_frac=rand(100, 20, 3), cell=np.identity(3) * 20, symbols=['O'] * 5 + ['H'] * 15) ret1 = crys.rpdf([traj, traj], rmax=5.0, dr=0.05, pbc=True) ret2 = crys.rpdf([traj], rmax=5.0, dr=0.05, pbc=True) aae(ret1, ret2) ret3 = crys.rpdf(traj, rmax=5.0, dr=0.05, pbc=True) aae(ret1, ret3) # dmask ret = crys.rpdf(traj, rmax=5.0, dr=0.05, dmask='>=2.0') msk = ret[:, 0] >= 2.0 imsk = np.invert(msk) assert (ret[msk, 1] > 0.0).any() assert (ret[imsk, 1] == 0.0).all() ret = crys.rpdf(traj, rmax=5.0, dr=0.05, dmask='{d}>=2.0') assert (ret[msk, 1] > 0.0).any() assert (ret[imsk, 1] == 0.0).all() ret = crys.rpdf(traj, rmax=5.0, dr=0.05, dmask='({d} >= 1.0) & ({d} <= 3.0)') msk = (ret[:, 0] >= 1.0) & (ret[:, 0] <= 3.0) imsk = np.invert(msk) assert (ret[msk, 1] > 0.0).any() assert (ret[imsk, 1] == 0.0).all() if have_vmd: # slicefirst and API print("vmd_measure_gofr: slicefirst ...") traj = crys.Trajectory(coords_frac=rand(100, 20, 3), cell=np.identity(3) * 20, symbols=['O'] * 5 + ['H'] * 15) for first, last, step in [(0, -1, 1), (20, 80, 10)]: ret = [] for sf in [True, False]: print("first=%i, last=%i, step=%i, slicefirst=%s" % (first, last, step, sf)) tmp = crys.vmd_measure_gofr( traj, dr=0.1, rmax='auto', sel=['all', 'all'], slicefirst=sf, first=first, last=last, step=step, usepbc=1, tmpdir=testdir, verbose=False, ) ret.append(tmp) assert np.allclose(ret[0][:, 0], ret[1][:, 0]) assert np.allclose(ret[0][:, 1], ret[1][:, 1]) assert np.allclose(ret[0][:, 2], ret[1][:, 2]) # API call_vmd_measure_gofr() trajfn = pj(testdir, 'vmd_xsf_call_vmd_measure_gofr') data = io.write_axsf(trajfn, traj) ret = crys.call_vmd_measure_gofr(trajfn, dr=0.1, rmax=10, sel=['all', 'all'], fntype='xsf', first=0, last=-1, step=1, usepbc=1, datafn=None, scriptfn=None, logfn=None, tmpdir=testdir, verbose=False) # compare results, up to L/2 = rmax_auto = 10 = rmax_smith(cell) # all-all, hist will differ rmax = 10 vmd = crys.vmd_measure_gofr(traj, dr=0.1, sel=['all', 'all'], rmax=10) pwt = crys.rpdf(traj, dr=0.1, amask=None, rmax=10) assert np.allclose(vmd[:-1, 0], pwt[:, 0]) # rad ##assert np.allclose(vmd[:-1,1], pwt[:,1]) # hist assert np.allclose(vmd[:-1, 2], pwt[:, 2]) # num_int # 2 selections, all ok sy = np.array(traj.symbols) vmd = crys.vmd_measure_gofr(traj, dr=0.1, sel=['name O', 'name H'], rmax=10) pwt = crys.rpdf(traj, dr=0.1, amask=[sy == 'O', sy == 'H'], rmax=10) assert np.allclose(vmd[:-1, 0], pwt[:, 0]) # rad assert np.allclose(vmd[:-1, 1], pwt[:, 1]) # hist assert np.allclose(vmd[:-1, 2], pwt[:, 2]) # num_int if doplot: plt.show()
def test_rms(): natoms = 5 nstep = 10 arr1 = np.random.rand(nstep, 3, natoms) arr2 = np.random.rand(natoms, nstep, 3) arr3 = np.random.rand(natoms, 3, nstep) # Test if rms() works. r3_rms_all1 = crys.rms(arr3, nitems='all') r3_rms_natoms1 = crys.rms(arr3, nitems=natoms) r3_rms_all2 = np.sqrt((arr3**2.0).sum() / float(3 * natoms * nstep)) r3_rms_natoms2 = np.sqrt((arr3**2.0).sum() / float(natoms)) np.testing.assert_almost_equal(r3_rms_all1, r3_rms_all2) np.testing.assert_almost_equal(r3_rms_natoms1, r3_rms_natoms2) # Test if rms3d() operates correctly along each axis. r1_3d = crys.rms3d(arr1, axis=0, nitems='all') r2_3d = crys.rms3d(arr2, axis=1, nitems='all') r3_3d = crys.rms3d(arr3, axis=2, nitems='all') r1_loop = np.empty((nstep, ), dtype=float) r2_loop = np.empty((nstep, ), dtype=float) r3_loop = np.empty((nstep, ), dtype=float) for k in range(nstep): r1_loop[k] = crys.rms(arr1[k, ...], nitems='all') r2_loop[k] = crys.rms(arr2[:, k, :], nitems='all') r3_loop[k] = crys.rms(arr3[..., k], nitems='all') np.testing.assert_array_almost_equal(r1_3d, r1_loop) np.testing.assert_array_almost_equal(r2_3d, r2_loop) np.testing.assert_array_almost_equal(r3_3d, r3_loop) # Test if rmsd() works. # # NOTE: Subtle numpy issue here: # It is very important NOT to use # R -= R[...,0][...,None] # or # for k in range(R.shape[-1]): # R[...,k] -= R[...,0][...,None] # because R itself is changed in the loop! You have to copy the reference # R[...,0] first and then broadcast it for subtracting. What also works is # this: # R = R - R[...,0][...,None] # HOWEVER, THIS DOES NOT: # for k in range(R.shape[-1]): # R[...,k] = R[...,k] - R[...,0][...,None] traj = crys.Trajectory(coords=np.random.rand(nstep, natoms, 3)) assert traj.timeaxis == 0 assert traj.nstep == nstep from_rmsd = crys.rmsd(traj, ref_idx=0) from_loop = np.empty((nstep, ), dtype=float) from_rms3d = crys.rms3d(traj.coords - traj.coords[0, ...][None, ...], nitems=natoms, axis=0) R = traj.coords.copy() ref = R[0, ...].copy() for k in range(nstep): R[k, ...] -= ref from_loop[k] = np.sqrt((R[k, ...]**2.0).sum() / natoms) np.testing.assert_array_almost_equal(from_rmsd, from_loop) np.testing.assert_array_almost_equal(from_rmsd, from_rms3d)