def setUp(self):
     self.lgf = LocalGeometryFinder()
     self.lgf.setup_parameters(
         centering_type="standard",
         structure_refinement=self.lgf.STRUCTURE_REFINEMENT_NONE,
     )
     self.lgf2 = LocalGeometryFinder(print_citation=True)
Example #2
0
 def setUp(self):
     self.lgf = LocalGeometryFinder()
     self.lgf.setup_parameters(centering_type='standard')
     self.strategies = [
         SimplestChemenvStrategy(),
         SimpleAbundanceChemenvStrategy()
     ]
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))
Example #4
0
def analyse_local_coord_env(atoms=None, ):
    """
    """
    #| - analyse_local_coord_env
    out_dict = dict()

    Ir_indices = []
    for i, s in enumerate(atoms.get_chemical_symbols()):
        if s == "Ir":
            Ir_indices.append(i)

    struct = AseAtomsAdaptor.get_structure(atoms)

    lgf = LocalGeometryFinder()
    lgf.setup_structure(structure=struct)

    se = lgf.compute_structure_environments(maximum_distance_factor=1.41,
                                            only_cations=False)

    strategy = MultiWeightsChemenvStrategy.stats_article_weights_parameters()

    lse = LightStructureEnvironments.from_structure_environments(
        strategy=strategy, structure_environments=se)

    isite = 0
    cor_env = []
    coor_env_dict = dict()
    for isite in Ir_indices:
        c_env = lse.coordination_environments[isite]
        coor_env_dict[isite] = c_env
        cor_env += [c_env[0]['ce_symbol']]

    out_dict["coor_env_dict"] = coor_env_dict

    return (out_dict)
Example #5
0
class CoordinationGeometryFinderTest(unittest2.TestCase):
    def setUp(self):
        self.lgf = LocalGeometryFinder()
        self.lgf.setup_parameters(centering_type='standard')
        self.strategies = [
            SimplestChemenvStrategy(),
            SimpleAbundanceChemenvStrategy()
        ]
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 setUp(self):
        with open("mp-7000.json", "r") as f:
            dict_lse = json.load(f)
        lse = LightStructureEnvironments.from_dict(dict_lse)
        struct = lse.structure
        bva = BVAnalyzer()
        valences = bva.get_valences(structure=struct)
        lgf = LocalGeometryFinder()
        lgf.setup_structure(structure=struct)
        se = lgf.compute_structure_environments(maximum_distance_factor=1.41, only_cations=False, valences=valences)
        strategy = MultiWeightsChemenvStrategy.stats_article_weights_parameters()
        self.lse = LightStructureEnvironments.from_structure_environments(strategy=strategy, structure_environments=se)

        with open("mp-5634.json", "r") as f:
            dict_lse2 = json.load(f)
        self.lse2 = LightStructureEnvironments.from_dict(dict_lse2)
    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}
Example #10
0
 def from_preset(preset):
     """
     Use a standard collection of CE types and
     choose your ChemEnv neighbor-finding strategy.
     Args:
         preset (str): preset types ("simple" or
                       "multi_weights").
     Returns:
         ChemEnvSiteFingerprint object from a preset.
     """
     cetypes = [
         'S:1', 'L:2', 'A:2', 'TL:3', 'TY:3', 'TS:3', 'T:4', 'S:4', 'SY:4',
         'SS:4', 'PP:5', 'S:5', 'T:5', 'O:6', 'T:6', 'PP:6', 'PB:7', 'ST:7',
         'ET:7', 'FO:7', 'C:8', 'SA:8', 'SBT:8', 'TBT:8', 'DD:8', 'DDPN:8',
         'HB:8', 'BO_1:8', 'BO_2:8', 'BO_3:8', 'TC:9', 'TT_1:9', 'TT_2:9',
         'TT_3:9', 'HD:9', 'TI:9', 'SMA:9', 'SS:9', 'TO_1:9', 'TO_2:9',
         'TO_3:9', 'PP:10', 'PA:10', 'SBSA:10', 'MI:10', 'S:10', 'H:10',
         'BS_1:10', 'BS_2:10', 'TBSA:10', 'PCPA:11', 'H:11', 'SH:11',
         'CO:11', 'DI:11', 'I:12', 'PBP:12', 'TT:12', 'C:12', 'AC:12',
         'SC:12', 'S:12', 'HP:12', 'HA:12', 'SH:13', 'DD:20'
     ]
     lgf = LocalGeometryFinder()
     lgf.setup_parameters(
         centering_type='centroid',
         include_central_site_in_centroid=True,
         structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE)
     if preset == "simple":
         return ChemEnvSiteFingerprint(
             cetypes,
             SimplestChemenvStrategy(distance_cutoff=1.4, angle_cutoff=0.3),
             lgf)
     elif preset == "multi_weights":
         return ChemEnvSiteFingerprint(
             cetypes,
             MultiWeightsChemenvStrategy.stats_article_weights_parameters(),
             lgf)
     else:
         raise RuntimeError('unknown neighbor-finding strategy preset.')
    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()
Example #12
0
def getSimplestChemenvStrategy(struct):
    # Setup the local geometry finder
    lgf = LocalGeometryFinder()
    lgf.setup_parameters(centering_type='centroid',
                         include_central_site_in_centroid=True)

    #you can also save the logging to a file, just remove the comment

    #     logging.basicConfig(#filename='chemenv_structure_environments.log',
    #                         format='%(levelname)s:%(module)s:%(funcName)s:%(message)s',
    #                         level=logging.DEBUG)
    lgf.setup_structure(structure=struct)
    se = lgf.compute_structure_environments(maximum_distance_factor=1.41,
                                            only_cations=False)
    strategy = SimplestChemenvStrategy(distance_cutoff=1.4, angle_cutoff=0.3)
    lse = LightStructureEnvironments.from_structure_environments(
        strategy=strategy, structure_environments=se)
    return lse.coordination_environments
    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()
Example #14
0
def extract_sites_o6_s5_t4(species,
                           transition,
                           path=None,
                           save_as='site_data.pkl',
                           verbose=0):
    """From a directory containing structure/spectra data of various crystal
    structures from the Materials Project, extract and store all site data
    corresponding to the O:6, S:5 and T:4 chemical environments.

    ~ Note: this script takes a long time to run, be patient! ~

    :Input:
    - species (string) the atom of focus for the XANES spectrum. For example:
      'Ti'.
    - path (string) override the default path if desired. Should be the
      absolute path.
    - transition (string) for example: 'K'.
    - save_as (string) the output pkl file name.
    - verbose (int) qqual to 0 or 1. 0 for silent running, 1 for a progress
      indicator. 1 by default.
    """

    logger = logging.getLogger()
    logger.setLevel(logging.CRITICAL)

    # set the path to where the extracted data is located
    if path is None:
        path = t4iss_defaults['t4iss_xanes_data']
    # e.g.
    # path = os.path.join(os.environ['HOME'], "datasets", "FEFF_data_June7")

    cell_counter = 0
    total_counter = 0

    t4_data = []
    s5_data = []
    o6_data = []

    forbidden = [".DS_Store", "CONTCAR", "collection.pkl"]
    correct_string = str(species) + "-" + str(transition)

    # for cell (e.g. mp-390) in the desired data directory
    os_list_directory = os.listdir(path)
    N_os_list_directory = len(os_list_directory)

    for ii in tqdm(range(N_os_list_directory)):

        cell = os_list_directory[ii]

        if verbose == 1:
            if ii % 100 == 0:
                print("%i/%i samples analyzed" % (ii, N_os_list_directory))

        # reset the cell counter
        cell_counter = 0
        pass_cell = False

        # define a path if cell isn't = forbidden
        if cell not in forbidden:
            cell_path = os.path.join(path, str(cell))

            # get the structure
            try:
                structure = mg.Structure.from_file(cell_path + "/CONTCAR")
            except (FileNotFoundError, NotADirectoryError):
                # skip if CONTCAR does not exist in the directory
                # or if it isn't a directory at all, there are a few of those
                pass_cell = True

            # skip if directory is empty
            if not pass_cell:  # call this first to avoid NotADirectoryError
                if os.listdir(cell_path) == []:
                    pass_cell = True

            if not pass_cell:
                # define a path to a given spectra/pickle file
                for sample in os.listdir(cell_path):
                    if sample not in forbidden:
                        pass_sample = False

                        # cell sample path
                        csp = os.path.join(cell_path, str(sample))

                        # assert that we're reading the correct species
                        # and correct transition
                        if correct_string in csp:
                            try:
                                with open(csp + "/xanes.pkl", 'rb') \
                                    as pickle_file:
                                    content = pickle.load(pickle_file)

                                # ensure we end up with content to analyze
                                # if not pass it
                                try:
                                    save_stdout = sys.stdout
                                    sys.stdout = open('.trash', 'w')
                                    lgf = LocalGeometryFinder()
                                    cesym = get_cesym(lgf, structure,
                                                      content.structure[1])
                                    sys.stdout = save_stdout
                                except IndexError:
                                    pass_sample = True

                                if pass_sample:
                                    pass
                                elif cesym[0] == "T:4":
                                    t4_data.append([
                                        cell, cell_counter,
                                        deepcopy(content), cesym
                                    ])
                                    cell_counter += 1
                                    total_counter += 1
                                elif cesym[0] == "S:5":
                                    s5_data.append([
                                        cell, cell_counter,
                                        deepcopy(content), cesym
                                    ])
                                    cell_counter += 1
                                    total_counter += 1
                                elif cesym[0] == "O:6":
                                    o6_data.append([
                                        cell, cell_counter,
                                        deepcopy(content), cesym
                                    ])
                                    cell_counter += 1
                                    total_counter += 1
                            except FileNotFoundError:
                                pass

    all_data = [t4_data, s5_data, o6_data]
    path_save = os.path.join(path, save_as)

    with open(path_save, 'wb') as f:
        pickle.dump(all_data, f)
Example #15
0
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])

        # WHY ARE WE TESTING STRINGS????
        # 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],
            20: [
                8, 12, 11, 0, 14, 10, 13, 6, 18, 1, 9, 17, 3, 19, 5, 7, 15, 2,
                16, 4
            ],
        }

        for coordination in range(1, 21):
            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=
                    f"Failed to get perfect environment with mp_symbol {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())))
 def setUp(self):
     self.lgf = LocalGeometryFinder()
     self.lgf.setup_parameters(centering_type='standard',
                               structure_refinement=self.lgf.STRUCTURE_REFINEMENT_NONE)
Example #17
0
        if sepplanealgo.algorithm_type != "SEPARATION_PLANE":
            raise ValueError("Should all be separation plane")

        permsonfile = f"Permutations on file in this algorithm ({len(sepplanealgo._permutations):d}) "
        print(permsonfile)
        print(sepplanealgo._permutations)
        permutations = sepplanealgo.safe_separation_permutations(
            ordered_plane=sepplanealgo.ordered_plane, ordered_point_groups=sepplanealgo.ordered_point_groups
        )

        sepplanealgo._permutations = permutations

        print(f"Test permutations ({len(permutations):d}) :")
        print(permutations)

        lgf = LocalGeometryFinder()
        lgf.setup_parameters(structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE)
        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)

        # Setting up the plane of separation
        local_plane = None
        found = False
        for npoints in range(sepplanealgo.minimum_number_of_points, min(sepplanealgo.maximum_number_of_points, 4) + 1):
            if found:
                break
            for ipoints in itertools.combinations(sepplanealgo.plane_points, npoints):
                points_combination = [lgf.local_geometry.coords[ipoint] for ipoint in ipoints]
Example #18
0
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)
        # 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!)')
    # print(row.id)

    key_value_pairs = row.key_value_pairs
    structure_id = key_value_pairs["structure_id"]

    if structure_id in ids_to_run:
        print("RUNNING!")

        atoms = row.toatoms()
        Ir_indices = [
            i for i, s in enumerate(atoms.get_chemical_symbols()) if s == 'Ir'
        ]

        struct = AseAtomsAdaptor.get_structure(atoms)

        lgf = LocalGeometryFinder()
        lgf.setup_structure(structure=struct)

        se = lgf.compute_structure_environments(maximum_distance_factor=1.41,
                                                only_cations=False)

        strategy = MultiWeightsChemenvStrategy.stats_article_weights_parameters(
        )

        lse = LightStructureEnvironments.from_structure_environments(
            strategy=strategy, structure_environments=se)

        isite = 0

        cor_env = []
        for isite in Ir_indices:
Example #21
0
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("")
Example #22
0
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())))
Example #24
0

if __name__ == "__main__":

    allcg = AllCoordinationGeometries()

    while True:
        cg_symbol = raw_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)

    myindices = range(cg.coordination_number)

    test = raw_input(
        'Enter if you want to test all possible permutations ("all" or "a") or a given number of random permutations (i.e. "25")'
    )

    if test == "all" or test == "a":
        perms_iterator = itertools.permutations(myindices)
        nperms = factorial(cg.coordination_number)
    else:
        try:
            nperms = int(test)
        except:
 def setUp(self):
     self.lgf = LocalGeometryFinder()
     self.lgf.setup_parameters(centering_type='standard')
     self.strategies = [SimplestChemenvStrategy(), SimpleAbundanceChemenvStrategy()]
Example #26
0
            break
        except LookupError:
            print('Wrong geometry, try again ...')
            continue

    # Check if the algorithm currently defined for this geometry corresponds to the explicit permutation algorithm
    for algo in cg.algorithms:
        if algo.algorithm_type != 'EXPLICIT_PERMUTATIONS':
            raise ValueError('WRONG ALGORITHM !')

    algo = Algo()
    algo.permutations = []
    for perm in itertools.permutations(range(cg.coordination)):
        algo.permutations.append(perm)

    lgf = LocalGeometryFinder()
    lgf.setup_parameters(structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE)
    lgf.setup_test_perfect_environment(cg_symbol,
                                       randomness=True,
                                       indices='ORDERED')

    lgf.perfect_geometry = AbstractGeometry.from_cg(cg=cg)

    points_perfect = lgf.perfect_geometry.points_wocs_ctwocc()
    res = lgf.coordination_geometry_symmetry_measures_standard(
        coordination_geometry=cg, algo=algo, points_perfect=points_perfect)
    (csms, perms, algos, local2perfect_maps, perfect2local_maps) = res

    csms_with_recorded_permutation = []
    explicit_permutations = []
    for icsm, csm in enumerate(csms):
    def test_real_systems(self):
        # Initialize geometry and connectivity finders
        strat = SimplestChemenvStrategy()
        lgf = LocalGeometryFinder()
        cf = ConnectivityFinder()

        # Connectivity of LiFePO4
        struct = self.get_structure("LiFePO4")
        lgf.setup_structure(structure=struct)
        se = lgf.compute_structure_environments(only_atoms=["Li", "Fe", "P"],
                                                maximum_distance_factor=1.2)
        lse = LightStructureEnvironments.from_structure_environments(
            strategy=strat, structure_environments=se)
        # Make sure the initial structure and environments are correct
        for isite in range(0, 4):
            assert lse.structure[isite].specie.symbol == "Li"
            assert lse.coordination_environments[isite][0][
                "ce_symbol"] == "O:6"
        for isite in range(4, 8):
            assert lse.structure[isite].specie.symbol == "Fe"
            assert lse.coordination_environments[isite][0][
                "ce_symbol"] == "O:6"
        for isite in range(8, 12):
            assert lse.structure[isite].specie.symbol == "P"
            assert lse.coordination_environments[isite][0][
                "ce_symbol"] == "T:4"
        # Get the connectivity including all environments and check results
        sc = cf.get_structure_connectivity(lse)
        assert len(sc.environment_subgraphs
                   ) == 0  # Connected component not computed by default
        ccs = sc.get_connected_components(
        )  # by default, will use all the environments (O:6 and T:4 here)
        assert list(sc.environment_subgraphs.keys()) == [
            "O:6-T:4"
        ]  # Now the default components are there
        assert len(sc.environment_subgraphs) == 1
        assert len(ccs) == 1
        cc = ccs[0]
        assert len(cc) == 12
        assert cc.periodicity == "3D"
        assert (
            cc.description() == """Connected component with environment nodes :
Node #0 Li (O:6)
Node #1 Li (O:6)
Node #2 Li (O:6)
Node #3 Li (O:6)
Node #4 Fe (O:6)
Node #5 Fe (O:6)
Node #6 Fe (O:6)
Node #7 Fe (O:6)
Node #8 P (T:4)
Node #9 P (T:4)
Node #10 P (T:4)
Node #11 P (T:4)""")
        assert (cc.description(
            full=True) == """Connected component with environment nodes :
Node #0 Li (O:6), connected to :
  - Node #1 Li (O:6) with delta image cells
     (-1 0 1)
     (-1 1 1)
  - Node #4 Fe (O:6) with delta image cells
     (-1 1 1)
     (0 1 1)
  - Node #5 Fe (O:6) with delta image cells
     (0 0 1)
  - Node #6 Fe (O:6) with delta image cells
     (-1 1 0)
  - Node #7 Fe (O:6) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #8 P (T:4) with delta image cells
     (-1 0 1)
     (0 0 1)
  - Node #11 P (T:4) with delta image cells
     (-1 1 0)
     (0 1 0)
Node #1 Li (O:6), connected to :
  - Node #0 Li (O:6) with delta image cells
     (1 -1 -1)
     (1 0 -1)
  - Node #4 Fe (O:6) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #5 Fe (O:6) with delta image cells
     (1 0 0)
  - Node #6 Fe (O:6) with delta image cells
     (0 0 -1)
  - Node #7 Fe (O:6) with delta image cells
     (0 0 -1)
     (1 0 -1)
  - Node #8 P (T:4) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #11 P (T:4) with delta image cells
     (0 0 -1)
     (1 0 -1)
Node #2 Li (O:6), connected to :
  - Node #3 Li (O:6) with delta image cells
     (0 0 0)
     (0 1 0)
  - Node #4 Fe (O:6) with delta image cells
     (0 1 0)
  - Node #5 Fe (O:6) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #6 Fe (O:6) with delta image cells
     (-1 1 0)
     (0 1 0)
  - Node #7 Fe (O:6) with delta image cells
     (0 0 0)
  - Node #9 P (T:4) with delta image cells
     (0 1 0)
     (1 1 0)
  - Node #10 P (T:4) with delta image cells
     (-1 0 0)
     (0 0 0)
Node #3 Li (O:6), connected to :
  - Node #2 Li (O:6) with delta image cells
     (0 -1 0)
     (0 0 0)
  - Node #4 Fe (O:6) with delta image cells
     (0 0 0)
  - Node #5 Fe (O:6) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #6 Fe (O:6) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #7 Fe (O:6) with delta image cells
     (0 0 0)
  - Node #9 P (T:4) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #10 P (T:4) with delta image cells
     (-1 0 0)
     (0 0 0)
Node #4 Fe (O:6), connected to :
  - Node #0 Li (O:6) with delta image cells
     (0 -1 -1)
     (1 -1 -1)
  - Node #1 Li (O:6) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #2 Li (O:6) with delta image cells
     (0 -1 0)
  - Node #3 Li (O:6) with delta image cells
     (0 0 0)
  - Node #5 Fe (O:6) with delta image cells
     (0 -1 0)
     (0 0 0)
     (1 -1 0)
     (1 0 0)
  - Node #8 P (T:4) with delta image cells
     (0 -1 0)
     (0 0 0)
  - Node #9 P (T:4) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #11 P (T:4) with delta image cells
     (0 0 -1)
Node #5 Fe (O:6), connected to :
  - Node #0 Li (O:6) with delta image cells
     (0 0 -1)
  - Node #1 Li (O:6) with delta image cells
     (-1 0 0)
  - Node #2 Li (O:6) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #3 Li (O:6) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #4 Fe (O:6) with delta image cells
     (-1 0 0)
     (-1 1 0)
     (0 0 0)
     (0 1 0)
  - Node #8 P (T:4) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #9 P (T:4) with delta image cells
     (0 0 0)
     (0 1 0)
  - Node #10 P (T:4) with delta image cells
     (-1 0 0)
Node #6 Fe (O:6), connected to :
  - Node #0 Li (O:6) with delta image cells
     (1 -1 0)
  - Node #1 Li (O:6) with delta image cells
     (0 0 1)
  - Node #2 Li (O:6) with delta image cells
     (0 -1 0)
     (1 -1 0)
  - Node #3 Li (O:6) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #7 Fe (O:6) with delta image cells
     (0 -1 0)
     (0 0 0)
     (1 -1 0)
     (1 0 0)
  - Node #9 P (T:4) with delta image cells
     (1 0 0)
  - Node #10 P (T:4) with delta image cells
     (0 -1 0)
     (0 0 0)
  - Node #11 P (T:4) with delta image cells
     (0 0 0)
     (1 0 0)
Node #7 Fe (O:6), connected to :
  - Node #0 Li (O:6) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #1 Li (O:6) with delta image cells
     (-1 0 1)
     (0 0 1)
  - Node #2 Li (O:6) with delta image cells
     (0 0 0)
  - Node #3 Li (O:6) with delta image cells
     (0 0 0)
  - Node #6 Fe (O:6) with delta image cells
     (-1 0 0)
     (-1 1 0)
     (0 0 0)
     (0 1 0)
  - Node #8 P (T:4) with delta image cells
     (0 0 1)
  - Node #10 P (T:4) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #11 P (T:4) with delta image cells
     (0 0 0)
     (0 1 0)
Node #8 P (T:4), connected to :
  - Node #0 Li (O:6) with delta image cells
     (0 0 -1)
     (1 0 -1)
  - Node #1 Li (O:6) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #4 Fe (O:6) with delta image cells
     (0 0 0)
     (0 1 0)
  - Node #5 Fe (O:6) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #7 Fe (O:6) with delta image cells
     (0 0 -1)
Node #9 P (T:4), connected to :
  - Node #2 Li (O:6) with delta image cells
     (-1 -1 0)
     (0 -1 0)
  - Node #3 Li (O:6) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #4 Fe (O:6) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #5 Fe (O:6) with delta image cells
     (0 -1 0)
     (0 0 0)
  - Node #6 Fe (O:6) with delta image cells
     (-1 0 0)
Node #10 P (T:4), connected to :
  - Node #2 Li (O:6) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #3 Li (O:6) with delta image cells
     (0 0 0)
     (1 0 0)
  - Node #5 Fe (O:6) with delta image cells
     (1 0 0)
  - Node #6 Fe (O:6) with delta image cells
     (0 0 0)
     (0 1 0)
  - Node #7 Fe (O:6) with delta image cells
     (0 0 0)
     (1 0 0)
Node #11 P (T:4), connected to :
  - Node #0 Li (O:6) with delta image cells
     (0 -1 0)
     (1 -1 0)
  - Node #1 Li (O:6) with delta image cells
     (-1 0 1)
     (0 0 1)
  - Node #4 Fe (O:6) with delta image cells
     (0 0 1)
  - Node #6 Fe (O:6) with delta image cells
     (-1 0 0)
     (0 0 0)
  - Node #7 Fe (O:6) with delta image cells
     (0 -1 0)
     (0 0 0)""")
        # Get the connectivity for T:4 and O:6 separately and check results
        # Only tetrahedral
        sc.setup_environment_subgraph(environments_symbols=["T:4"])
        assert list(sc.environment_subgraphs.keys()) == ["O:6-T:4", "T:4"]
        ccs = sc.get_connected_components()
        assert len(ccs) == 4
        for cc in ccs:
            assert cc.periodicity == "0D"
        # Only octahedral
        sc.setup_environment_subgraph(environments_symbols=["O:6"])
        assert list(
            sc.environment_subgraphs.keys()) == ["O:6-T:4", "T:4", "O:6"]
        ccs = sc.get_connected_components()
        assert len(ccs) == 1
        cc = ccs[0]
        assert cc.periodicity == "3D"
        # Only Manganese octahedral
        sc.setup_environment_subgraph(environments_symbols=["O:6"],
                                      only_atoms=["Fe"])
        assert list(sc.environment_subgraphs.keys()) == [
            "O:6-T:4",
            "T:4",
            "O:6",
            "O:6#Fe",
        ]
        ccs = sc.get_connected_components()
        assert len(ccs) == 2
        for cc in ccs:
            assert cc.periodicity == "2D"

        # Connectivity of Li4Fe3Mn1(PO4)4
        struct = Structure.from_file(
            os.path.join(self.TEST_FILES_DIR, "Li4Fe3Mn1(PO4)4.cif"))
        lgf.setup_structure(structure=struct)
        se = lgf.compute_structure_environments(
            only_atoms=["Li", "Fe", "Mn", "P"], maximum_distance_factor=1.2)
        lse = LightStructureEnvironments.from_structure_environments(
            strategy=strat, structure_environments=se)
        # Make sure the initial structure and environments are correct
        for isite in range(0, 4):
            assert lse.structure[isite].specie.symbol == "Li"
            assert lse.coordination_environments[isite][0][
                "ce_symbol"] == "O:6"
        for isite in range(4, 5):
            assert lse.structure[isite].specie.symbol == "Mn"
            assert lse.coordination_environments[isite][0][
                "ce_symbol"] == "O:6"
        for isite in range(5, 8):
            assert lse.structure[isite].specie.symbol == "Fe"
            assert lse.coordination_environments[isite][0][
                "ce_symbol"] == "O:6"
        for isite in range(8, 12):
            assert lse.structure[isite].specie.symbol == "P"
            assert lse.coordination_environments[isite][0][
                "ce_symbol"] == "T:4"
        # Get the connectivity including all environments and check results
        sc = cf.get_structure_connectivity(lse)
        assert len(sc.environment_subgraphs
                   ) == 0  # Connected component not computed by default
        ccs = sc.get_connected_components(
        )  # by default, will use all the environments (O:6 and T:4 here)
        # Now connected components for the defaults are there :
        assert list(sc.environment_subgraphs.keys()) == ["O:6-T:4"]
        assert len(sc.environment_subgraphs) == 1
        assert len(ccs) == 1
        cc = ccs[0]
        assert cc.periodicity == "3D"
        # Get the connectivity for Li octahedral only
        ccs = sc.get_connected_components(environments_symbols=["O:6"],
                                          only_atoms=["Li"])
        assert list(sc.environment_subgraphs.keys()) == ["O:6-T:4", "O:6#Li"]
        assert len(ccs) == 2
        for cc in ccs:
            assert cc.periodicity == "1D"
            assert len(cc) == 2
        # Sort connected components as they might
        # come in a different order depending on
        # the algorithm used to get them.
        sorted_ccs = sorted(ccs, key=lambda x: sorted(x.graph.nodes())[0])
        assert (sorted_ccs[0].description(
            full=True) == """Connected component with environment nodes :
Node #0 Li (O:6), connected to :
  - Node #1 Li (O:6) with delta image cells
     (1 -1 1)
     (1 0 1)
Node #1 Li (O:6), connected to :
  - Node #0 Li (O:6) with delta image cells
     (-1 0 -1)
     (-1 1 -1)""")
        assert (sorted_ccs[1].description(
            full=True) == """Connected component with environment nodes :
Node #2 Li (O:6), connected to :
  - Node #3 Li (O:6) with delta image cells
     (0 -1 0)
     (0 0 0)
Node #3 Li (O:6), connected to :
  - Node #2 Li (O:6) with delta image cells
     (0 0 0)
     (0 1 0)""")
        # Get the connectivity for Mn octahedral only
        ccs = sc.get_connected_components(environments_symbols=["O:6"],
                                          only_atoms=["Mn"])
        assert list(sc.environment_subgraphs.keys()) == [
            "O:6-T:4", "O:6#Li", "O:6#Mn"
        ]
        assert len(ccs) == 1
        assert ccs[0].periodicity == "0D"
        # Get the connectivity for Fe octahedral only
        ccs = sc.get_connected_components(environments_symbols=["O:6"],
                                          only_atoms=["Fe"])
        assert list(sc.environment_subgraphs.keys()) == [
            "O:6-T:4",
            "O:6#Li",
            "O:6#Mn",
            "O:6#Fe",
        ]
        assert len(ccs) == 2
        ccs_periodicities = set(cc.periodicity for cc in ccs)
        assert ccs_periodicities == {"0D", "2D"}
Example #28
0
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))
Example #29
0
            break
        except LookupError:
            print('Wrong geometry, try again ...')
            continue

    # Check if the algorithm currently defined for this geometry corresponds to the explicit permutation algorithm
    for algo in cg.algorithms:
        if algo.algorithm_type != 'EXPLICIT_PERMUTATIONS':
            raise ValueError('WRONG ALGORITHM !')

    algo = Algo()
    algo.permutations = []
    for perm in itertools.permutations(range(cg.coordination)):
        algo.permutations.append(perm)

    lgf = LocalGeometryFinder()
    lgf.setup_parameters(structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE)
    lgf.setup_test_perfect_environment(cg_symbol, randomness=True, indices='ORDERED')

    lgf.perfect_geometry = AbstractGeometry.from_cg(cg=cg)

    points_perfect = lgf.perfect_geometry.points_wocs_ctwocc()
    res = lgf.coordination_geometry_symmetry_measures_standard(coordination_geometry=cg,
                                                               algo=algo,
                                                               points_perfect=points_perfect)
    (csms, perms, algos, local2perfect_maps, perfect2local_maps) = res

    csms_with_recorded_permutation = []
    explicit_permutations = []
    for icsm, csm in enumerate(csms):
        found = False
Example #30
0
 def setUpClass(cls):
     cls.lgf = LocalGeometryFinder()
     cls.lgf.setup_parameters(centering_type="standard")
     os.makedirs("tmp_dir")
Example #31
0
            for ii in range(nperms):
                shuffle(myindices)
                perms_iterator.append(list(myindices))

        for cg_symbol, cg_name in symbol_name_mapping.items():
            cg = allcg[cg_symbol]
            if cg.deactivate:
                continue

            print('Testing {} ({})'.format(cg_symbol, cg_name))

            cg = allcg[cg_symbol]
            if cg.points is None:
                continue

            lgf = LocalGeometryFinder()
            lgf.setup_parameters(
                structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE)

            # Reinitialize the itertools permutations
            if perms_type == 'all':
                perms_iterator = itertools.permutations(myindices)

            #Loop on the permutations
            iperm = 1
            for indices_perm in perms_iterator:

                lgf.setup_test_perfect_environment(cg_symbol,
                                                   indices=indices_perm,
                                                   randomness=True,
                                                   max_random_dist=0.1,
Example #32
0
def extract_average_spectra(species,
                            transition,
                            path=None,
                            save_as='avg_data.pkl',
                            verbose=1):
    """Documentation is identical to extract_sites_o6_s5_t4 except that this
    function extracts the average spectra for all site-types for every
    crystal structure.
    """

    logger = logging.getLogger()
    logger.setLevel(logging.CRITICAL)

    # set the path to where the extracted data is located
    if path is None:
        path = t4iss_defaults['t4iss_data']

    if verbose == 1:
        print("path is ", path)

    cell_counter = 0
    total_counter = 0
    key_site_counter = 0
    directory_counter = 0

    # initialize an empty dictionary which can be thought of as one hot
    # encoding the key will be of form O:6, T:4, etc. and the value will be
    # the index of the basis vector corresponding to that site - the labels
    # will be generated after this block is run
    key_site = {}

    # empty lists for all the cn data
    all_site_data = []
    all_cell_data = []

    # these files will end up raising errors during execution of the
    # following loops - avoid them
    forbidden = [".DS_Store", "CONTCAR", "*.pkl"]

    # assert that only strings with the correct species and transition are
    # added to the training dataset
    correct_string = str(species) + "-" + str(transition)

    # for cell (e.g. mp-390) in the desired data directory
    os_list_directory = os.listdir(path)
    N_os_list_directory = len(os_list_directory)

    for ii, cell in enumerate(os_list_directory[:5]):

        if verbose == 1:
            if ii % 20 == 0.0:
                print("%i/%i" % (ii, N_os_list_directory))

        # reset the cell counter
        cell_counter = 0
        pass_cell = False
        current_cell_data = []

        # define a path if cell isn't = forbidden
        if cell not in forbidden:
            cell_path = os.path.join(path, str(cell))

            try:
                xanes_data = read_xanes(cell_path, absorption_specie=species)
            except (ValueError, FileNotFoundError):
                # print("No %s in %s. Passing." % (species, cell_path))
                pass_cell = True

            # get the structure
            try:
                structure = mg.Structure.from_file(cell_path + "/CONTCAR")
            except (FileNotFoundError, NotADirectoryError):
                # skip if CONTCAR does not exist in the directory
                # or if it isn't a directory at all, there are a few of those
                pass_cell = True

            # skip if directory is empty
            if not pass_cell:  # call this first to avoid NotADirectoryError
                if os.listdir(cell_path) == []:
                    pass_cell = True

            if not pass_cell:
                # define a path to a given spectra/pickle file
                for sample in os.listdir(cell_path):
                    if sample not in forbidden:

                        pass_sample = False

                        # cell sample path
                        csp = os.path.join(cell_path, str(sample))

                        # assert that we're reading the correct species
                        # and correct transition
                        if correct_string in csp:
                            try:
                                with open(csp + "/xanes.pkl",
                                          'rb') as pickle_file:
                                    content = pickle.load(pickle_file)

                                # ensure we end up with content to analyze,
                                # if not pass it
                                try:
                                    save_stdout = sys.stdout
                                    sys.stdout = open('.trash', 'w')
                                    lgf = LocalGeometryFinder()
                                    cesym = get_cesym(lgf, structure,
                                                      content.structure[1])
                                    sys.stdout = save_stdout
                                except IndexError:
                                    pass_sample = True

                                # print(all_cn_data[key[cesym[0]]])
                                # raise ValueError

                                if pass_sample:
                                    pass
                                else:
                                    # add in the average data if this is the
                                    # first time the
                                    # directory / cell has been looked at
                                    if cell_counter == 0:
                                        all_cell_data.\
                                            append([cell, directory_counter,
                                                    deepcopy(xanes_data[0])])

                                    # if the symmetry label does not exist,
                                    # append it to the dictionary with its
                                    # type and index, and initialize a new
                                    # list in all_cn_data with key_counter as
                                    # its index
                                    if cesym[0] not in key_site.keys():
                                        key_site[cesym[0]] = key_site_counter
                                        all_site_data.append([])
                                        key_site_counter += 1

                                    x = [
                                        cell, directory_counter, cell_counter,
                                        deepcopy(content), cesym,
                                        content.multiplicity
                                    ]
                                    all_site_data[key_site[cesym[0]]].append(x)
                                    current_cell_data.append(x)
                                    cell_counter += 1
                                    total_counter += 1

                            except FileNotFoundError:
                                pass

        if pass_cell or (pass_sample and cell_counter == 0):
            pass
        else:
            # sanity check - can cross-reference with the atom id's using
            # VESTA
            # finder = SpacegroupAnalyzer(structure)
            # struct = finder.get_symmetrized_structure()
            # [sites, indices]  = struct.equivalent_sites,
            # struct.equivalent_indices
            # print(directory_counter, indices)

            # for every cell / directory (e.g. mvc-16746), generate an
            # individual dictionary which labels the proportion of each
            # coordination number present in the crystal structure
            temp_dictionary = {}

            # running counter of all the multiplicity numbers
            total_multiplicity = 0

            for xx in current_cell_data:

                # current multiplicity of xx
                cm = xx[3].multiplicity

                # if the current ce symbol does not exist in the
                # temp_dictionary, create it and initialize its counter equal
                # to the multiplicity of that entry
                if xx[4][0] not in temp_dictionary.keys():
                    temp_dictionary[xx[4][0]] = cm

                # else, it must have been previously initialized, and so we
                # should add the multiplicity to it
                else:
                    temp_dictionary[xx[4][0]] += cm

                # append the total multiplicity for normalizing later
                total_multiplicity += cm

            # next, modify each value in the dictionary: normalize by total
            # multiplicity
            for xx in temp_dictionary:
                temp_dictionary[xx] /= float(total_multiplicity)

            all_cell_data[directory_counter].append(temp_dictionary)
            directory_counter += 1

    path_save = os.path.join(path, save_as)

    with open(path_save, 'wb') as f:
        pickle.dump(all_cell_data, f)
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))
Example #34
0
    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'
                    )
                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)
Example #35
0
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('')
Example #36
0
            for ii in range(nperms):
                shuffle(myindices)
                perms_iterator.append(list(myindices))

        for cg_symbol, cg_name in symbol_name_mapping.items():
            cg = allcg[cg_symbol]
            if cg.deactivate:
                continue

            print('Testing {} ({})'.format(cg_symbol, cg_name))

            cg = allcg[cg_symbol]
            if cg.points is None:
                continue

            lgf = LocalGeometryFinder()
            lgf.setup_parameters(structure_refinement=lgf.STRUCTURE_REFINEMENT_NONE)



            # Reinitialize the itertools permutations
            if perms_type == 'all':
                perms_iterator = itertools.permutations(myindices)

            #Loop on the permutations
            iperm = 1
            for indices_perm in perms_iterator:


                lgf.setup_test_perfect_environment(cg_symbol, indices=indices_perm,
                                                   randomness=True, max_random_dist=0.1,
Example #37
0
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)

    myindices = range(cg.coordination_number)

    test = input(
        'Enter if you want to test all possible permutations ("all" or "a") or a given number of random permutations (i.e. "25")'
    )

    if test == 'all' or test == 'a':
        perms_iterator = itertools.permutations(myindices)
        nperms = factorial(cg.coordination_number)
    else:
        try:
            nperms = int(test)
        except Exception:
class CoordinationGeometryFinderTest(unittest2.TestCase):

    def setUp(self):
        self.lgf = LocalGeometryFinder()
        self.lgf.setup_parameters(centering_type='standard')
        self.strategies = [SimplestChemenvStrategy(), SimpleAbundanceChemenvStrategy()]
Example #39
0
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],
Example #40
0
        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])
Example #41
0
 def setUp(self):
     self.lgf = LocalGeometryFinder()
     self.lgf.setup_parameters(
         centering_type='standard',
         structure_refinement=self.lgf.STRUCTURE_REFINEMENT_NONE)
Example #42
0
    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)
Example #43
0
        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])
Example #44
0
    def get_light_structure_environment(self, only_cation_environments=False):
        """
        will return a LobsterLightStructureEnvironments object
        if the structure only contains coordination environments smaller 13
        Args:
            only_cation_environments: only data for cations will be returned

        Returns: LobsterLightStructureEnvironments Object

        """

        lgf = LocalGeometryFinder()
        lgf.setup_structure(structure=self.structure)
        list_ce_symbols = []
        list_csm = []
        list_permut = []
        for ival, _neigh_coords in enumerate(self.list_coords):

            if (len(_neigh_coords)) > 13:
                raise ValueError("Environment cannot be determined. Number of neighbors is larger than 13.")
            lgf.setup_local_geometry(isite=ival, coords=_neigh_coords, optimization=2)
            cncgsm = lgf.get_coordination_symmetry_measures(optimization=2)

            list_ce_symbols.append(min(cncgsm.items(), key=lambda t: t[1]["csm_wcs_ctwcc"])[0])
            list_csm.append(min(cncgsm.items(), key=lambda t: t[1]["csm_wcs_ctwcc"])[1]["csm_wcs_ctwcc"])
            list_permut.append(min(cncgsm.items(), key=lambda t: t[1]["csm_wcs_ctwcc"])[1]["indices"])

        if not only_cation_environments:
            lse = LobsterLightStructureEnvironments.from_Lobster(
                list_ce_symbol=list_ce_symbols,
                list_csm=list_csm,
                list_permutation=list_permut,
                list_neighsite=self.list_neighsite,
                list_neighisite=self.list_neighisite,
                structure=self.structure,
                valences=self.valences,
            )
        else:
            new_list_ce_symbols = []
            new_list_csm = []
            new_list_permut = []
            new_list_neighsite = []
            new_list_neighisite = []

            for ival, val in enumerate(self.valences):

                if val >= 0.0:

                    new_list_ce_symbols.append(list_ce_symbols[ival])
                    new_list_csm.append(list_csm[ival])
                    new_list_permut.append(list_permut[ival])
                    new_list_neighisite.append(self.list_neighisite[ival])
                    new_list_neighsite.append(self.list_neighsite[ival])
                else:
                    new_list_ce_symbols.append(None)
                    new_list_csm.append(None)
                    new_list_permut.append([])
                    new_list_neighisite.append([])
                    new_list_neighsite.append([])

            lse = LobsterLightStructureEnvironments.from_Lobster(
                list_ce_symbol=new_list_ce_symbols,
                list_csm=new_list_csm,
                list_permutation=new_list_permut,
                list_neighsite=new_list_neighsite,
                list_neighisite=new_list_neighisite,
                structure=self.structure,
                valences=self.valences,
            )

        return lse