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 figure_fractions(self, weights_options, morphing_factors=None): if morphing_factors is None: morphing_factors = np.linspace(1.0, 2.0, 21) # Set up the local geometry finder lgf = LocalGeometryFinder() lgf.setup_parameters(structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE) # Set up the weights for the MultiWeights strategy weights = self.get_weights(weights_options) # Set up the strategy strat = MultiWeightsChemenvStrategy(dist_ang_area_weight=weights['DistAngArea'], self_csm_weight=weights['SelfCSM'], delta_csm_weight=weights['DeltaCSM'], cn_bias_weight=weights['CNBias'], angle_weight=weights['Angle'], normalized_angle_distance_weight=weights['NormalizedAngDist']) fake_valences = [-1] * (self.coordination_geometry.coordination_number + 1) fake_valences[0] = 1 fractions_initial_environment = np.zeros_like(morphing_factors) fractions_final_environment = np.zeros_like(morphing_factors) for ii, morphing_factor in enumerate(morphing_factors): print(ii) struct = self.get_structure(morphing_factor=morphing_factor) print(struct) # Get the StructureEnvironments lgf.setup_structure(structure=struct) se = lgf.compute_structure_environments(only_indices=[0], valences=fake_valences) strat.set_structure_environments(structure_environments=se) result = strat.get_site_coordination_environments_fractions(site=se.structure[0], isite=0, return_strategy_dict_info=True, return_all=True) for res in result: if res['ce_symbol'] == self.initial_environment_symbol: fractions_initial_environment[ii] = res['ce_fraction'] elif res['ce_symbol'] == self.expected_final_environment_symbol: fractions_final_environment[ii] = res['ce_fraction'] fig_width_cm = 8.25 fig_height_cm = 7.0 fig_width = fig_width_cm / 2.54 fig_height = fig_height_cm / 2.54 fig = plt.figure(num=1, figsize=(fig_width, fig_height)) subplot = fig.add_subplot(111) subplot.plot(morphing_factors, fractions_initial_environment, 'b-', label='{}'.format(self.initial_environment_symbol), linewidth=1.5) subplot.plot(morphing_factors, fractions_final_environment, 'g--', label='{}'.format(self.expected_final_environment_symbol), linewidth=1.5) plt.legend(fontsize=8.0, loc=7) plt.show()
def estimate_parameters(self, dist_factor_min, dist_factor_max, symmetry_measure_type='csm_wcs_ctwcc'): only_symbols = [self.initial_environment_symbol, self.expected_final_environment_symbol] # Set up the local geometry finder lgf = LocalGeometryFinder() lgf.setup_parameters(structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE) # Get the StructureEnvironments fake_valences = [-1] * (self.coordination_geometry.coordination_number + 1) fake_valences[0] = 1 # Get the StructureEnvironments for the structure with dist_factor_min struct = self.get_structure(morphing_factor=dist_factor_min) lgf.setup_structure(structure=struct) se = lgf.compute_structure_environments(only_indices=[0], valences=fake_valences, only_symbols=only_symbols) csm_info = se.get_csms(isite=0, mp_symbol=self.initial_environment_symbol) if len(csm_info) == 0: raise ValueError('No csm found for {}'.format(self.initial_environment_symbol)) csm_info.sort(key=lambda x: x['other_symmetry_measures'][symmetry_measure_type]) csm_initial_min_dist = csm_info[0]['other_symmetry_measures'][symmetry_measure_type] csm_info = se.get_csms(isite=0, mp_symbol=self.expected_final_environment_symbol) if len(csm_info) == 0: raise ValueError('No csm found for {}'.format(self.initial_environment_symbol)) csm_info.sort(key=lambda x: x['other_symmetry_measures'][symmetry_measure_type]) csm_final = csm_info[0]['other_symmetry_measures'][symmetry_measure_type] if not np.isclose(csm_final, 0.0, rtol=0.0, atol=1e-10): raise ValueError('Final coordination is not perfect !') # Get the StructureEnvironments for the structure with dist_factor_max struct = self.get_structure(morphing_factor=dist_factor_max) lgf.setup_structure(structure=struct) se = lgf.compute_structure_environments(only_indices=[0], valences=fake_valences, only_symbols=only_symbols) csm_info = se.get_csms(isite=0, mp_symbol=self.initial_environment_symbol) if len(csm_info) == 0: raise ValueError('No csm found for {}'.format(self.initial_environment_symbol)) csm_info.sort(key=lambda x: x['other_symmetry_measures'][symmetry_measure_type]) csm_initial_max_dist = csm_info[0]['other_symmetry_measures'][symmetry_measure_type] csm_info = se.get_csms(isite=0, mp_symbol=self.expected_final_environment_symbol) if len(csm_info) == 0: raise ValueError('No csm found for {}'.format(self.initial_environment_symbol)) csm_info.sort(key=lambda x: x['other_symmetry_measures'][symmetry_measure_type]) csm_final = csm_info[0]['other_symmetry_measures'][symmetry_measure_type] if not np.isclose(csm_final, 0.0, rtol=0.0, atol=1e-10): raise ValueError('Final coordination is not perfect !') return {'delta_csm_min': csm_initial_min_dist, 'self_weight_max_csm': csm_initial_max_dist}
def estimate_parameters(self, dist_factor_min, dist_factor_max, symmetry_measure_type="csm_wcs_ctwcc"): only_symbols = [self.initial_environment_symbol, self.expected_final_environment_symbol] # Set up the local geometry finder lgf = LocalGeometryFinder() lgf.setup_parameters(structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE) # Get the StructureEnvironments fake_valences = [-1] * (self.coordination_geometry.coordination_number + 1) fake_valences[0] = 1 # Get the StructureEnvironments for the structure with dist_factor_min struct = self.get_structure(morphing_factor=dist_factor_min) lgf.setup_structure(structure=struct) se = lgf.compute_structure_environments(only_indices=[0], valences=fake_valences, only_symbols=only_symbols) csm_info = se.get_csms(isite=0, mp_symbol=self.initial_environment_symbol) if len(csm_info) == 0: raise ValueError(f"No csm found for {self.initial_environment_symbol}") csm_info.sort(key=lambda x: x["other_symmetry_measures"][symmetry_measure_type]) csm_initial_min_dist = csm_info[0]["other_symmetry_measures"][symmetry_measure_type] csm_info = se.get_csms(isite=0, mp_symbol=self.expected_final_environment_symbol) if len(csm_info) == 0: raise ValueError(f"No csm found for {self.initial_environment_symbol}") csm_info.sort(key=lambda x: x["other_symmetry_measures"][symmetry_measure_type]) csm_final = csm_info[0]["other_symmetry_measures"][symmetry_measure_type] if not np.isclose(csm_final, 0.0, rtol=0.0, atol=1e-10): raise ValueError("Final coordination is not perfect !") # Get the StructureEnvironments for the structure with dist_factor_max struct = self.get_structure(morphing_factor=dist_factor_max) lgf.setup_structure(structure=struct) se = lgf.compute_structure_environments(only_indices=[0], valences=fake_valences, only_symbols=only_symbols) csm_info = se.get_csms(isite=0, mp_symbol=self.initial_environment_symbol) if len(csm_info) == 0: raise ValueError(f"No csm found for {self.initial_environment_symbol}") csm_info.sort(key=lambda x: x["other_symmetry_measures"][symmetry_measure_type]) csm_initial_max_dist = csm_info[0]["other_symmetry_measures"][symmetry_measure_type] csm_info = se.get_csms(isite=0, mp_symbol=self.expected_final_environment_symbol) if len(csm_info) == 0: raise ValueError(f"No csm found for {self.initial_environment_symbol}") csm_info.sort(key=lambda x: x["other_symmetry_measures"][symmetry_measure_type]) csm_final = csm_info[0]["other_symmetry_measures"][symmetry_measure_type] if not np.isclose(csm_final, 0.0, rtol=0.0, atol=1e-10): raise ValueError("Final coordination is not perfect !") return {"delta_csm_min": csm_initial_min_dist, "self_weight_max_csm": csm_initial_max_dist}
class CoordinationGeometryFinderTest(unittest.TestCase): def setUp(self): self.lgf = LocalGeometryFinder() self.lgf.setup_parameters(centering_type='standard', structure_refinement=self.lgf.STRUCTURE_REFINEMENT_NONE) # 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): allcg = AllCoordinationGeometries() 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], 13: [4, 11, 5, 12, 1, 2, 8, 3, 0, 6, 9, 7, 10], } for coordination in range(1, 14): for mp_symbol in allcg.get_implemented_geometries(coordination=coordination, returned='mp_symbol'): cg = allcg.get_geometry_from_mp_symbol(mp_symbol=mp_symbol) self.lgf.allcg = AllCoordinationGeometries(only_symbols=[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(only_indices=[0], maximum_distance_factor=1.01*cg.distfactor_max, min_cn=cg.coordination_number, max_cn=cg.coordination_number, only_symbols=[mp_symbol] ) self.assertAlmostEqual(se.get_csm(0, mp_symbol)['symmetry_measure'], 0.0, delta=1e-8, msg='Failed to get perfect environment with mp_symbol {}'.format(mp_symbol))
# Define the coordination geometry cg_symbol = raw_input('Enter symbol of the geometry for which you want to get the optimized permutations ' 'or "q" to quit : ') if cg_symbol == 'q': break if cg_symbol not in sepplane_cgs: print('Wrong geometry, try again ...') continue cg = allcg[cg_symbol] print('Getting explicit permutations for geometry "{}" (symbol : "{}")\n'.format(cg.name, cg_symbol)) # Setup of the local geometry finder lgf = LocalGeometryFinder() lgf.setup_parameters(structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE) # Setup the random environment lgf.setup_test_perfect_environment(cg_symbol, randomness=True, indices=range(cg.coordination_number), max_random_dist=0.05) lgf.perfect_geometry = AbstractGeometry.from_cg(cg=cg) points_perfect = lgf.perfect_geometry.points_wocs_ctwocc() # 1. Check the algorithms defined for this coordination geometry and get the explicit permutations original_nexplicit_perms = [] original_nexplicit_optimized_perms = [] for ialgo, algo in enumerate(cg.algorithms): algo._permutations = algo.explicit_permutations if algo.algorithm_type == 'EXPLICIT_PERMUTATIONS': raise ValueError('Do something for the explicit ones ... (these should anyway be by far ok!)') if algo.explicit_optimized_permutations is None:
class CoordinationGeometryFinderTest(unittest2.TestCase): def setUp(self): self.lgf = LocalGeometryFinder() self.lgf.setup_parameters(centering_type='standard') self.strategies = [SimplestChemenvStrategy(), SimpleAbundanceChemenvStrategy()]
def run_task(self, fw_spec): logging.basicConfig(filename='chemenv_structure_environments.log', format='%(levelname)s:%(module)s:%(funcName)s:%(message)s', level=logging.DEBUG) lgf = LocalGeometryFinder() lgf.setup_parameters(centering_type='centroid', include_central_site_in_centroid=True, structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE) if 'chemenv_parameters' in fw_spec: for param, value in fw_spec['chemenv_parameters'].items(): lgf.setup_parameter(param, value) identifier = fw_spec['identifier'] if 'structure' in fw_spec: structure = fw_spec['structure'] else: if identifier['source'] == 'MaterialsProject' and 'material_id' in identifier: if not 'mapi_key' in fw_spec: raise ValueError('The mapi_key should be provided to get the structure from the Materials Project') # FIXME: Use MPRester from pymatgen from pymatgen.matproj.rest import MPRester a = MPRester(fw_spec['mapi_key']) structure = a.get_structure_by_material_id(identifier['material_id']) else: raise ValueError('Either structure or identifier with source = MaterialsProject and material_id ' 'should be provided') info = {} # Compute the structure environments lgf.setup_structure(structure) if 'valences' in fw_spec: valences = fw_spec['valences'] else: try: bva = BVAnalyzer() valences = bva.get_valences(structure=structure) info['valences'] = {'origin': 'BVAnalyzer'} except: valences = 'undefined' info['valences'] = {'origin': 'None'} excluded_atoms = None if 'excluded_atoms' in fw_spec: excluded_atoms = fw_spec['excluded_atoms'] se = lgf.compute_structure_environments(only_cations=False, valences=valences, excluded_atoms=excluded_atoms) # Write to json file if 'json_file' in fw_spec: json_file = fw_spec['json_file'] else: json_file = 'structure_environments.json' f = open(json_file, 'w') json.dump(se.as_dict(), f) f.close() # Save to database if 'mongo_database' in fw_spec: database = fw_spec['mongo_database'] entry = {'identifier': identifier, 'elements': [elmt.symbol for elmt in structure.composition.elements], 'nelements': len(structure.composition.elements), 'pretty_formula': structure.composition.reduced_formula, 'nsites': len(structure) } saving_option = fw_spec['saving_option'] if saving_option == 'gridfs': gridfs_msonables = {'structure': structure, 'structure_environments': se} elif saving_option == 'storefile': gridfs_msonables = None if 'se_prefix' in fw_spec: se_prefix = fw_spec['se_prefix'] if not se_prefix.isalpha(): raise ValueError('Prefix for structure_environments file is "{}" ' 'while it should be alphabetic'.format(se_prefix)) else: se_prefix = '' if se_prefix: se_rfilename = '{}_{}.json'.format(se_prefix, fw_spec['storefile_basename']) else: se_rfilename = '{}.json'.format(fw_spec['storefile_basename']) se_rfilepath = '{}/{}'.format(fw_spec['storefile_dirpath'], se_rfilename) storage_server = fw_spec['storage_server'] storage_server.put(localpath=json_file, remotepath=se_rfilepath, overwrite=True, makedirs=False) entry['structure_environments_file'] = se_rfilepath else: raise ValueError('Saving option is "{}" while it should be ' '"gridfs" or "storefile"'.format(saving_option)) criteria = {'identifier': identifier} if database.collection.find(criteria).count() == 1: database.update_entry(query=criteria, entry_update=entry, gridfs_msonables=gridfs_msonables) else: database.insert_entry(entry=entry, gridfs_msonables=gridfs_msonables)
def compute_environments(chemenv_configuration): string_sources = {'cif': {'string': 'a Cif file', 'regexp': r'.*\.cif$'}, 'mp': {'string': 'the Materials Project database', 'regexp': r'mp-[0-9]+$'}} questions = {'c': 'cif'} 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() 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(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': while True: test = input('Enter index of site(s) (e.g. 0 1 2, separated by spaces) for which you want to see the grid of parameters : ') try: indices=[int(x) for x in test.split()] print(str(indices)) for isite in indices: if isite <0: raise IndexError se.plot_environments(isite, additional_condition=se.AC.ONLY_ACB) break except ValueError: print('This is not a valid site') except IndexError: print('This site is out of the site range') 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 = [] while True: try: 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)) break except (ValueError,IndexError): print('Not a valid multiplicity') 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.allcg.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(PymatgenTest): def setUp(self): self.lgf = LocalGeometryFinder() self.lgf.setup_parameters(centering_type='standard', structure_refinement=self.lgf.STRUCTURE_REFINEMENT_NONE) # self.strategies = [SimplestChemenvStrategy(), SimpleAbundanceChemenvStrategy()] def test_abstract_geometry(self): cg_ts3 = self.lgf.allcg['TS:3'] cg_tet = self.lgf.allcg['T:4'] abstract_geom = AbstractGeometry.from_cg(cg=cg_ts3, centering_type='central_site') self.assertArrayAlmostEqual(abstract_geom.centre, [0.0, 0.0, 0.0]) abstract_geom = AbstractGeometry.from_cg(cg=cg_ts3, centering_type='centroid') self.assertArrayAlmostEqual(abstract_geom.centre, [0.0, 0.0, 0.33333333333]) with self.assertRaises(ValueError) as cm: AbstractGeometry.from_cg(cg=cg_ts3, centering_type='central_site', include_central_site_in_centroid=True) self.assertEqual(str(cm.exception), 'The center is the central site, no calculation of the centroid, ' 'variable include_central_site_in_centroid should be set to False') abstract_geom = AbstractGeometry.from_cg(cg=cg_ts3, centering_type='centroid', include_central_site_in_centroid=True) self.assertArrayAlmostEqual(abstract_geom.centre, [0.0, 0.0, 0.25]) self.assertEqual(abstract_geom.__str__(), '\nAbstract Geometry with 3 points :\n' ' [-1. 0. -0.25]\n' ' [ 1. 0. -0.25]\n' ' [0. 0. 0.75]\n' 'Points are referenced to the centroid (calculated with the central site) :\n' ' [0. 0. 0.25]\n') symm_dict = symmetry_measure([[0.0, 0.0, 0.0]], [1.1, 2.2, 3.3]) self.assertAlmostEqual(symm_dict['symmetry_measure'], 0.0) self.assertEqual(symm_dict['scaling_factor'], None) self.assertEqual(symm_dict['rotation_matrix'], None) tio2_struct = self.get_structure('TiO2') envs = self.lgf.compute_coordination_environments(structure=tio2_struct, indices=[0]) self.assertAlmostEqual(envs[0][0]['csm'], 1.5309987846957258) self.assertAlmostEqual(envs[0][0]['ce_fraction'], 1.0) self.assertEqual(envs[0][0]['ce_symbol'], 'O:6') self.assertEqual(sorted(envs[0][0]['permutation']), sorted([0, 4, 1, 5, 2, 3])) self.lgf.setup_random_structure(coordination=5) self.assertEqual(len(self.lgf.structure), 6) self.lgf.setup_random_indices_local_geometry(coordination=5) self.assertEqual(self.lgf.icentral_site, 0) self.assertEqual(len(self.lgf.indices), 5) self.lgf.setup_ordered_indices_local_geometry(coordination=5) self.assertEqual(self.lgf.icentral_site, 0) self.assertEqual(self.lgf.indices, list(range(1, 6))) self.lgf.setup_explicit_indices_local_geometry(explicit_indices=[3, 5, 2, 0, 1, 4]) self.assertEqual(self.lgf.icentral_site, 0) self.assertEqual(self.lgf.indices, [4, 6, 3, 1, 2, 5]) LiFePO4_struct = self.get_structure('LiFePO4') isite = 10 envs_LiFePO4 = self.lgf.compute_coordination_environments(structure=LiFePO4_struct, indices=[isite]) self.assertAlmostEqual(envs_LiFePO4[isite][0]['csm'], 0.140355832317) nbs_coords = [np.array([6.16700437, -4.55194317, -5.89031356]), np.array([4.71588167, -4.54248093, -3.75553856]), np.array([6.88012571, -5.79877503, -3.73177541]), np.array([6.90041188, -3.32797839, -3.71812416])] self.lgf.setup_structure(LiFePO4_struct) self.lgf.setup_local_geometry(isite, coords=nbs_coords) perfect_tet = AbstractGeometry.from_cg(cg=cg_tet, centering_type='centroid', include_central_site_in_centroid=False) points_perfect_tet = perfect_tet.points_wcs_ctwcc() res = self.lgf.coordination_geometry_symmetry_measures_fallback_random(coordination_geometry=cg_tet, NRANDOM=5, points_perfect=points_perfect_tet) permutations_symmetry_measures, permutations, algos, local2perfect_maps, perfect2local_maps = res for perm_csm_dict in permutations_symmetry_measures: self.assertAlmostEqual(perm_csm_dict['symmetry_measure'], 0.140355832317) # # 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): allcg = AllCoordinationGeometries() 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], 13: [4, 11, 5, 12, 1, 2, 8, 3, 0, 6, 9, 7, 10], } for coordination in range(1, 14): for mp_symbol in allcg.get_implemented_geometries(coordination=coordination, returned='mp_symbol'): cg = allcg.get_geometry_from_mp_symbol(mp_symbol=mp_symbol) self.lgf.allcg = AllCoordinationGeometries(only_symbols=[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(only_indices=[0], maximum_distance_factor=1.01*cg.distfactor_max, min_cn=cg.coordination_number, max_cn=cg.coordination_number, only_symbols=[mp_symbol] ) self.assertAlmostEqual(se.get_csm(0, mp_symbol)['symmetry_measure'], 0.0, delta=1e-8, msg='Failed to get perfect environment with mp_symbol {}'.format(mp_symbol)) def test_disable_hints(self): allcg = AllCoordinationGeometries() mp_symbol = 'SH:13' mp_symbols = ['SH:13', 'HP:12'] cg = allcg.get_geometry_from_mp_symbol(mp_symbol=mp_symbol) mypoints = cg.points mypoints[-1] = [0.9*cc for cc in mypoints[-1]] self.lgf.allcg = AllCoordinationGeometries(only_symbols=[mp_symbol]) self.lgf.setup_test_perfect_environment(mp_symbol, randomness=False, indices=[4, 11, 5, 12, 1, 2, 8, 3, 0, 6, 9, 7, 10], random_translation='NONE', random_rotation='NONE', random_scale='NONE', points=mypoints) se_nohints = self.lgf.compute_structure_environments(only_indices=[0], maximum_distance_factor=1.02 * cg.distfactor_max, min_cn=12, max_cn=13, only_symbols=mp_symbols, get_from_hints=False ) se_hints = self.lgf.compute_structure_environments(only_indices=[0], maximum_distance_factor=1.02 * cg.distfactor_max, min_cn=12, max_cn=13, only_symbols=mp_symbols, get_from_hints=True ) with self.assertRaises(KeyError): abc = se_nohints.ce_list[0][12] abc.minimum_geometries() self.assertAlmostEqual(se_hints.ce_list[0][13][0], se_nohints.ce_list[0][13][0]) self.assertTrue(set(se_nohints.ce_list[0].keys()).issubset(set(se_hints.ce_list[0].keys())))
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, 4)