Ejemplo n.º 1
0
    def en_difference_active(self, atoms=None):
        """Returns a list of electronegativity metrics, squared and summed over
        adsorbate bonds including those with the surface.

        Parameters
        ----------
        atoms : object
            ASE Atoms object.

        Returns
        ----------
        features : list
            If None was passed, the elements are strings, naming the feature.
        """
        labels = ['dist_' + s + '_active' for s in electronegativities]
        if atoms is None:
            return labels
        cm = atoms.connectivity
        ads = atoms.subsets['ads_atoms']
        site = atoms.subsets['site_atoms']
        active = ads + site
        bonds = cm[ads, :][:, active]
        active_numbers = atoms.numbers[active]
        ads_numbers = atoms.numbers[ads]
        en_active = list_mendeleev_params(active_numbers, electronegativities)
        en_ads = list_mendeleev_params(ads_numbers, electronegativities)
        delta_en = (en_ads[:, np.newaxis, :] -
                    en_active[np.newaxis, :, :]) ** 2
        en_result = list(np.einsum("ij,ijk->k", bonds, delta_en))
        assert len(en_result) == len(labels)
        return en_result
Ejemplo n.º 2
0
    def en_difference_chemi(self, atoms=None):
        """Returns a list of electronegativity metrics, squared and summed over
        adsorbate-site bonds.

        Parameters
        ----------
        atoms : object
            ASE Atoms object.

        Returns
        ----------
        features : list
            If None was passed, the elements are strings, naming the feature.
        """
        labels = ['dist_' + s + '_chemi' for s in electronegativities]
        if atoms is None:
            return labels
        cm = atoms.connectivity
        chemi = atoms.subsets['chemisorbed_atoms']
        site = atoms.subsets['site_atoms']
        bonds = cm[chemi, :][:, site]
        chemi_numbers = atoms.numbers[chemi]
        site_numbers = atoms.numbers[site]
        en_chemi = list_mendeleev_params(chemi_numbers, electronegativities)
        en_site = list_mendeleev_params(site_numbers, electronegativities)
        delta_en = (en_chemi[:, np.newaxis, :] -
                    en_site[np.newaxis, :, :]) ** 2
        en_result = list(np.einsum("ij,ijk->k", bonds, delta_en))
        assert len(en_result) == len(labels)
        return en_result
Ejemplo n.º 3
0
    def term(self, atoms=None):
        """Return a fingerprint vector with propeties averaged over the
        termination atoms.

        Parameters
        ----------
        atoms : object
        """
        labels = make_labels(self.slab_params, '', '_term')
        labels.append('ground_state_magmom_term')
        if atoms is None:
            return labels
        else:
            if ('key_value_pairs' in atoms.info and
                    'term' in atoms.info['key_value_pairs']):
                term = atoms.info['key_value_pairs']['term']
                numbers = [atomic_numbers[s] for s in string2symbols(term)]
            elif 'termination_atoms' in atoms.subsets:
                term = atoms.subsets['termination_atoms']
                numbers = atoms.numbers[term]
            else:
                raise NotImplementedError("termination fingerprint.")
            dat = list_mendeleev_params(numbers, params=self.slab_params)
            result = list(np.nanmean(dat, axis=0))
            result += [np.nanmean([gs_magmom[z] for z in numbers])]
            check_labels(labels, result, atoms)
            return result
Ejemplo n.º 4
0
    def mean_surf_ligands(self, atoms=None):
        """Function that takes an atoms objects and returns a fingerprint
        vector containing the count of nearest neighbors and properties of
        the nearest neighbors.

        Parameters
        ----------
        atoms : object
            ASE Atoms object.

        Returns
        ----------
        features : list
            If None was passed, the elements are strings, naming the feature.
        """
        labels = ['nn_surf_ligands', 'identnn_surf_ligands']
        labels += make_labels(self.slab_params, '', '_surf_ligands')
        labels.append('ground_state_magmom_surf_ligands')
        if atoms is None:
            return labels
        else:
            ligand_atoms = atoms.subsets['ligand_atoms']
            numbers = atoms.numbers[ligand_atoms]
            # Import CatLearn data on that element.
            dat = list_mendeleev_params(numbers, params=self.slab_params)
            result = list(np.nanmean(dat, axis=0))
            result += [np.nanmean([gs_magmom[z] for z in numbers])]
            # Append count of ligand atoms.
            result = [len(ligand_atoms), len(np.unique(numbers))] + result
            check_labels(labels, result, atoms)
            return result
Ejemplo n.º 5
0
    def ads_av(self, atoms=None):
        """Function that takes an atoms objects and returns a fingerprint
        vector with averages of the atomic properties of the adsorbate.

        Parameters
        ----------
        atoms : object
            ASE Atoms object.

        Returns
        ----------
        features : list
            If None was passed, the elements are strings, naming the feature.
        """
        ads_params = default_params + ['econf', 'ionenergies']
        labels = make_labels(ads_params, '', '_ads_av')
        labels.append('ground_state_magmom_ads_av')
        if atoms is None:
            return labels
        else:
            numbers = [atoms[j].number for j in atoms.subsets['ads_atoms']]
            dat = list_mendeleev_params(numbers, params=ads_params)
            result = list(np.nanmean(dat, axis=0))
            result += [np.nanmean([gs_magmom[z] for z in numbers])]
            check_labels(labels, result, atoms)
            return result
Ejemplo n.º 6
0
    def mean_chemisorbed_atoms(self, atoms=None):
        """Function that takes an atoms objects and returns a fingerprint
        vector containing properties of the closest add atom to a surface
        metal atom.

        Parameters
        ----------
        atoms : object
            ASE Atoms object.

        Returns
        ----------
        features : list
            If None was passed, the elements are strings, naming the feature.
        """
        extra_ads_params = ['atomic_radius', 'heat_of_formation',
                            'oxistates', 'block', 'econf', 'ionenergies']
        labels = make_labels(default_params + extra_ads_params, '', '_ads1')
        labels.append('ground_state_magmom_ads1')
        if atoms is None:
            return labels
        else:
            # Get atomic number of alpha adsorbate atom.
            chemisorbed_atoms = atoms.subsets['chemisorbed_atoms']
            numbers = atoms.numbers[chemisorbed_atoms]
            # Import CatLearn data on that element.
            dat = list_mendeleev_params(numbers, params=default_params +
                                        extra_ads_params)
            result = list(np.nanmean(dat, axis=0))
            result += [np.nanmean([gs_magmom[z] for z in numbers])]
            check_labels(labels, result, atoms)
            return result
Ejemplo n.º 7
0
    def sum_site(self, atoms=None):
        """Function that takes an atoms objects and returns a fingerprint
        vector with properties summed over the surface metal atoms
        closest to an add atom.

        Parameters
        ----------
        atoms : object
            ASE Atoms object.

        Returns
        ----------
        features : list
            If None was passed, the elements are strings, naming the feature.
        """
        labels = make_labels(self.slab_params, '', '_site_sum')
        labels.append('ground_state_magmom_site_sum')
        if atoms is None:
            return labels
        else:
            numbers = [atoms[j].number for j in atoms.subsets['site_atoms']]
            dat = list_mendeleev_params(numbers, params=self.slab_params)
            result = list(np.nansum(dat, axis=0))
            result += [np.nansum([gs_magmom[z] for z in numbers])]
            check_labels(labels, result, atoms)
            return result
Ejemplo n.º 8
0
    def bulk(self, atoms=None):
        """Return a fingerprint vector with propeties averaged over
        the bulk atoms.

        Parameters
        ----------
        atoms : object
            ASE Atoms object.

        Returns
        ----------
        features : list
            If None was passed, the elements are strings, naming the feature.
        """
        labels = make_labels(self.slab_params, '', '_bulk')
        labels.append('ground_state_magmom_bulk')
        if atoms is None:
            return labels
        else:
            if ('key_value_pairs' in atoms.info and
                    'bulk' in atoms.info['key_value_pairs']):
                bulk = atoms.info['key_value_pairs']['bulk']
                numbers = [atomic_numbers[s] for s in string2symbols(bulk)]
            elif 'bulk_atoms' in atoms.subsets:
                bulk = atoms.subsets['bulk_atoms']
                numbers = atoms.numbers[bulk]
            else:
                raise NotImplementedError("bulk fingerprint.")
            dat = list_mendeleev_params(numbers, params=self.slab_params)
            result = list(np.nanmean(dat, axis=0))
            result += [np.nanmean([gs_magmom[z] for z in numbers])]
            check_labels(labels, result, atoms)
            return result
Ejemplo n.º 9
0
 def bulk_summation(self, atoms=None):
     """Return a fingerprint vector with propeties of the element name
     saved in the atoms.info['key_value_pairs']['bulk']"""
     if atoms is None:
         return ['atomic_number_sum',
                 'atomic_volume_sum',
                 'boiling_point_sum',
                 'density_sum',
                 'dipole_polarizability_sum',
                 'electron_affinity_sum',
                 'group_id_sum',
                 'lattice_constant_sum',
                 'melting_point_sum',
                 'period_sum',
                 'vdw_radius_sum',
                 'covalent_radius_cordero_sum',
                 'en_allen_sum',
                 'atomic_weight_sum',
                 'c6_sum',
                 'c6_gb_sum',
                 'en_allred-rochow_sum',
                 'en_cottrell-sutton_sum',
                 'en_gordy_sum',
                 'en_martynov-batsanov_sum',
                 'en_mulliken_sum',
                 'en_nagle_sum',
                 'en_ghosh_sum',
                 'gas_basicity_sum',
                 'metallic_radius_sum',
                 'atomic_radius_sum',
                 'heat_of_formation_sum',
                 'dft_sum_modulus_sum',
                 'dft_rhodensity_sum',
                 'en_pauling_sum',
                 'dbcenter_sum',
                 'dbfilling_sum',
                 'dbwidth_sum',
                 'dbskew_sum',
                 'dbkurtosis_sum',
                 'sblock_sum',
                 'pblock_sum',
                 'dblock_sum',
                 'fblock_sum',
                 'ne_outer_sum',
                 'ne_s_sum',
                 'ne_p_sum',
                 'ne_d_sum',
                 'ne_f_sum',
                 'ionenergy_sum',
                 'ground_state_magmom_sum']
     else:
         numbers = atoms.get_atomic_numbers()
         dat = list_mendeleev_params(numbers, params=default_params +
                                     self.extra_params)
         result = list(np.nansum(dat, axis=0))
         result += [np.nansum([gs_magmom[z] for z in numbers])]
         return result
Ejemplo n.º 10
0
    def get_autocorrelation(self, atoms):
        """Return the autocorrelation fingerprint for a molecule."""
        connectivity = catlearn_neighborlist(atoms)

        G = nx.Graph(connectivity)
        distance_matrix = nx.floyd_warshall_numpy(G)
        Bm = np.zeros(distance_matrix.shape)

        n = len(self.parameters)
        W = list_mendeleev_params(atoms.numbers, self.parameters).T

        fingerprint = np.zeros(n * (self.dstar + 1))
        for dd in range(self.dstar + 1):
            B = Bm.copy()
            B[distance_matrix == dd] = 1
            AC = np.dot(np.dot(W, B), W.T).diagonal()
            fingerprint[n * dd:n * (dd + 1)] = AC

        return fingerprint
Ejemplo n.º 11
0
    def en_difference_ads(self, atoms=None):
        """Returns a list of electronegativity metrics, squared and summed over
        bonds within the adsorbate atoms.

        Parameters
        ----------
        atoms : object
        """
        labels = ['dist_' + s + '_ads' for s in electronegativities]
        if atoms is None:
            return labels
        cm = atoms.connectivity
        ads = atoms.subsets['ads_atoms']
        bonds = cm[ads, :][:, ads]
        ads_numbers = atoms.numbers[ads]
        en_ads = list_mendeleev_params(ads_numbers, electronegativities)
        delta_en = (en_ads[:, np.newaxis, :] - en_ads[np.newaxis, :, :])**2
        en_result = list(np.einsum("ij,ijk->k", bonds, delta_en))
        assert len(en_result) == len(labels)
        return en_result
Ejemplo n.º 12
0
    def median_site(self, atoms=None):
        """Function that takes an atoms objects and returns a fingerprint
        vector with properties averaged over the surface metal atoms
        closest to an add atom.

        Parameters
        ----------
        atoms : object
        """
        labels = make_labels(self.slab_params, '', '_site_med')
        labels.append('ground_state_magmom_site_med')
        if atoms is None:
            return labels
        else:
            numbers = [atoms[j].number for j in atoms.subsets['site_atoms']]
            dat = list_mendeleev_params(numbers, params=self.slab_params)
            result = list(np.nanmedian(dat, axis=0))
            result += [np.nanmedian([gs_magmom[z] for z in numbers])]
            check_labels(labels, result, atoms)
            return result
Ejemplo n.º 13
0
    def conv_bulk(self, atoms=None):
        """Return a fingerprint vector with propeties convoluted over the
        bulk atoms.

        Parameters
        ----------
        atoms : object
            A single atoms object.
        """
        labels = [
            'atomic_number_bulk_conv_0', 'atomic_volume_bulk_conv_0',
            'boiling_point_bulk_conv_0', 'density_bulk_conv_0',
            'dipole_polarizability_bulk_conv_0',
            'electron_affinity_bulk_conv_0', 'group_id_bulk_conv_0',
            'lattice_constant_bulk_conv_0', 'melting_point_bulk_conv_0',
            'period_bulk_conv_0', 'vdw_radius_bulk_conv_0',
            'covalent_radius_cordero_bulk_conv_0', 'en_allen_bulk_conv_0',
            'atomic_weight_bulk_conv_0', 'atomic_radius_bulk_conv_0',
            'heat_of_formation_bulk_conv_0', 'dft_bulk_modulus_bulk_conv_0',
            'dft_rhodensity_bulk_conv_0', 'dbcenter_bulk_conv_0',
            'dbfilling_bulk_conv_0', 'dbwidth_bulk_conv_0',
            'dbskew_bulk_conv_0', 'dbkurtosis_bulk_conv_0',
            'oxi_min_bulk_conv_0', 'oxi_med_bulk_conv_0',
            'oxi_max_bulk_conv_0', 'sblock_bulk_conv_0', 'pblock_bulk_conv_0',
            'dblock_bulk_conv_0', 'fblock_bulk_conv_0', 'ne_outer_bulk_conv_0',
            'ne_s_bulk_conv_0', 'ne_p_bulk_conv_0', 'ne_d_bulk_conv_0',
            'ne_f_bulk_conv_0', 'ionenergy_bulk_conv_0',
            'ground_state_magmom_bulk_conv_0', 'atomic_number_bulk_conv_1',
            'atomic_volume_bulk_conv_1', 'boiling_point_bulk_conv_1',
            'density_bulk_conv_1', 'dipole_polarizability_bulk_conv_1',
            'electron_affinity_bulk_conv_1', 'group_id_bulk_conv_1',
            'lattice_constant_bulk_conv_1', 'melting_point_bulk_conv_1',
            'period_bulk_conv_1', 'vdw_radius_bulk_conv_1',
            'covalent_radius_cordero_bulk_conv_1', 'en_allen_bulk_conv_1',
            'atomic_weight_bulk_conv_1', 'atomic_radius_bulk_conv_1',
            'heat_of_formation_bulk_conv_1', 'dft_bulk_modulus_bulk_conv_1',
            'dft_rhodensity_bulk_conv_1', 'dbcenter_bulk_conv_1',
            'dbfilling_bulk_conv_1', 'dbwidth_bulk_conv_1',
            'dbskew_bulk_conv_1', 'dbkurtosis_bulk_conv_1',
            'oxi_min_bulk_conv_1', 'oxi_med_bulk_conv_1',
            'oxi_max_bulk_conv_1', 'sblock_bulk_conv_1', 'pblock_bulk_conv_1',
            'dblock_bulk_conv_1', 'fblock_bulk_conv_1', 'ne_outer_bulk_conv_1',
            'ne_s_bulk_conv_1', 'ne_p_bulk_conv_1', 'ne_d_bulk_conv_1',
            'ne_f_bulk_conv_1', 'ionenergy_bulk_conv_1',
            'ground_state_magmom_bulk_conv_1'
        ]

        if atoms is None:
            return labels

        if 'bulk_atoms' in atoms.subsets:
            bulk = atoms.subsets['bulk_atoms']
            numbers = atoms.numbers[bulk]
            connectivity = atoms.connectivity[bulk]
        else:
            raise NotImplementedError("bulk convoluted fingerprint.")
        slab_numbers = atoms.numbers
        dat_b = list_mendeleev_params(numbers, params=self.slab_params)
        dat = list_mendeleev_params(slab_numbers, params=self.slab_params)
        result = list(np.sqrt(np.sum(dat_b * dat_b, axis=0)) / len(bulk))
        result += [
            np.sqrt(np.sum([gs_magmom[z]**2 for z in numbers])) / len(bulk)
        ]
        for i in range(dat.shape[1]):
            result += [
                np.sqrt(
                    np.sum(dat[:, i][:len(connectivity)].reshape(
                        len(connectivity), 1) * (dat[:, i] * connectivity))) /
                len(bulk)
            ]
        gsm = np.array([gs_magmom[z] for z in atoms.numbers])
        result += [
            np.sqrt(
                np.sum(gsm[:len(connectivity)].reshape(len(connectivity), 1) *
                       (gsm * connectivity))) / len(bulk)
        ]
        check_length(labels, result, atoms)

        return result