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())))
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_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)
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())))
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)
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( 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.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('')
__version__ = "2.0" __maintainer__ = "David Waroquiers" __email__ = "*****@*****.**" __date__ = "Feb 20, 2016" from pymatgen.analysis.chemenv.coordination_environments.coordination_geometry_finder import LocalGeometryFinder from pymatgen.analysis.chemenv.coordination_environments.coordination_geometry_finder import AbstractGeometry from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import AllCoordinationGeometries from math import factorial import itertools from random import shuffle if __name__ == '__main__': allcg = AllCoordinationGeometries() test = input( 'Standard ("s", all permutations for cn <= 6, 500 random permutations for cn > 6) or on demand' ) if test == 's': perms_def = 'standard' elif test == 'o': perms_def = 'on_demand' else: try: nperms = int(test) perms_def = 'ndefined' except Exception: perms_def = 'on_demand'
elif permutations_setup[0] == 'y': permutations_setup_type = 'y' npermutations = None try: nperm_factor = int(permutations_setup[1:]) except: raise ValueError('Wrong command line option for permutations_setup') else: permutations_setup_type = 'n' try: npermutations = int(permutations_setup) except: raise ValueError('Wrong command line option for permutations_setup') # Class containing all the coordination geometries allcg = AllCoordinationGeometries() sepplane_cgs = [] for coordination in range(1, 13): symbol_name_mapping = allcg.get_symbol_name_mapping(coordination=coordination) for symbol, name in symbol_name_mapping.items(): cg = allcg[symbol] if cg.points is None: continue if cg.algorithms[0].algorithm_type != 'EXPLICIT_PERMUTATIONS': sepplane_cgs.append(symbol) continue ncols = 5 nlines = int(np.ceil(float(len(sepplane_cgs)) / ncols)) sepplane_cgs_grid = [] for iline in range(nlines):
__email__ = "*****@*****.**" __date__ = "Feb 20, 2016" from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import AllCoordinationGeometries from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import SEPARATION_PLANE from pymatgen.analysis.chemenv.utils.scripts_utils import visualize from pymatgen.analysis.chemenv.utils.coordination_geometry_utils import Plane import numpy as np if __name__ == '__main__': print('+-------------------------------------------------------+\n' '| Development script of the ChemEnv utility of pymatgen |\n' '| Visualization of the model coordination environments |\n' '+-------------------------------------------------------+\n') allcg = AllCoordinationGeometries() vis = None while True: cg_symbol = raw_input( 'Enter symbol of the geometry you want to see, "l" to see the list ' 'of existing geometries or "q" to quit : ') if cg_symbol == 'q': break if cg_symbol == 'l': print( allcg.pretty_print(maxcn=13, additional_info={'nb_hints': True})) continue try: cg = allcg[cg_symbol] except LookupError:
from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import AllCoordinationGeometries from pymatgen.analysis.chemenv.coordination_environments.coordination_geometry_finder import LocalGeometryFinder import logging allcg = AllCoordinationGeometries() lgf = LocalGeometryFinder() logging.basicConfig(format="%(levelname)s:%(module)s:%(funcName)s:%(message)s", level="DEBUG") mp_symbol = "DD:20" coordination = 20 myindices = [ 8, 12, 11, 0, 14, 10, 13, 6, 18, 1, 9, 17, 3, 19, 5, 7, 15, 2, 16, 4 ] cg = allcg.get_geometry_from_mp_symbol(mp_symbol=mp_symbol) lgf.allcg = AllCoordinationGeometries(only_symbols=[mp_symbol]) lgf.setup_test_perfect_environment( mp_symbol, randomness=False, indices=myindices, random_translation="NONE", random_rotation="NONE", random_scale="NONE", ) se = 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],
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('')
__date__ = "Feb 20, 2016" from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import AllCoordinationGeometries from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import SEPARATION_PLANE from pymatgen.analysis.chemenv.utils.scripts_utils import visualize from pymatgen.analysis.chemenv.utils.coordination_geometry_utils import Plane import numpy as np if __name__ == '__main__': print('+-------------------------------------------------------+\n' '| Development script of the ChemEnv utility of pymatgen |\n' '| Visualization of the model coordination environments |\n' '+-------------------------------------------------------+\n') allcg = AllCoordinationGeometries() vis = None while True: cg_symbol = raw_input('Enter symbol of the geometry you want to see, "l" to see the list ' 'of existing geometries or "q" to quit : ') if cg_symbol == 'q': break if cg_symbol == 'l': print(allcg.pretty_print(maxcn=12)) continue try: cg = allcg[cg_symbol] except LookupError: print('Wrong geometry, try again ...') continue print(cg.name)
def from_name(cls, name: str) -> SymmetryMeasure: reference_points = AllCoordinationGeometries().get_geometry_from_name( name).points return cls(reference_points, name)
def get_chemenv_analysis(struct, distance_cutoff, angle_cutoff): if not struct: raise PreventUpdate struct = self.from_data(struct) distance_cutoff = float(distance_cutoff) angle_cutoff = float(angle_cutoff) # decide which indices to present to user sga = SpacegroupAnalyzer(struct) symm_struct = sga.get_symmetrized_structure() inequivalent_indices = [ indices[0] for indices in symm_struct.equivalent_indices ] wyckoffs = symm_struct.wyckoff_symbols lgf = LocalGeometryFinder() lgf.setup_structure(structure=struct) se = lgf.compute_structure_environments( maximum_distance_factor=distance_cutoff + 0.01, only_indices=inequivalent_indices, ) strategy = SimplestChemenvStrategy(distance_cutoff=distance_cutoff, angle_cutoff=angle_cutoff) lse = LightStructureEnvironments.from_structure_environments( strategy=strategy, structure_environments=se) all_ce = AllCoordinationGeometries() envs = [] unknown_sites = [] for index, wyckoff in zip(inequivalent_indices, wyckoffs): datalist = { "Site": struct[index].species_string, "Wyckoff Label": wyckoff, } if not lse.neighbors_sets[index]: unknown_sites.append( f"{struct[index].species_string} ({wyckoff})") continue # represent the local environment as a molecule mol = Molecule.from_sites( [struct[index]] + lse.neighbors_sets[index][0].neighb_sites) mol = mol.get_centered_molecule() mg = MoleculeGraph.with_empty_graph(molecule=mol) for i in range(1, len(mol)): mg.add_edge(0, i) view = html.Div( [ StructureMoleculeComponent( struct_or_mol=mg, static=True, id= f"{struct.composition.reduced_formula}_site_{index}", scene_settings={ "enableZoom": False, "defaultZoom": 0.6 }, ).all_layouts["struct"] ], style={ "width": "300px", "height": "300px" }, ) env = lse.coordination_environments[index] co = all_ce.get_geometry_from_mp_symbol(env[0]["ce_symbol"]) name = co.name if co.alternative_names: name += f" (also known as {', '.join(co.alternative_names)})" datalist.update({ "Environment": name, "IUPAC Symbol": co.IUPAC_symbol_str, get_tooltip( "CSM", '"Continuous Symmetry Measure," a measure of how symmetrical a ' "local environment is from most symmetrical at 0% to least " "symmetrical at 100%", ): f"{env[0]['csm']:.2f}%", "Interactive View": view, }) envs.append(get_data_list(datalist)) # TODO: switch to tiles? envs_grouped = [envs[i:i + 2] for i in range(0, len(envs), 2)] analysis_contents = [] for env_group in envs_grouped: analysis_contents.append( Columns([Column(e, size=6) for e in env_group])) if unknown_sites: unknown_sites = html.Strong( f"The following sites were not identified: {', '.join(unknown_sites)}. " f"Please try changing the distance or angle cut-offs to identify these sites." ) else: unknown_sites = html.Span() return html.Div( [html.Div(analysis_contents), html.Br(), unknown_sites])
from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import AllCoordinationGeometries from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import SEPARATION_PLANE from pymatgen.analysis.chemenv.utils.scripts_utils import visualize from pymatgen.analysis.chemenv.utils.coordination_geometry_utils import Plane import numpy as np if __name__ == "__main__": print( "+-------------------------------------------------------+\n" "| Development script of the ChemEnv utility of pymatgen |\n" "| Visualization of the model coordination environments |\n" "+-------------------------------------------------------+\n" ) allcg = AllCoordinationGeometries() vis = None while True: cg_symbol = raw_input( 'Enter symbol of the geometry you want to see, "l" to see the list ' 'of existing geometries or "q" to quit : ' ) if cg_symbol == "q": break if cg_symbol == "l": print(allcg.pretty_print(maxcn=12)) continue try: cg = allcg[cg_symbol] except LookupError: print("Wrong geometry, try again ...")
__email__ = "*****@*****.**" __date__ = "Feb 20, 2016" from pymatgen.analysis.chemenv.coordination_environments.coordination_geometry_finder import LocalGeometryFinder from pymatgen.analysis.chemenv.coordination_environments.coordination_geometry_finder import AbstractGeometry from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import AllCoordinationGeometries from math import factorial import numpy as np import itertools from random import shuffle import time if __name__ == '__main__': allcg = AllCoordinationGeometries() while True: cg_symbol = input( 'Enter symbol of the geometry for which you want to get the explicit permutations : ' ) try: cg = allcg[cg_symbol] break except LookupError: print('Wrong geometry, try again ...') continue lgf = LocalGeometryFinder() lgf.setup_parameters(structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE)
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 # 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.frac_coords + 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("")
def from_name(cls, name): reference_points = AllCoordinationGeometries().get_geometry_from_name( name).points return cls(reference_points, name)
__email__ = "*****@*****.**" __date__ = "Feb 20, 2016" from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import AllCoordinationGeometries from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import SEPARATION_PLANE from pymatgen.analysis.chemenv.utils.scripts_utils import visualize from pymatgen.analysis.chemenv.utils.coordination_geometry_utils import Plane import numpy as np if __name__ == "__main__": print("+-------------------------------------------------------+\n" "| Development script of the ChemEnv utility of pymatgen |\n" "| Visualization of the model coordination environments |\n" "+-------------------------------------------------------+\n") allcg = AllCoordinationGeometries() vis = None while True: cg_symbol = input( 'Enter symbol of the geometry you want to see, "l" to see the list ' 'of existing geometries or "q" to quit : ') if cg_symbol == "q": break if cg_symbol == "l": print( allcg.pretty_print(maxcn=20, additional_info={"nb_hints": True})) continue try: cg = allcg[cg_symbol] except LookupError:
def get_chemenv_analysis(struct, distance_cutoff, angle_cutoff): if not struct: raise PreventUpdate struct = self.from_data(struct) kwargs = self.reconstruct_kwargs_from_state( callback_context.inputs) distance_cutoff = kwargs["distance_cutoff"] angle_cutoff = kwargs["angle_cutoff"] # TODO: remove these brittle guard statements, figure out more robust way to handle multiple input types if isinstance(struct, StructureGraph): struct = struct.structure def get_valences(struct): valences = [ getattr(site.specie, "oxi_state", None) for site in struct ] valences = [v for v in valences if v is not None] if len(valences) == len(struct): return valences else: return "undefined" # decide which indices to present to user sga = SpacegroupAnalyzer(struct) symm_struct = sga.get_symmetrized_structure() inequivalent_indices = [ indices[0] for indices in symm_struct.equivalent_indices ] wyckoffs = symm_struct.wyckoff_symbols lgf = LocalGeometryFinder() lgf.setup_structure(structure=struct) se = lgf.compute_structure_environments( maximum_distance_factor=distance_cutoff + 0.01, only_indices=inequivalent_indices, valences=get_valences(struct), ) strategy = SimplestChemenvStrategy(distance_cutoff=distance_cutoff, angle_cutoff=angle_cutoff) lse = LightStructureEnvironments.from_structure_environments( strategy=strategy, structure_environments=se) all_ce = AllCoordinationGeometries() envs = [] unknown_sites = [] for index, wyckoff in zip(inequivalent_indices, wyckoffs): datalist = { "Site": unicodeify_species(struct[index].species_string), "Wyckoff Label": wyckoff, } if not lse.neighbors_sets[index]: unknown_sites.append( f"{struct[index].species_string} ({wyckoff})") continue # represent the local environment as a molecule mol = Molecule.from_sites( [struct[index]] + lse.neighbors_sets[index][0].neighb_sites) mol = mol.get_centered_molecule() mg = MoleculeGraph.with_empty_graph(molecule=mol) for i in range(1, len(mol)): mg.add_edge(0, i) view = html.Div( [ StructureMoleculeComponent( struct_or_mol=mg, disable_callbacks=True, id= f"{struct.composition.reduced_formula}_site_{index}", scene_settings={ "enableZoom": False, "defaultZoom": 0.6 }, )._sub_layouts["struct"] ], style={ "width": "300px", "height": "300px" }, ) env = lse.coordination_environments[index] co = all_ce.get_geometry_from_mp_symbol(env[0]["ce_symbol"]) name = co.name if co.alternative_names: name += f" (also known as {', '.join(co.alternative_names)})" datalist.update({ "Environment": name, "IUPAC Symbol": co.IUPAC_symbol_str, get_tooltip( "CSM", "The continuous symmetry measure (CSM) describes the similarity to an " "ideal coordination environment. It can be understood as a 'distance' to " "a shape and ranges from 0 to 100 in which 0 corresponds to a " "coordination environment that is exactly identical to the ideal one. A " "CSM larger than 5.0 already indicates a relatively strong distortion of " "the investigated coordination environment.", ): f"{env[0]['csm']:.2f}", "Interactive View": view, }) envs.append(get_data_list(datalist)) # TODO: switch to tiles? envs_grouped = [envs[i:i + 2] for i in range(0, len(envs), 2)] analysis_contents = [] for env_group in envs_grouped: analysis_contents.append( Columns([Column(e, size=6) for e in env_group])) if unknown_sites: unknown_sites = html.Strong( f"The following sites were not identified: {', '.join(unknown_sites)}. " f"Please try changing the distance or angle cut-offs to identify these sites, " f"or try an alternative algorithm such as LocalEnv.") else: unknown_sites = html.Span() return html.Div( [html.Div(analysis_contents), html.Br(), unknown_sites])
__date__ = "Feb 20, 2016" from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import AllCoordinationGeometries from pymatgen.analysis.chemenv.coordination_environments.coordination_geometries import SEPARATION_PLANE from pymatgen.analysis.chemenv.utils.scripts_utils import visualize from pymatgen.analysis.chemenv.utils.coordination_geometry_utils import Plane import numpy as np if __name__ == '__main__': print('+-------------------------------------------------------+\n' '| Development script of the ChemEnv utility of pymatgen |\n' '| Visualization of the model coordination environments |\n' '+-------------------------------------------------------+\n') allcg = AllCoordinationGeometries() vis = None while True: cg_symbol = input('Enter symbol of the geometry you want to see, "l" to see the list ' 'of existing geometries or "q" to quit : ') if cg_symbol == 'q': break if cg_symbol == 'l': print(allcg.pretty_print(maxcn=13, additional_info={'nb_hints': True})) continue try: cg = allcg[cg_symbol] except LookupError: print('Wrong geometry, try again ...') continue print(cg.name)