コード例 #1
0
ファイル: data.py プロジェクト: PDoakORNL/pymatgen
def get_boxed_molecule(input_structure, box_size):
    """
    Return a boxed molecule.

    Args:
        input_structure(Molecule/Structure): either Molecule of Structure object
        box_size (list): [[x_min, x_max], [y_min, y_max], [z_min, z_max]]

    Returns:
        Structure
    """
    box_lengths = [min_max[1] - min_max[0] for min_max in box_size]
    # be defensive about the box size
    if isinstance(input_structure, Molecule):
        boxed_molecule = input_structure.get_boxed_structure(*box_lengths)
    elif isinstance(input_structure, Structure):
        max_length = max(input_structure.lattice.abc)
        max_box_size = max(box_lengths)
        boxed_molecule = Molecule.from_sites(input_structure.sites)
        if max_length < max_box_size:
            boxed_molecule = \
                boxed_molecule.get_boxed_structure(*box_lengths)
        else:
            boxed_molecule = \
                boxed_molecule.get_boxed_structure(max_length,
                                                   max_length, max_length)
    else:
        raise ValueError("molecule must be an object of Molecule or "
                         "Structure ")
    return boxed_molecule
コード例 #2
0
def generate_Si_cluster():
    from pymatgen.io.xyz import XYZ

    coords = [[0, 0, 0], [0.75, 0.5, 0.75]]
    lattice = Lattice.from_parameters(a=3.84, b=3.84, c=3.84, alpha=120, beta=90, gamma=60)

    struct = Structure(lattice, ['Si', 'Si'], coords)
    struct.make_supercell([2, 2, 2])

    # Creating molecule for testing
    mol = Molecule.from_sites(struct)
    XYZ(mol).write_file(os.path.join(test_dir, "Si_cluster.xyz"))

    # Rorate the whole molecule
    mol_rotated = mol.copy()
    rotate(mol_rotated, seed=42)
    XYZ(mol_rotated).write_file(os.path.join(test_dir, "Si_cluster_rotated.xyz"))

    # Perturbing the atom positions
    mol_perturbed = mol.copy()
    perturb(mol_perturbed, 0.3, seed=42)
    XYZ(mol_perturbed).write_file(os.path.join(test_dir, "Si_cluster_perturbed.xyz"))

    # Permuting the order of the atoms
    mol_permuted = mol.copy()
    permute(mol_permuted, seed=42)
    XYZ(mol_permuted).write_file(os.path.join(test_dir, "Si_cluster_permuted.xyz"))

    # All-in-one
    mol2 = mol.copy()
    rotate(mol2, seed=42)
    perturb(mol2, 0.3, seed=42)
    permute(mol2, seed=42)
    XYZ(mol2).write_file(os.path.join(test_dir, "Si_cluster_2.xyz"))
コード例 #3
0
def get_m_graph_from_site_data(s_data):
    mol = Molecule.from_sites([Site.from_dict(isite)
                               for isite in s_data['local_graph']['sites']])
    mg = MoleculeGraph.with_empty_graph(mol)
    for i in range(1, len(mg)):
        mg.add_edge(0, i)
    return mg
コード例 #4
0
ファイル: pbc.py プロジェクト: caer200/ocelot_api
    def unwrap_and_squeeze(pstructure: Structure):
        """
        after unwrapping, the mols can be far away from each other, this tries to translate them s.t. they stay together

        :param pstructure:
        :return:
        """
        mols, unwrap_structure, psiteblocks = PBCparser.unwrap(pstructure)
        if len(mols) > 1:
            refpoint = mols[0].center_of_mass
            refpoint = unwrap_structure.lattice.get_fractional_coords(refpoint)
            for i in range(1, len(mols)):
                varmol = mols[i]
                varpoint = varmol.center_of_mass
                varpoint = unwrap_structure.lattice.get_fractional_coords(varpoint)
                distance, fctrans = PBCparser.get_dist_and_trans(unwrap_structure.lattice, refpoint, varpoint)
                for j in range(len(psiteblocks[i])):
                    psiteblocks[i][j]._frac_coords += fctrans
            squeeze_psites = []
            squeeze_mols = []
            pblock: [PeriodicSite]
            for pblock in psiteblocks:
                squeeze_block = []
                for ps in pblock:
                    squeeze_psites.append(ps)
                    squeeze_block.append(
                        Site(ps.species_string, ps.coords, properties=ps.properties))  # do we need deepcopy?
                mol = Molecule.from_sites(squeeze_block)
                squeeze_mols.append(mol)
            squeeze_unwrap_structure = Structure.from_sites(squeeze_psites)
            return squeeze_mols, squeeze_unwrap_structure, psiteblocks


        else:
            return mols, unwrap_structure, psiteblocks
コード例 #5
0
    def from_structure(cls, input_structure, box_size, set_charge=True, translate=True):
        """
        Set LammpsData from the given structure. If the input structure is
        a Structure, it is converted to a molecule. TIf the molecule doesnt fit
        in the input box, the box size is updated based on the max and min site
        coordinates of the molecules.

        Args:
            input_structure (Molecule/Structure)
            box_size (list): [[x_min, x_max], [y_min, y_max], [z_min, z_max]]
            set_charge (bool): whether or not to set the charge field in
                Atoms. If true, the charge will be non-zero only if the
                input_structure has the "charge" site property set.
            translate (bool): if true move the molecule to the center of the
                new box(it that is required).

        Returns:
            LammpsData
        """
        if isinstance(input_structure, Structure):
            input_structure = Molecule.from_sites(input_structure.sites)
        box_size = cls.check_box_size(input_structure, box_size, translate=translate)
        natoms, natom_types, atomic_masses_dict = cls.get_basic_system_info(input_structure.copy())
        atoms_data = cls.get_atoms_data(input_structure, atomic_masses_dict,
                                        set_charge=set_charge)
        return cls(box_size, atomic_masses_dict.values(), atoms_data)
コード例 #6
0
ファイル: data.py プロジェクト: arafune/pymatgen
def get_boxed_molecule(input_structure, box_size):
    """
    Return a boxed molecule.

    Args:
        input_structure(Molecule/Structure): either Molecule of Structure object
        box_size (list): [[x_min, x_max], [y_min, y_max], [z_min, z_max]]

    Returns:
        Structure
    """
    box_lengths = [min_max[1] - min_max[0] for min_max in box_size]
    # be defensive about the box size
    if isinstance(input_structure, Molecule):
        boxed_molecule = input_structure.get_boxed_structure(*box_lengths)
    elif isinstance(input_structure, Structure):
        max_length = max(input_structure.lattice.abc)
        max_box_size = max(box_lengths)
        boxed_molecule = Molecule.from_sites(input_structure.sites)
        if max_length < max_box_size:
            boxed_molecule = \
                boxed_molecule.get_boxed_structure(*box_lengths)
        else:
            boxed_molecule = \
                boxed_molecule.get_boxed_structure(max_length,
                                                   max_length, max_length)
    else:
        raise ValueError("molecule must be an object of Molecule or "
                         "Structure ")
    return boxed_molecule
コード例 #7
0
def get_scene(data, site_index):
    site_data = data['site_data'][site_index]
    mol = Molecule.from_sites([Site.from_dict(isite)
                               for isite in site_data['local_graph']['sites']])
    scene = get_m_graph_from_mol(mol).get_scene()
    scene.name = "ref-site"
    return scene
コード例 #8
0
ファイル: calec.py プロジェクト: caer200/ocelot_api
    def input_gen_gauss(self,
                        charge=None,
                        spin_multiplicity=None,
                        title=None,
                        functional='HF',
                        basis_set='6-31G(d)',
                        route_parameters=SUGGESTED_route_parameters,
                        input_parameters=None,
                        link0_parameters=None,
                        dieze_tag='#P',
                        gen_basis=None):

        ginobj_mono_a = GaussianInput(self.mono_a, charge, spin_multiplicity,
                                      title, functional, basis_set,
                                      route_parameters, input_parameters,
                                      link0_parameters, dieze_tag, gen_basis)

        ginobj_mono_b = GaussianInput(self.mono_a, charge, spin_multiplicity,
                                      title, functional, basis_set,
                                      route_parameters, input_parameters,
                                      link0_parameters, dieze_tag, gen_basis)

        dimer_sites = self.mono_a.sites + self.mono_b.sites
        dimer_pmgmol = Molecule.from_sites(dimer_sites)
        ginobj_dimer = GaussianInput(dimer_pmgmol, charge, spin_multiplicity,
                                     title, functional, basis_set,
                                     route_parameters, input_parameters,
                                     link0_parameters, dieze_tag, gen_basis)
        return ginobj_mono_a.to_string(
            cart_coords=True), ginobj_mono_b.to_string(
                cart_coords=True), ginobj_dimer.to_string(cart_coords=True)
コード例 #9
0
ファイル: structure.py プロジェクト: DCoupry/autografs
    def extract_dummies(self) -> Molecule:
        """
        Creates and returns a pymatgen Molecule containing only
        the dummies from the original Fragment.atoms object

        Returns
        -------
        Molecule
            The extracted dummy atoms
        """
        dummies_idx = self.atoms.indices_from_symbol("X")
        dummies = Molecule.from_sites([self.atoms[i] for i in dummies_idx])
        return dummies
コード例 #10
0
ファイル: configuration.py プロジェクト: caer200/ocelot_api
 def from_labeled_clean_pstructure(cls, pstructure: Structure, occu=1.0):
     unwrap_structure = deepcopy(pstructure)
     psites = list(unwrap_structure.sites)
     k = lambda x: x.properties['imol']
     psites.sort(key=k)
     mols = []
     for imol, group in groupby(psites, key=k):
         mols.append(Molecule.from_sites(list(group)))
     molconformers = []
     for m in mols:
         try:
             mc = MolConformer.from_pmgmol(m)
             molconformers.append(mc)
         except ConformerError:
             warnings.warn(
                 'conformer init failed for one molecule in the cell')
     return cls(molconformers, unwrap_structure, occu)
コード例 #11
0
def conver2zindo(pmgmol):
    """
    this will replace elements that are not in Zindo_elements with elements in the same group
    """
    if pmgmol is None:
        return None
    sites = pmgmol.sites
    newsites = []
    for s in sites:
        if not s.species_string in Zindo_elements:
            group = Element(s.species_string).group
            samegroup_symbols = [symbol for symbol in Zindo_elements if Element(symbol).group == group]
            replacement = sorted(samegroup_symbols, key=lambda x: Element(x).number, reverse=True)[0]
            newsites.append(Site(replacement, s.coords))
        else:
            newsites.append(Site(s.species_string, s.coords))
    return Molecule.from_sites(newsites)
コード例 #12
0
ファイル: molecule_matcher.py プロジェクト: janosh/pymatgen
    def fit(self, p: Molecule):
        """Order, rotate and transform `p` molecule according to the best match.

        Args:
            p: a `Molecule` object what will be matched with the target one.

        Returns:
            p_prime: Rotated and translated of the `p` `Molecule` object
            rmsd: Root-mean-square-deviation between `p_prime` and the `target`
        """

        inds, U, V, rmsd = self.match(p)

        # Translate and rotate `mol1` unto `mol2` using Kabsch algorithm.
        p_prime = Molecule.from_sites([p[i] for i in inds])
        for site in p_prime:
            site.coords = np.dot(site.coords, U) + V

        return p_prime, rmsd
コード例 #13
0
ファイル: cgd2pkl.py プロジェクト: DCoupry/autografs
def analyze(topology: Structure, skin: float = 5e-3) -> List[Molecule]:
    # containers for the output
    fragments = []
    # we iterate over non-dummies
    dmat = topology.distance_matrix
    dummies = numpy.array(topology.indices_from_symbol("X"))
    not_dummies = numpy.array(
        [i for i in range(len(topology)) if i not in dummies])
    # initialize and set tags
    tags = numpy.zeros(len(topology), dtype=int)
    tags[dummies] = dummies + 1
    topology.add_site_property(property_name="tags", values=tags)
    # TODO : site properties
    # get the distances between centers and connections
    distances = dmat[not_dummies][:, dummies]
    coordinations = numpy.array(topology.atomic_numbers)[not_dummies]
    partitions = numpy.argsort(distances, axis=1)
    for center_idx, best_dummies in enumerate(partitions):
        coordination = coordinations[center_idx]
        if coordination < len(best_dummies):
            best_dummies = best_dummies[:coordination]
        cutoff = distances[center_idx][best_dummies].max() + skin
        # now extract the corresponding fragment
        fragment_center = topology.sites[not_dummies[center_idx]]
        fragment_sites = topology.get_neighbors(fragment_center, r=cutoff)
        # some topologies in the RCSR have a crazy size
        # we ignore them with the heat of a thousand suns
        assert len(
            fragment_sites) <= 12, "Fragment size larger than limit of 12."
        # store as molecule to use the point group analysis
        fragment = Molecule.from_sites(
            fragment_sites)  #, charge=1, spin_multiplicity=1)
        # this is needed because X have no mass, leading to a
        # symmetrization error.
        fragment.replace_species({"X": "He"})
        pg = PointGroupAnalyzer(fragment, tolerance=0.1)
        # from pymatgen.io.ase import AseAtomsAdaptor
        # view(AseAtomsAdaptor.get_atoms(fragment))
        if pg.sch_symbol == "C1":
            raise ("NoSymm")
        fragment.replace_species({"He": "X"})
        fragments.append(Fragment(atoms=fragment, symmetry=pg, name="slot"))
    return fragments
コード例 #14
0
ファイル: molecule_matcher.py プロジェクト: janosh/pymatgen
    def fit(self, p: Molecule, ignore_warning=False):
        """Order, rotate and transform `p` molecule according to the best match.

        A `ValueError` will be raised when the total number of possible combinations
        become unfeasible (more than a million combinations).

        Args:
            p: a `Molecule` object what will be matched with the target one.
            ignore_warning: ignoring error when the number of combination is too large

        Returns:
            p_prime: Rotated and translated of the `p` `Molecule` object
            rmsd: Root-mean-square-deviation between `p_prime` and the `target`
        """

        inds, U, V, rmsd = self.match(p, ignore_warning=ignore_warning)

        p_prime = Molecule.from_sites([p[i] for i in inds])
        for site in p_prime:
            site.coords = np.dot(site.coords, U) + V

        return p_prime, rmsd
コード例 #15
0
ファイル: interface.py プロジェクト: matk86/MPInterfaces
 def position_mols(self):
     """
     position the center of masses of the molecules wrt each other
     first movement is in the x direction
     """
     new_mol = self.mols[0]
     mov_vec = np.array([1, 0, 0])
     for i in range(len(self.mols) - 1):
         # cm1 = new_mol.center_of_mass
         new_cm = new_mol.center_of_mass
         # cm2 = self.mols[i+1].center_of_mass
         new_cm = new_cm + self.cm_dist[i] * mov_vec
         mov_vec = self.get_perp_vec(self.mol_vecs[i], mov_vec)
         mov_vec = mov_vec / np.linalg.norm(mov_vec)
         new_coords = self.mols[i + 1].cart_coords + new_cm
         self.mols[i + 1] = Molecule(
             self.mols[i + 1].species_and_occu,
             new_coords,
             charge=self.mols[i + 1]._charge,
             spin_multiplicity=self.mols[i + 1]._spin_multiplicity,
             site_properties=self.mols[i + 1].site_properties)
         new_mol = Molecule.from_sites(self.mols[i].sites +
                                       self.mols[i + 1].sites,
                                       validate_proximity=True)
コード例 #16
0
ファイル: interface.py プロジェクト: henniggroup/MPInterfaces
 def position_mols(self):
     """
     position the center of masses of the molecules wrt each other
     first movement is in the x direction
     """
     new_mol = self.mols[0]
     mov_vec = np.array([1, 0, 0])
     for i in range(len(self.mols) - 1):
         # cm1 = new_mol.center_of_mass
         new_cm = new_mol.center_of_mass
         # cm2 = self.mols[i+1].center_of_mass
         new_cm = new_cm + self.cm_dist[i] * mov_vec
         mov_vec = self.get_perp_vec(self.mol_vecs[i], mov_vec)
         mov_vec = mov_vec / np.linalg.norm(mov_vec)
         new_coords = self.mols[i + 1].cart_coords + new_cm
         self.mols[i + 1] = Molecule(
             self.mols[i + 1].species_and_occu,
             new_coords,
             charge=self.mols[i + 1]._charge,
             spin_multiplicity=self.mols[i + 1]._spin_multiplicity,
             site_properties=self.mols[i + 1].site_properties)
         new_mol = Molecule.from_sites(
             self.mols[i].sites + self.mols[i + 1].sites,
             validate_proximity=True)
コード例 #17
0
def get_closest_matched(ref_data, site_index, all_random_sites):
    """
    Find the 10 most similar sites
    Args:
        ref_data:
        site_index:
        all_random_sites:

    Returns:

    """
    ref_soap_vec = ref_data['site_data'][site_index]['soap_vec']

    def similarity(random_site_data):
        return np.abs(1 - np.dot(random_site_data, ref_soap_vec) / np.dot(ref_soap_vec, ref_soap_vec))

    all_sites_with_sim = [(isite, similarity(isite['soap_vec']))
                          for isite in all_random_sites]
    all_sites_with_sim.sort(key=lambda x: x[1])

    matched_res = []
    for itr, (site_info, proj) in enumerate(all_sites_with_sim[:3]):
        mol = Molecule.from_sites([Site.from_dict(isite)
                                   for isite in site_info['local_graph']['sites']])
        mg = get_m_graph_from_mol(mol)
        scene = mg.get_scene()
        scene.name = f"matched-site-{itr}"
        matched_res.append(site_info["task_id"] + "   " + f"{proj:0.4f}")
        matched_res.append(Simple3DScene(
            sceneSize=210,
            inletSize=150,
            inletPadding=0,
            axisView='SW',
            data=scene
        ))
    return matched_res
コード例 #18
0
 def __init__(
     self,
     start_monomer,
     s_head,
     s_tail,
     monomer,
     head,
     tail,
     end_monomer,
     e_head,
     e_tail,
     n_units,
     link_distance=1.0,
     linear_chain=False,
 ):
     """
     Args:
         start_monomer (Molecule): Starting molecule
         s_head (int): starting atom index of the start_monomer molecule
         s_tail (int): tail atom index of the start_monomer
         monomer (Molecule): The monomer
         head (int): index of the atom in the monomer that forms the head
         tail (int): tail atom index. monomers will be connected from
             tail to head
         end_monomer (Molecule): Terminal molecule
         e_head (int): starting atom index of the end_monomer molecule
         e_tail (int): tail atom index of the end_monomer
         n_units (int): number of monomer units excluding the start and
             terminal molecules
         link_distance (float): distance between consecutive monomers
         linear_chain (bool): linear or random walk polymer chain
     """
     self.start = s_head
     self.end = s_tail
     self.monomer = monomer
     self.n_units = n_units
     self.link_distance = link_distance
     self.linear_chain = linear_chain
     # translate monomers so that head atom is at the origin
     start_monomer.translate_sites(range(len(start_monomer)),
                                   -monomer.cart_coords[s_head])
     monomer.translate_sites(range(len(monomer)),
                             -monomer.cart_coords[head])
     end_monomer.translate_sites(range(len(end_monomer)),
                                 -monomer.cart_coords[e_head])
     self.mon_vector = monomer.cart_coords[tail] - monomer.cart_coords[head]
     self.moves = {
         1: [1, 0, 0],
         2: [0, 1, 0],
         3: [0, 0, 1],
         4: [-1, 0, 0],
         5: [0, -1, 0],
         6: [0, 0, -1],
     }
     self.prev_move = 1
     # places the start monomer at the beginning of the chain
     self.molecule = start_monomer.copy()
     self.length = 1
     # create the chain
     self._create(self.monomer, self.mon_vector)
     # terminate the chain with the end_monomer
     self.n_units += 1
     end_mon_vector = end_monomer.cart_coords[
         e_tail] - end_monomer.cart_coords[e_head]
     self._create(end_monomer, end_mon_vector)
     self.molecule = Molecule.from_sites(self.molecule.sites)
コード例 #19
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])
コード例 #20
0
    def gen_input(self,
                  step_size,
                  nrings,
                  maxnbq,
                  height=1.7,
                  normaldirection=0,
                  charge=None,
                  spin_multiplicity=None,
                  title=None,
                  functional='HF',
                  basis_set='6-31G(d)',
                  route_parameters=None,
                  input_parameters=None,
                  link0_parameters=None,
                  dieze_tag='#P',
                  gen_basis=None):
        """
        this will return two lists of gauss input string, xticks, xnumbers, pt_idx(ring idx) for plotting

        pts are cart coords for bqs

        return None if failed

        one problem is if the number of ghost atoms cannot be too large, so the param maxnbq is introduced as
        the max number of ghost atoms that is allowed to show in one input file
        for other param docs see nics_line_scan_path and pymatgen.io.gassian
        """
        pts, pt_idx, xnumbers, xticks = self.nics_line_scan_path(
            step_size, nrings, height, normaldirection)
        sigma_mol_msites = self.nics_sigma_structure(normal_idx=1 -
                                                     normaldirection)
        sigma_pmgmol = Molecule.from_sites(sigma_mol_msites)
        total_pmgmol = self.omol.pmgmol
        chunksize = maxnbq

        total_ginobj = GaussianInput(total_pmgmol, charge, spin_multiplicity,
                                     title, functional, basis_set,
                                     route_parameters, input_parameters,
                                     link0_parameters, dieze_tag, gen_basis)
        sigma_ginobj = GaussianInput(sigma_pmgmol, charge, spin_multiplicity,
                                     title, functional, basis_set,
                                     route_parameters, input_parameters,
                                     link0_parameters, dieze_tag, gen_basis)

        total_outs_list = []
        sigma_outs_list = []
        if len(pts) > maxnbq:
            pts_sep_list = [
                pts[i * chunksize:(i + 1) * chunksize]
                for i in range((len(pts) + chunksize - 1) // chunksize)
            ]
            for idx in range(len(pts_sep_list)):
                total_outs = total_ginobj.to_string(cart_coords=True)
                total_outs = self.add_bqlines(total_outs, pts_sep_list[idx])
                sigma_outs = sigma_ginobj.to_string(cart_coords=True)
                sigma_outs = self.add_bqlines(sigma_outs, pts_sep_list[idx])

                total_outs_list.append(total_outs)
                sigma_outs_list.append(sigma_outs)
        else:  # is this redundant?
            total_outs = total_ginobj.to_string(cart_coords=True)
            total_outs = self.add_bqlines(total_outs, pts)
            sigma_outs = sigma_ginobj.to_string(cart_coords=True)
            sigma_outs = self.add_bqlines(sigma_outs, pts)
            total_outs_list.append(total_outs)
            sigma_outs_list.append(sigma_outs)
        return sigma_outs_list, total_outs_list, xticks, xnumbers, pt_idx, pts
コード例 #21
0
 def dimerjob_from_two_molecules(cls, pmgmol1, pmgmol2, jobname='dimer'):
     dimerpmgmol = Molecule.from_sites(pmgmol1.sites + pmgmol2.sites)
     return cls(jobname, dimerpmgmol, isdimer=True, mol_A=pmgmol1, mol_D=pmgmol2)
コード例 #22
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])
コード例 #23
0
ファイル: pbc.py プロジェクト: caer200/ocelot_api
    def unwrap(pstructure: Structure):
        """
        unwrap the structure, extract isolated mols

        this will modify psites *in-place*, properties will be inherited and a new property
        'imol' will be written
        psite with imol=x is an element of both mols[x] and unwrap_pblock_list[x]

        this method is not supposed to modify siteid!

        :param pstructure: periodic structure obj from pymatgen
        :return: mols, unwrap_str_sorted, unwrap_pblock_list
        """

        psites = pstructure.sites
        cutoff_matrix = np.zeros((len(psites), len(psites)))
        for i in range(len(psites)):
            for j in range(i + 1, len(psites)):
                cutoff = AtomicRadius(psites[i]) + AtomicRadius(psites[j])
                cutoff *= 1.3
                cutoff_matrix[i][j] = cutoff
                cutoff_matrix[j][i] = cutoff

        if all('iasym' in s.properties for s in psites):
            sameiasym = True
            warnings.warn('if a percolating step involves hydrogens, only percolate to sites with the same iasym')
        else:
            sameiasym = False

        pindices = range(len(psites))
        visited = []
        block_list = []
        # unwrap = []
        unwrap_block_list = []
        unwrap_pblock_list = []
        while len(visited) != len(psites):
            # initialization
            unvisited = [idx for idx in pindices if idx not in visited]
            ini_idx = unvisited[0]
            block = [ini_idx]
            # unwrap.append(psites[ini_idx])
            unwrap_block = [Site(psites[ini_idx].species_string, psites[ini_idx].coords,
                                 properties=deepcopy(psites[ini_idx].properties))]
            unwrap_pblock = [psites[ini_idx]]
            pointer = 0
            while pointer != len(block):
                outside = [idx for idx in pindices if idx not in block and idx not in visited]
                for i in outside:
                    si = psites[i]
                    sj = psites[block[pointer]]
                    if sameiasym and (si.species_string == 'H' or sj.species_string == 'H'):
                        if si.properties['iasym'] != sj.properties['iasym']:
                            continue
                    distance, fctrans = PBCparser.get_dist_and_trans(pstructure.lattice,
                                                                     psites[block[pointer]].frac_coords,
                                                                     psites[i].frac_coords, )
                    fctrans = np.rint(fctrans)

                    cutoff = cutoff_matrix[block[pointer]][i]
                    if distance < cutoff:
                        block.append(i)
                        psites[i]._frac_coords += fctrans
                        # psites[i] = PeriodicSite(psites[i].species_string, psites[i].frac_coords + fctrans,
                        #                          pstructure.lattice, properties=deepcopy(psites[i].properties))
                        unwrap_block.append(
                            # Site(psites[i].species_string, psites[i].coords, properties=deepcopy(psites[i].properties))
                            Site(psites[i].species_string, psites[i].coords, properties=psites[i].properties)
                        )
                        unwrap_pblock.append(psites[i])
                visited.append(block[pointer])
                pointer += 1
            unwrap_block_list.append(unwrap_block)
            unwrap_pblock_list.append(unwrap_pblock)
            block_list.append(block)

        unwrap = []
        for i in range(len(unwrap_block_list)):
            for j in range(len(unwrap_block_list[i])):
                unwrap_block_list[i][j].properties['imol'] = i
                unwrap_pblock_list[i][j].properties['imol'] = i
                unwrap.append(unwrap_pblock_list[i][j])

        mols = [Molecule.from_sites(sites) for sites in unwrap_block_list]

        # unwrap_structure = Structure.from_sites(sorted(unwrap, key=lambda x: x.species_string))
        unwrap_structure = Structure.from_sites(unwrap, to_unit_cell=False)
        return mols, unwrap_structure, unwrap_pblock_list
コード例 #24
0
ファイル: utils.py プロジェクト: ajr15/Torina
def to_pymatgen_Molecule(mol):
    sites = []
    for atom, coord in zip(mol.atoms, mol.coords):
        sites.append(Site(atom, coord))
    return Molecule.from_sites(sites)
コード例 #25
0
ファイル: legend.py プロジェクト: munrojm/crystaltoolkit
    def __init__(
        self,
        site_collection: Union[SiteCollection, Site],
        color_scheme: str = "Jmol",
        radius_scheme: str = "uniform",
        cmap: str = "coolwarm",
        cmap_range: Optional[Tuple[float, float]] = None,
    ):
        """
        Create a legend for a given SiteCollection to choose how to
        display colors and radii for the given sites and the species
        on those sites.

        If a site has a "display_color" or "display_radius" site
        property defined, this can be used to manually override the
        displayed colors and radii respectively.

        Args:
            site_collection: SiteCollection or, for convenience, a
            single site can be provided and this will be converted
            into a SiteCollection
            color_scheme: choose how to color-code species, one of
            "Jmol", "VESTA", "accessible" or a scalar site property
            (e.g. magnetic moment) or a categorical/string site
            property (e.g. Wyckoff label)
            radius_scheme: choose the radius for a species, one of
            "atomic", "specified_or_average_ionic", "covalent",
            "van_der_waals", "atomic_calculated", "uniform"
            cmap: only used if color_mode is set to a scalar site
            property, defines the matplotlib color map to use, by
            default is blue-white-red for negative to postive values
            cmap_range: only used if color_mode is set to a scalar site
            property, defines the minimum and maximum values of the
            color scape
        """

        if isinstance(site_collection, Site):
            site_collection = Molecule.from_sites([site_collection])

        site_prop_types = self.analyze_site_props(site_collection)

        self.allowed_color_schemes = (
            ["VESTA", "Jmol", "accessible"]
            + site_prop_types.get("scalar", [])
            + site_prop_types.get("categorical", [])
        )

        self.allowed_radius_schemes = (
            "atomic",
            "specified_or_average_ionic",
            "covalent",
            "van_der_waals",
            "atomic_calculated",
            "uniform",
        )

        if color_scheme not in self.allowed_color_schemes:
            warnings.warn(
                f"Color scheme {color_scheme} not available, "
                f"falling back to {self.default_color_scheme}."
            )
            color_scheme = self.default_color_scheme

        # if color-coding by a scalar site property, determine minimum and
        # maximum values for color scheme, will default to be symmetric
        # about zero
        if color_scheme in site_prop_types.get("scalar", []) and not cmap_range:
            props = np.array(
                [
                    p
                    for p in site_collection.site_properties[color_scheme]
                    if p is not None
                ]
            )
            prop_max = max([abs(min(props)), max(props)])
            prop_min = -prop_max
            cmap_range = (prop_min, prop_max)

        el_colors = EL_COLORS.copy()
        el_colors.update(
            self.generate_accessible_color_scheme_on_the_fly(site_collection)
        )

        self.categorical_colors = self.generate_categorical_color_scheme_on_the_fly(
            site_collection, site_prop_types
        )

        self.el_colors = el_colors
        self.site_prop_types = site_prop_types
        self.site_collection = site_collection
        self.color_scheme = color_scheme
        self.radius_scheme = radius_scheme
        self.cmap = cmap
        self.cmap_range = cmap_range