Source code for tests.test_dataframes

import copy
import pathlib
import tempfile
import unittest

import numpy as np
import uncertainties

from hikari.dataframes import BaseFrame, CifBlock, CifFrame, HklFrame, \
    UBaseFrame
from hikari.dataframes.cif import CifValidator
from hikari.symmetry import PG

RAD60 = 1.0471975511965976
RAD70 = 1.2217304763960306
RAD80 = 1.3962634015954636
RAD90 = 1.5707963267948966

U1 = uncertainties.ufloat(1, 1)
U6 = uncertainties.ufloat(6.0, 0.1)
U7 = uncertainties.ufloat(7.0, 0.1)
U8 = uncertainties.ufloat(8.0, 0.1)
U60 = uncertainties.ufloat(60.0, 1.0)
U70 = uncertainties.ufloat(70.0, 1.0)
U80 = uncertainties.ufloat(80.0, 1.0)
U90 = uncertainties.ufloat(90.0, 1.0)


nacl_cif_path = str(pathlib.Path(__file__).parent.joinpath('NaCl.cif'))
nacl_fcf_path = str(pathlib.Path(__file__).parent.joinpath('NaCl.fcf'))
nacl_hkl_path = str(pathlib.Path(__file__).parent.joinpath('NaCl.hkl'))


[docs] class TestBaseFrame(unittest.TestCase):
[docs] def setUp(self) -> None: self.b = BaseFrame() self.b.edit_cell(a=6, b=7, c=8, al=60, be=70, ga=80)
[docs] def test_init(self): b = BaseFrame() self.assertAlmostEqual(b.a_d, 1.) self.assertAlmostEqual(b.b_d, 1.) self.assertAlmostEqual(b.c_d, 1.) self.assertAlmostEqual(b.al_d, RAD90) self.assertAlmostEqual(b.be_d, RAD90) self.assertAlmostEqual(b.ga_d, RAD90)
[docs] def test_edit_cell(self): self.assertAlmostEqual(self.b.a_d, 6.) self.assertAlmostEqual(self.b.b_d, 7.) self.assertAlmostEqual(self.b.c_d, 8.) self.assertAlmostEqual(self.b.al_d, RAD60) self.assertAlmostEqual(self.b.be_d, RAD70) self.assertAlmostEqual(self.b.ga_d, RAD80) with self.assertRaises(KeyError): BaseFrame().edit_cell(alpha=0.0)
[docs] def test_reciprocal_cell(self): self.assertAlmostEqual(self.b.a_r, 0.1773638940193107) self.assertAlmostEqual(self.b.b_r, 0.1649580865234412) self.assertAlmostEqual(self.b.c_r, 0.1512680839136182) self.assertAlmostEqual(self.b.al_r, 2.067032910195549) self.assertAlmostEqual(self.b.be_r, 1.874672323582712) self.assertAlmostEqual(self.b.ga_r, 1.574038054665492)
[docs] def test_vectors(self): expected_a_v = np.array([6.00000000, 0.00000000, 0.00000000]) expected_b_v = np.array([1.21553724, 6.89365427, 0.00000000]) expected_c_v = np.array([2.73616115, 3.57924741, 6.61077984]) expected_a_w = np.array([0.16666667, -0.02938783, -0.05307098]) expected_b_w = np.array([0.00000000, 0.14506094, -0.07853975]) expected_c_w = np.array([0.00000000, 0.00000000, 0.15126808]) self.assertAlmostEqual(sum(self.b.a_v - expected_a_v), 0.) self.assertAlmostEqual(sum(self.b.b_v - expected_b_v), 0.) self.assertAlmostEqual(sum(self.b.c_v - expected_c_v), 0.) self.assertAlmostEqual(sum(self.b.a_w - expected_a_w), 0.) self.assertAlmostEqual(sum(self.b.b_w - expected_b_w), 0.) self.assertAlmostEqual(sum(self.b.c_w - expected_c_w), 0.)
[docs] def test_perpendicular(self): def norm(v): return v / np.sqrt(v.dot(v)) av, bv, cv = self.b.a_v, self.b.b_v, self.b.c_v aw, bw, cw = self.b.a_w, self.b.b_w, self.b.c_w self.assertAlmostEqual(sum(norm(np.cross(av, bv)) - norm(cw)), 0.) self.assertAlmostEqual(sum(norm(np.cross(bv, cv)) - norm(aw)), 0.) self.assertAlmostEqual(sum(norm(np.cross(cv, av)) - norm(bw)), 0.) self.assertAlmostEqual(sum(norm(np.cross(aw, bw)) - norm(cv)), 0.) self.assertAlmostEqual(sum(norm(np.cross(bw, cw)) - norm(av)), 0.) self.assertAlmostEqual(sum(norm(np.cross(cw, aw)) - norm(bv)), 0.)
[docs] def test_matrices(self): v = np.array([1.6180339887, 2.7182818285, 3.1415926536]) self.assertAlmostEqual(v @ self.b.G_d @ v, 1797.2495106787824) self.assertAlmostEqual(v @ self.b.G_r @ v, 0.2238961843294296) self.assertAlmostEqual(sum(sum(self.b.G_d@self.b.A_r - self.b.A_d)), 0.) self.assertAlmostEqual(sum(sum(self.b.G_r@self.b.A_d - self.b.A_r)), 0.)
[docs] def test_volumes(self): self.assertAlmostEqual(self.b.v_d, 273.4345841924758) self.assertAlmostEqual(self.b.v_r, 0.003657181855591761)
[docs] class TestCifFrameReader(unittest.TestCase):
[docs] def setUp(self) -> None: self.c = CifFrame()
[docs] def test_read_cif_file(self): self.c.read(nacl_cif_path) self.assertIn('NaCl', self.c) self.assertIsInstance(self.c['NaCl'], CifBlock)
[docs] def test_read_fcf_file(self): self.c.read(nacl_fcf_path) self.assertIn('NaCl', self.c) self.assertIsInstance(self.c['NaCl'], CifBlock)
[docs] class TestCifBlockReader(unittest.TestCase):
[docs] def setUp(self) -> None: self.b = CifBlock()
[docs] def test_read(self): self.b.read(path=nacl_cif_path, block='NaCl') self.assertIn('_audit_creation_date', self.b) self.assertIsInstance(self.b, CifBlock)
[docs] def test_read_loop(self): self.b.read(nacl_cif_path, 'NaCl') self.assertEqual(self.b['_atom_type_symbol'], ['Cl', 'Na']) self.assertEqual(len(self.b['_space_group_symop_operation_xyz']), 192)
[docs] class TestCifBlockGeneral(unittest.TestCase): b = CifBlock()
[docs] @classmethod def setUpClass(cls) -> None: cls.b.read(path=nacl_cif_path, block='NaCl')
[docs] def test_access_existing(self): self.assertEqual(self.b['_cell_length_a'], '5.64109(5)') self.assertEqual(len(self.b['_diffrn_refln_index_h']), 8578)
[docs] def test_access_nonexistent(self): with self.assertRaises(KeyError): _ = self.b['_nonexistent_key']
[docs] def test_assign(self): self.b['_cell_angle_beta'] = '120' self.assertEqual(self.b['_cell_angle_beta'], '120') self.b['_fictitious_list'] = ['f', 'i', 'c'] self.assertEqual(self.b['_fictitious_list'], ['f', 'i', 'c'])
[docs] def test_contains(self): self.assertIn('_cell_length_a', self.b) self.assertNotIn('_nonexistent_key', self.b)
[docs] def test_get(self): self.assertEqual(self.b.get('_cell_length_a'), '5.64109(5)')
[docs] def test_get_nonexistent(self): self.assertIs(self.b.get('_nonexistent_key'), None)
[docs] def test_get_with_default(self): self.assertEqual(self.b.get('_nonexistent_key', 'default'), 'default')
[docs] def test_get_as_type_single(self): k = '_cell_angle_alpha' self.assertEqual(self.b.get_as_type(k, typ=str), '90') self.assertEqual(self.b.get_as_type(k, typ=int), 90) u_typ = uncertainties.ufloat_fromstr self.assertEqual(repr(self.b.get_as_type(k, typ=u_typ)), repr(U90))
[docs] def test_get_as_type_list(self): k = '_atom_site_occupancy' self.assertEqual(self.b.get_as_type(k, typ=str), ['1', '1']) self.assertEqual(self.b.get_as_type(k, typ=int), [1, 1]) u_typ = uncertainties.ufloat_fromstr self.assertEqual(repr(self.b.get_as_type(k, typ=u_typ)), repr([U1, U1]))
[docs] def test_get_as_type_nonexistent(self): self.assertIs(self.b.get_as_type('_nonexistent_key', str), None)
[docs] def test_get_as_type_exceptions(self): self.b['_cell_angle_beta'] = U90 # CifBlock stores str and list types with self.assertRaises(TypeError): _ = self.b.get_as_type('_cell_angle_beta', str)
[docs] def test_get_as_type_defaults(self): self.assertEqual(self.b.get_as_type('_nonexistent_key', str, 'default'), 'default')
[docs] class TestCifBlockInterface(unittest.TestCase): b = CifBlock()
[docs] def test_base_frame_fill_from_cif_block_robust(self): self.b.read(path=nacl_cif_path, block='NaCl') base = BaseFrame() base.fill_from_cif_block(self.b, fragile=False) self.assertAlmostEqual(base.v_d, 179.51018149594705) self.assertAlmostEqual(base.orientation[0, 0], -0.0617076000)
[docs] def test_base_frame_fill_from_cif_block_fragile(self): self.b.read(path=nacl_cif_path, block='NaCl_olex2_C2/m') base = BaseFrame() with self.assertRaises(KeyError): base.fill_from_cif_block(self.b, fragile=True)
[docs] class TestCifValidator(unittest.TestCase): v = CifValidator()
[docs] def test_creation(self): self.assertTrue('_atom_site_label' in self.v) self.assertIn('_atom_site_label', self.v) self.assertIsInstance(self.v.get('_atom_site_label'), CifBlock)
[docs] def test_contains(self): self.assertIn('atom_site_fract_', self.v) self.assertIn('_atom_site_fract_', self.v) self.assertIn('_atom_site_fract_x', self.v)
[docs] def test_get(self): self.assertEqual(self.v.get('atom_site_fract_')['_type'], 'numb') self.assertEqual(self.v.get('_atom_site_fract_')['_type'], 'numb') self.assertEqual(self.v.get('_atom_site_fract_x')['_type'], 'numb') self.assertIs(self.v.get('nonexistent_key'), None)
[docs] def test_get__category(self): cat = 'atom_site' self.assertEqual(self.v.get__category('atom_site_fract_'), cat) self.assertEqual(self.v.get__category('_atom_site_fract_'), cat) self.assertEqual(self.v.get__category('_atom_site_fract_x'), cat) self.assertEqual(self.v.get__category('nonexistent_key', 'def'), 'def')
[docs] def test_get__list(self): self.assertIs(self.v.get__list('atom_site_fract_'), True) self.assertIs(self.v.get__list('refine_ls_number_reflns'), None) self.assertEqual(self.v.get__list('exptl_crystal_colour'), None) self.assertEqual(self.v.get__list('nonexistent_key', 'def'), 'def')
[docs] class TestCifWriter(unittest.TestCase): temp_dir = tempfile.TemporaryDirectory() temp_path1 = str(pathlib.Path(temp_dir.name) / 'temp1.cif') temp_path2 = str(pathlib.Path(temp_dir.name) / 'temp2.cif')
[docs] @classmethod def tearDownClass(cls) -> None: cls.temp_dir.cleanup()
[docs] def setUp(self) -> None: self.c_cif1 = CifFrame() self.c_cif2 = CifFrame() self.c_cif1.read(nacl_cif_path)
[docs] def test_write_cif_file(self): self.c_cif1.write(self.temp_path1)
[docs] def test_write_cif_file_is_consistent(self): self.c_cif1.write(self.temp_path1) self.c_cif2.read(self.temp_path1) self.c_cif2.write(self.temp_path2) with open(self.temp_path1, 'r') as cif1_contents: with open(self.temp_path2, 'r') as cif2_contents: self.assertEqual(cif1_contents.read(), cif2_contents.read())
[docs] class TestHklFrame(unittest.TestCase): h1 = HklFrame() h2 = HklFrame()
[docs] @classmethod def setUpClass(cls) -> None: cls.h1.read(nacl_hkl_path, hkl_format='shelx_4') cls.h1.edit_cell(a=5.64109, b=5.64109, c=5.64109)
[docs] def setUp(self) -> None: self.h2 = copy.deepcopy(self.h1)
[docs] def test_len(self): self.assertEqual(len(self.h1), 8578)
[docs] def test_add(self): h3 = self.h1 + self.h2 self.assertEqual(len(h3), 17156) self.assertIsInstance(h3, HklFrame)
[docs] def test_str(self): str_h = str(self.h1) self.assertIn('h', str_h[:300]) self.assertIn('52001.5', str_h[:300]) self.assertIn('419.465', str_h[-300:])
[docs] def test_read(self): self.h2.read(nacl_hkl_path, hkl_format='free_4') self.assertEqual(self.h2.table.__len__(), 8578)
[docs] def test_write(self): temp_dir = tempfile.TemporaryDirectory() temp_path = str(pathlib.Path(temp_dir.name) / 'temp.hkl') self.h2.write(hkl_path=temp_path, hkl_format='shelx_40') self.h2.read(nacl_hkl_path, hkl_format='shelx_40') self.assertEqual(self.h2.table.__len__(), 8578) temp_dir.cleanup()
[docs] def test_la_and_r_lim(self): self.h2.la = 0.50 self.assertAlmostEqual(self.h2.la, 0.50) self.assertAlmostEqual(self.h2.r_lim, 4.0) self.h2.la = 'AgKa' self.assertAlmostEqual(self.h2.la, 0.5608) self.assertAlmostEqual(self.h2.r_lim, 3.56633380884)
[docs] def test_copy(self): h = self.h1.copy() self.assertEqual(str(h), str(self.h1))
[docs] def test_find_equivalents(self): self.h2.find_equivalents() self.assertEqual(self.h2.table['equiv'].nunique(), 2861) self.h2.find_equivalents(point_group=PG['m-3m']) self.assertEqual(self.h2.table['equiv'].nunique(), 111)
[docs] def test_place(self): self.h2.place() xyz = self.h2.table.loc[:, ['x', 'y', 'z']].to_numpy() expected_xyz_sum = np.array([882.09902696, 1188.0682634, 516.21229231]) expected_xyz_mean = np.array([0.102832710, 0.1385017800, 0.0601786300]) self.assertAlmostEqual(xyz.max(), 2.4817898668519733) self.assertAlmostEqual(xyz.sum(), 2586.379582669306) self.assertAlmostEqual(sum(xyz.sum(axis=0) - expected_xyz_sum), 0.0) self.assertAlmostEqual(sum(xyz.mean(axis=0) - expected_xyz_mean), 0.0)
[docs] def test_fill(self): self.h2.fill(radius=2.0) self.assertEqual(len(self.h2), 6030) self.h2.edit_cell(a=3, b=10, c=30) self.h2.fill(radius=2.0) self.assertEqual(len(self.h2), 29872) self.h2.edit_cell(a=10, b=10, c=10, al=100, be=100, ga=100) self.h2.fill(radius=2.0) self.assertEqual(len(self.h2), 31734) self.h2.edit_cell(a=99, b=99, c=99) with self.assertRaises(ValueError): self.h2.fill(radius=2.0)
[docs] def test_trim(self): self.h2.place() self.h2.trim(limit=1.2) self.h2.find_equivalents(point_group=PG['m-3m']) self.assertEqual(len(self.h2), 1761) self.assertEqual(self.h2.table['equiv'].nunique(), 18)
[docs] def test_dac_trim(self): self.h2.place() self.h2.dac_trim(opening_angle=30, vector=np.array([1, 0, 0])) self.h2.find_equivalents(point_group=PG['m-3m']) self.assertEqual(len(self.h2), 434) self.assertEqual(self.h2.table['equiv'].nunique(), 10)
[docs] def test_merge(self): self.h2.merge(point_group=PG['12/m1']) self.assertEqual(len(self.h2.table), 831) self.h2.merge(point_group=PG['4/m']) self.assertEqual(len(self.h2.table), 390) self.h2.merge(point_group=PG['m-3']) self.assertEqual(len(self.h2.table), 159) self.h2.merge(point_group=PG['m-3m']) self.assertEqual(len(self.h2.table), 111)
[docs] def test_transform_single(self): ops = np.array([[1, 0, 0], [0, -1, 0], [0, 0, -1]]) sum1_h, sum1_k, sum1_l = self.h2.table.sum(axis=0)[['h', 'k', 'l']] self.h2.transform(ops) sum2_h, sum2_k, sum2_l = self.h2.table.sum(axis=0)[['h', 'k', 'l']] self.assertEqual((sum1_h, sum1_k, sum1_l), (sum2_h, -sum2_k, -sum2_l))
[docs] def test_transform_list(self): ops = [np.eye(3), -np.eye(3)] self.h2.transform(ops) sum_h, sum_k, sum_l = self.h2.table.sum(axis=0)[['h', 'k', 'l']] self.assertEqual((0, 0, 0), (sum_h, sum_k, sum_h))
[docs] def test_thin_out(self): l1 = len(self.h2) self.h2.thin_out(target_cplt=0.321) self.assertAlmostEqual(0.321 * l1, len(self.h2), delta=1.0)
[docs] @staticmethod def assertIsFile(path): if not pathlib.Path(path).resolve().is_file(): raise AssertionError("File does not exist: %s" % str(path))
[docs] def test_to_res(self): temp_dir = tempfile.TemporaryDirectory() temp_path = str(pathlib.Path(temp_dir.name) / 'temp_hkl.res') self.h2.to_res(temp_path) self.assertIsFile(temp_path) temp_dir.cleanup()
[docs] class TestUBaseFrame(unittest.TestCase):
[docs] def setUp(self) -> None: self.b = UBaseFrame() self.b.edit_cell(a=U6, b=U7, c=U8, al=U60, be=U70, ga=U80)
[docs] def test_init(self): b = UBaseFrame() self.assertAlmostEqual(b.a_d.n, 1) self.assertAlmostEqual(b.b_d.n, 1) self.assertAlmostEqual(b.c_d.n, 1) self.assertAlmostEqual(b.al_d.n, np.pi / 2) self.assertAlmostEqual(b.be_d.n, np.pi / 2) self.assertAlmostEqual(b.ga_d.n, np.pi / 2)
[docs] def test_edit_cell(self): self.assertAlmostEqual(self.b.a_d.n, 6) self.assertAlmostEqual(self.b.b_d.n, 7) self.assertAlmostEqual(self.b.c_d.n, 8) self.assertAlmostEqual(self.b.al_d.n, RAD60) self.assertAlmostEqual(self.b.be_d.n, RAD70) self.assertAlmostEqual(self.b.ga_d.n, RAD80) with self.assertRaises(KeyError): BaseFrame().edit_cell(alpha=0.0)
[docs] def test_reciprocal_cell(self): self.assertAlmostEqual(self.b.a_r.n, 0.1773638940193107) self.assertAlmostEqual(self.b.b_r.n, 0.1649580865234412) self.assertAlmostEqual(self.b.c_r.n, 0.1512680839136182) self.assertAlmostEqual(self.b.al_r.n, 2.067032910195549) self.assertAlmostEqual(self.b.be_r.n, 1.874672323582712) self.assertAlmostEqual(self.b.ga_r.n, 1.574038054665492)
[docs] def test_vectors(self): expected_a_v = np.array([6.00000000, 0.00000000, 0.00000000]) expected_b_v = np.array([1.21553724, 6.89365427, 0.00000000]) expected_c_v = np.array([2.73616115, 3.57924741, 6.61077984]) expected_a_w = np.array([0.16666667, -0.02938783, -0.05307098]) expected_b_w = np.array([0.00000000, 0.14506094, -0.07853975]) expected_c_w = np.array([0.00000000, 0.00000000, 0.15126808]) self.assertAlmostEqual(sum(self.b.a_v - expected_a_v).n, 0.) self.assertAlmostEqual(sum(self.b.b_v - expected_b_v).n, 0.) self.assertAlmostEqual(sum(self.b.c_v - expected_c_v).n, 0.) self.assertAlmostEqual(sum(self.b.a_w - expected_a_w).n, 0.) self.assertAlmostEqual(sum(self.b.b_w - expected_b_w).n, 0.) self.assertAlmostEqual(sum(self.b.c_w - expected_c_w).n, 0.)
[docs] def test_perpendicular(self): def norm(v): return v / (v.dot(v) ** (1/2)) av, bv, cv = self.b.a_v, self.b.b_v, self.b.c_v aw, bw, cw = self.b.a_w, self.b.b_w, self.b.c_w self.assertAlmostEqual(sum(norm(np.cross(av, bv)) - norm(cw)).n, 0.) self.assertAlmostEqual(sum(norm(np.cross(bv, cv)) - norm(aw)).n, 0.) self.assertAlmostEqual(sum(norm(np.cross(cv, av)) - norm(bw)).n, 0.) self.assertAlmostEqual(sum(norm(np.cross(aw, bw)) - norm(cv)).n, 0.) self.assertAlmostEqual(sum(norm(np.cross(bw, cw)) - norm(av)).n, 0.) self.assertAlmostEqual(sum(norm(np.cross(cw, aw)) - norm(bv)).n, 0.)
[docs] def test_matrices(self): v = np.array([1.6180339887, 2.7182818285, 3.1415926536]) self.assertAlmostEqual((v @ self.b.G_d @ v).n, 1797.2495106787824) self.assertAlmostEqual((v @ self.b.G_r @ v).n, 0.2238961843294296) self.assertAlmostEqual(sum(sum(self.b.G_d @ self.b.A_r - self.b.A_d)).n, 0.) self.assertAlmostEqual(sum(sum(self.b.G_r @ self.b.A_d - self.b.A_r)).n, 0.)
[docs] def test_volumes(self): self.assertAlmostEqual(self.b.v_d.n, 273.4345841924758) self.assertAlmostEqual(self.b.v_r.n, 0.003657181855591761)
if __name__ == '__main__': unittest.main()