class CoordinationGeometryFinderTest(unittest2.TestCase): def setUp(self): self.lgf = LocalGeometryFinder() self.lgf.setup_parameters(centering_type='standard') self.strategies = [SimplestChemenvStrategy(), SimpleAbundanceChemenvStrategy()] # def _strategy_test(self, strategy): # files = [] # for (dirpath, dirnames, filenames) in os.walk(json_files_dir): # files.extend(filenames) # break # # for ifile, json_file in enumerate(files): # with self.subTest(json_file=json_file): # f = open("{}/{}".format(json_files_dir, json_file), 'r') # dd = json.load(f) # f.close() # # atom_indices = dd['atom_indices'] # expected_geoms = dd['expected_geoms'] # # struct = Structure.from_dict(dd['structure']) # # struct = self.lgf.setup_structure(struct) # se = self.lgf.compute_structure_environments_detailed_voronoi(only_indices=atom_indices, # maximum_distance_factor=1.5) # # #All strategies should get the correct environment with their default parameters # strategy.set_structure_environments(se) # for ienv, isite in enumerate(atom_indices): # ce = strategy.get_site_coordination_environment(struct[isite]) # try: # coord_env = ce[0] # except TypeError: # coord_env = ce # #Check that the environment found is the expected one # self.assertEqual(coord_env, expected_geoms[ienv]) # # def test_simplest_chemenv_strategy(self): # strategy = SimplestChemenvStrategy() # self._strategy_test(strategy) # # def test_simple_abundance_chemenv_strategy(self): # strategy = SimpleAbundanceChemenvStrategy() # self._strategy_test(strategy) def test_perfect_environments(self): for coordination in range(1, 13): for mp_symbol in AllCoordinationGeometries().get_implemented_geometries(coordination=coordination, returned='mp_symbol'): with self.subTest(msg=mp_symbol, mp_symbol=mp_symbol): self.lgf.setup_test_perfect_environment(mp_symbol, randomness=False, indices='RANDOM', random_translation=True, random_rotation=True, random_scale=True) se = self.lgf.compute_structure_environments_detailed_voronoi(only_indices=[0], maximum_distance_factor=1.5) self.assertAlmostEqual(se.get_csm(0, mp_symbol)['symmetry_measure'], 0.0, msg='mp_symbol {} not recognized ...'.format(mp_symbol))
class LightStructureEnvironmentsTest(unittest.TestCase): @classmethod def setUpClass(cls): os.makedirs('tmp_dir') def setUp(self): self.lgf = LocalGeometryFinder() self.lgf.setup_parameters(centering_type='standard') self.strategies = [SimplestChemenvStrategy(), SimpleAbundanceChemenvStrategy()] def test_read_structure_environments(self): f = open("{}/{}".format(json_files_dir, 'test_T--4_FePO4_icsd_4266.json'), 'r') dd = json.load(f) f.close() atom_indices = dd['atom_indices'] struct = Structure.from_dict(dd['structure']) self.lgf.setup_structure(struct) se = self.lgf.compute_structure_environments_detailed_voronoi(only_indices=atom_indices, maximum_distance_factor=2.25) f = open('tmp_dir/se.json', 'w') json.dump(se.as_dict(), f) f.close() f = open('tmp_dir/se.json', 'r') dd = json.load(f) f.close() se2 = StructureEnvironments.from_dict(dd) self.assertEqual(se, se2) _strategy = SimplestChemenvStrategy() light_se = LightStructureEnvironments(_strategy, se) f = open('tmp_dir/light_se.json', 'w') json.dump(light_se.as_dict(), f) f.close() f = open('tmp_dir/light_se.json', 'r') dd = json.load(f) f.close() light_se2 = LightStructureEnvironments.from_dict(dd) self.assertEqual(light_se, light_se2) @classmethod def tearDownClass(cls): #Remove the directory in which the temporary files have been created shutil.rmtree('tmp_dir')
def compute_environments(chemenv_configuration): string_sources = { 'cif': { 'string': 'a Cif file', 'regexp': '.*\.cif$' }, 'mp': { 'string': 'the Materials Project database', 'regexp': 'mp-[0-9]+$' } } questions = {'c': 'cif'} if chemenv_configuration.has_materials_project_access: questions['m'] = 'mp' lgf = LocalGeometryFinder() lgf.setup_parameters() allcg = AllCoordinationGeometries() strategy_class = strategies_class_lookup[ chemenv_configuration.package_options['default_strategy']['strategy']] #TODO: Add the possibility to change the parameters and save them in the chemenv_configuration default_strategy = strategy_class() default_strategy.setup_options( chemenv_configuration.package_options['default_strategy'] ['strategy_options']) firsttime = True while True: if len(questions) > 1: found = False print( 'Enter the source from which the structure is coming or <q> to quit :' ) for key_character, qq in questions.items(): print(' - <{}> for a structure from {}'.format( key_character, string_sources[qq]['string'])) test = input(' ... ') if test == 'q': break if test not in list(questions.keys()): for key_character, qq in questions.items(): print(test) print(test.__class__) print(string_sources[qq]['regexp'].__class__) if re.match(string_sources[qq]['regexp'], str(test)) is not None: found = True source_type = qq if not found: print('Wrong key, try again ...') continue else: source_type = questions[test] else: found = False source_type = list(questions.values())[0] if found and len(questions) > 1: input_source = test if source_type == 'cif': if not found: input_source = input('Enter path to cif file : ') cp = CifParser(input_source) structure = cp.get_structures()[0] elif source_type == 'mp': if not found: input_source = input( 'Enter materials project id (e.g. "mp-1902") : ') a = MPRester(chemenv_configuration.materials_project_api_key) structure = a.get_structure_by_material_id(input_source) lgf.setup_structure(structure) print('Computing environments for {} ... '.format( structure.composition.reduced_formula)) se = lgf.compute_structure_environments_detailed_voronoi() print('Computing environments finished') while True: test = input( 'See list of environments determined for each (unequivalent) site ? ' '("y" or "n", "d" with details, "g" to see the grid) : ') strategy = default_strategy if test in ['y', 'd', 'g']: strategy.set_structure_environments(se) for eqslist in se.equivalent_sites: site = eqslist[0] isite = se.structure.index(site) try: if strategy.uniquely_determines_coordination_environments: ces = strategy.get_site_coordination_environments( site) else: ces = strategy.get_site_coordination_environments_fractions( site) except NeighborsNotComputedChemenvError: continue if ces is None: continue if len(ces) == 0: continue comp = site.species_and_occu #ce = strategy.get_site_coordination_environment(site) if strategy.uniquely_determines_coordination_environments: ce = ces[0] if ce is None: continue thecg = allcg.get_geometry_from_mp_symbol(ce[0]) mystring = 'Environment for site #{} {} ({}) : {} ({})\n'.format( str(isite), comp.get_reduced_formula_and_factor()[0], str(comp), thecg.name, ce[0]) else: mystring = 'Environments for site #{} {} ({}) : \n'.format( str(isite), comp.get_reduced_formula_and_factor()[0], str(comp)) for ce in ces: cg = allcg.get_geometry_from_mp_symbol(ce[0]) mystring += ' - {} ({}): {:.2f} % (csm : {:2f})\n'.format( cg.name, cg.mp_symbol, 100.0 * ce[2], ce[1]['symmetry_measure']) if test in [ 'd', 'g' ] and strategy.uniquely_determines_coordination_environments: if thecg.mp_symbol != UNCLEAR_ENVIRONMENT_SYMBOL: mystring += ' <Continuous symmetry measures> ' mingeoms = se.ce_list[isite][ thecg. coordination_number][0].minimum_geometries() for mingeom in mingeoms: mystring += '{} : {:.2f} '.format( mingeom[0], mingeom[1]['symmetry_measure']) print(mystring) if test == 'g': test = input( 'Enter index of site(s) for which you want to see the grid of parameters : ' ) indices = list(map(int, test.split())) print(indices) for isite in indices: se.plot_environments(isite, additional_condition=se.AC.ONLY_ACB) if no_vis: test = input('Go to next structure ? ("y" to do so)') if test == 'y': break continue test = input( 'View structure with environments ? ("y" for the unit cell or "m" for a supercell or "n") : ' ) if test in ['y', 'm']: if test == 'm': mydeltas = [] test = input('Enter multiplicity (e.g. 3 2 2) : ') nns = test.split() for i0 in range(int(nns[0])): for i1 in range(int(nns[1])): for i2 in range(int(nns[2])): mydeltas.append( np.array([1.0 * i0, 1.0 * i1, 1.0 * i2], np.float)) else: mydeltas = [np.zeros(3, np.float)] if firsttime: vis = StructureVis(show_polyhedron=False, show_unit_cell=True) vis.show_help = False firsttime = False vis.set_structure(se.structure) strategy.set_structure_environments(se) for isite, site in enumerate(se.structure): try: ces = strategy.get_site_coordination_environments(site) except NeighborsNotComputedChemenvError: continue if len(ces) == 0: continue ce = strategy.get_site_coordination_environment(site) if ce is not None and ce[0] != UNCLEAR_ENVIRONMENT_SYMBOL: for mydelta in mydeltas: psite = PeriodicSite(site._species, site._fcoords + mydelta, site._lattice, properties=site._properties) vis.add_site(psite) neighbors = strategy.get_site_neighbors(psite) draw_cg(vis, psite, neighbors, cg=lgf.cg.get_geometry_from_mp_symbol( ce[0]), perm=ce[1]['permutation']) vis.show() test = input('Go to next structure ? ("y" to do so) : ') if test == 'y': break print('')
def compute_environments(chemenv_configuration): string_sources = {'cif': {'string': 'a Cif file', 'regexp': '.*\.cif$'}, 'mp': {'string': 'the Materials Project database', 'regexp': 'mp-[0-9]+$'}} questions = {'c': 'cif'} if chemenv_configuration.has_materials_project_access: questions['m'] = 'mp' lgf = LocalGeometryFinder() lgf.setup_parameters() allcg = AllCoordinationGeometries() strategy_class = strategies_class_lookup[chemenv_configuration.package_options['default_strategy']['strategy']] #TODO: Add the possibility to change the parameters and save them in the chemenv_configuration default_strategy = strategy_class() default_strategy.setup_options(chemenv_configuration.package_options['default_strategy']['strategy_options']) max_dist_factor = chemenv_configuration.package_options['default_max_distance_factor'] firsttime = True while True: if len(questions) > 1: found = False print('Enter the source from which the structure is coming or <q> to quit :') for key_character, qq in questions.items(): print(' - <{}> for a structure from {}'.format(key_character, string_sources[qq]['string'])) test = input(' ... ') if test == 'q': break if test not in list(questions.keys()): for key_character, qq in questions.items(): if re.match(string_sources[qq]['regexp'], str(test)) is not None: found = True source_type = qq if not found: print('Wrong key, try again ...') continue else: source_type = questions[test] else: found = False source_type = list(questions.values())[0] if found and len(questions) > 1: input_source = test if source_type == 'cif': if not found: input_source = input('Enter path to cif file : ') cp = CifParser(input_source) structure = cp.get_structures()[0] elif source_type == 'mp': if not found: input_source = input('Enter materials project id (e.g. "mp-1902") : ') a = MPRester(chemenv_configuration.materials_project_api_key) structure = a.get_structure_by_material_id(input_source) lgf.setup_structure(structure) print('Computing environments for {} ... '.format(structure.composition.reduced_formula)) se = lgf.compute_structure_environments_detailed_voronoi(maximum_distance_factor=max_dist_factor) print('Computing environments finished') while True: test = input('See list of environments determined for each (unequivalent) site ? ' '("y" or "n", "d" with details, "g" to see the grid) : ') strategy = default_strategy if test in ['y', 'd', 'g']: strategy.set_structure_environments(se) for eqslist in se.equivalent_sites: site = eqslist[0] isite = se.structure.index(site) try: if strategy.uniquely_determines_coordination_environments: ces = strategy.get_site_coordination_environments(site) else: ces = strategy.get_site_coordination_environments_fractions(site) except NeighborsNotComputedChemenvError: continue if ces is None: continue if len(ces) == 0: continue comp = site.species_and_occu #ce = strategy.get_site_coordination_environment(site) if strategy.uniquely_determines_coordination_environments: ce = ces[0] if ce is None: continue thecg = allcg.get_geometry_from_mp_symbol(ce[0]) mystring = 'Environment for site #{} {} ({}) : {} ({})\n'.format(str(isite), comp.get_reduced_formula_and_factor()[0], str(comp), thecg.name, ce[0]) else: mystring = 'Environments for site #{} {} ({}) : \n'.format(str(isite), comp.get_reduced_formula_and_factor()[0], str(comp)) for ce in ces: cg = allcg.get_geometry_from_mp_symbol(ce[0]) csm = ce[1]['other_symmetry_measures']['csm_wcs_ctwcc'] mystring += ' - {} ({}): {:.2f} % (csm : {:2f})\n'.format(cg.name, cg.mp_symbol, 100.0*ce[2], csm) if test in ['d', 'g'] and strategy.uniquely_determines_coordination_environments: if thecg.mp_symbol != UNCLEAR_ENVIRONMENT_SYMBOL: mystring += ' <Continuous symmetry measures> ' mingeoms = se.ce_list[isite][thecg.coordination_number][0].minimum_geometries() for mingeom in mingeoms: csm = mingeom[1]['other_symmetry_measures']['csm_wcs_ctwcc'] mystring += '{} : {:.2f} '.format(mingeom[0], csm) print(mystring) if test == 'g': test = input('Enter index of site(s) for which you want to see the grid of parameters : ') indices = list(map(int, test.split())) print(indices) for isite in indices: se.plot_environments(isite, additional_condition=se.AC.ONLY_ACB) if no_vis: test = input('Go to next structure ? ("y" to do so)') if test == 'y': break continue test = input('View structure with environments ? ("y" for the unit cell or "m" for a supercell or "n") : ') if test in ['y', 'm']: if test == 'm': mydeltas = [] test = input('Enter multiplicity (e.g. 3 2 2) : ') nns = test.split() for i0 in range(int(nns[0])): for i1 in range(int(nns[1])): for i2 in range(int(nns[2])): mydeltas.append(np.array([1.0*i0, 1.0*i1, 1.0*i2], np.float)) else: mydeltas = [np.zeros(3, np.float)] if firsttime: vis = StructureVis(show_polyhedron=False, show_unit_cell=True) vis.show_help = False firsttime = False vis.set_structure(se.structure) strategy.set_structure_environments(se) for isite, site in enumerate(se.structure): try: ces = strategy.get_site_coordination_environments(site) except NeighborsNotComputedChemenvError: continue if len(ces) == 0: continue ce = strategy.get_site_coordination_environment(site) if ce is not None and ce[0] != UNCLEAR_ENVIRONMENT_SYMBOL: for mydelta in mydeltas: psite = PeriodicSite(site._species, site._fcoords + mydelta, site._lattice, properties=site._properties) vis.add_site(psite) neighbors = strategy.get_site_neighbors(psite) draw_cg(vis, psite, neighbors, cg=lgf.cg.get_geometry_from_mp_symbol(ce[0]), perm=ce[1]['permutation']) vis.show() test = input('Go to next structure ? ("y" to do so) : ') if test == 'y': break print('')
class CoordinationGeometryFinderTest(unittest2.TestCase): def setUp(self): self.lgf = LocalGeometryFinder() self.lgf.setup_parameters(centering_type='standard') self.strategies = [ SimplestChemenvStrategy(), SimpleAbundanceChemenvStrategy() ] # def _strategy_test(self, strategy): # files = [] # for (dirpath, dirnames, filenames) in os.walk(json_files_dir): # files.extend(filenames) # break # # for ifile, json_file in enumerate(files): # with self.subTest(json_file=json_file): # f = open("{}/{}".format(json_files_dir, json_file), 'r') # dd = json.load(f) # f.close() # # atom_indices = dd['atom_indices'] # expected_geoms = dd['expected_geoms'] # # struct = Structure.from_dict(dd['structure']) # # struct = self.lgf.setup_structure(struct) # se = self.lgf.compute_structure_environments_detailed_voronoi(only_indices=atom_indices, # maximum_distance_factor=1.5) # # #All strategies should get the correct environment with their default parameters # strategy.set_structure_environments(se) # for ienv, isite in enumerate(atom_indices): # ce = strategy.get_site_coordination_environment(struct[isite]) # try: # coord_env = ce[0] # except TypeError: # coord_env = ce # #Check that the environment found is the expected one # self.assertEqual(coord_env, expected_geoms[ienv]) # # def test_simplest_chemenv_strategy(self): # strategy = SimplestChemenvStrategy() # self._strategy_test(strategy) # # def test_simple_abundance_chemenv_strategy(self): # strategy = SimpleAbundanceChemenvStrategy() # self._strategy_test(strategy) def test_perfect_environments(self): indices_CN = { 1: [0], 2: [1, 0], 3: [1, 0, 2], 4: [2, 0, 3, 1], 5: [2, 3, 1, 0, 4], 6: [0, 2, 3, 1, 5, 4], 7: [2, 6, 0, 3, 4, 5, 1], 8: [1, 2, 6, 3, 7, 0, 4, 5], 9: [5, 2, 6, 0, 4, 7, 3, 8, 1], 10: [8, 5, 6, 3, 0, 7, 2, 4, 9, 1], 11: [7, 6, 4, 1, 2, 5, 0, 8, 9, 10, 3], 12: [5, 8, 9, 0, 3, 1, 4, 2, 6, 11, 10, 7], } for coordination in range(1, 13): for mp_symbol in AllCoordinationGeometries( ).get_implemented_geometries(coordination=coordination, returned='mp_symbol'): with self.subTest(msg=mp_symbol, mp_symbol=mp_symbol): self.lgf.setup_test_perfect_environment( mp_symbol, randomness=False, indices=indices_CN[coordination], random_translation='NONE', random_rotation='NONE', random_scale='NONE') se = self.lgf.compute_structure_environments_detailed_voronoi( only_indices=[0], maximum_distance_factor=1.5) self.assertAlmostEqual( se.get_csm(0, mp_symbol)['symmetry_measure'], 0.0, 4)