def run_task(self, fw_spec):
        db = SPStructuresMongoAdapter.auto_load()
        tstructs = []
        species = fw_spec['species']
        t = fw_spec['threshold']
        for p in SubstitutionPredictor(threshold=t).list_prediction(species):
            subs = p['substitutions']
            if len(set(subs.values())) < len(species):
                continue
            st = SubstitutionTransformation(subs)
            target = map(str, subs.keys())
            for snl in db.get_snls(target):
                ts = TransformedStructure.from_snl(snl)
                ts.append_transformation(st)
                if ts.final_structure.charge == 0:
                    tstructs.append(ts)

        transmuter = StandardTransmuter(tstructs)
        f = RemoveDuplicatesFilter(structure_matcher=StructureMatcher(
            comparator=ElementComparator(), primitive_cell=False))
        transmuter.apply_filter(f)
        results = []
        for ts in transmuter.transformed_structures:
            results.append(ts.to_snl([]).to_dict)
        submissions = SPSubmissionsMongoAdapter.auto_load()
        submissions.insert_results(fw_spec['submission_id'], results)
示例#2
0
 def test_filter(self):
     transmuter = StandardTransmuter.from_structures(self._struct_list)
     fil = RemoveDuplicatesFilter()
     transmuter.apply_filter(fil)
     out = self._sm.group_structures(transmuter.transformed_structures)
     self.assertEqual(
         self._sm.find_indexes(transmuter.transformed_structures, out),
         [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
示例#3
0
    def pred_from_structures(self,
                             target_species,
                             structures_list,
                             remove_duplicates=True,
                             remove_existing=False):
        """
        performs a structure prediction targeting compounds containing all of
        the target_species, based on a list of structure (those structures
        can for instance come from a database like the ICSD). It will return
        all the structures formed by ionic substitutions with a probability
        higher than the threshold

        Notes:
        If the default probability model is used, input structures must
        be oxidation state decorated. See AutoOxiStateDecorationTransformation

        This method does not change the number of species in a structure. i.e
        if the number of target species is 3, only input structures containing
        3 species will be considered.

        Args:
            target_species:
                a list of species with oxidation states
                e.g., [Specie('Li',1),Specie('Ni',2), Specie('O',-2)]

            structures_list:
                a list of dictionnary of the form {'structure':Structure object
                ,'id':some id where it comes from}
                the id can for instance refer to an ICSD id.

            remove_duplicates:
                if True, the duplicates in the predicted structures will
                be removed

            remove_existing:
                if True, the predicted structures that already exist in the
                structures_list will be removed

        Returns:
            a list of TransformedStructure objects.
        """
        target_species = get_el_sp(target_species)
        result = []
        transmuter = StandardTransmuter([])
        if len(list(set(target_species) & set(self.get_allowed_species()))) \
                != len(target_species):
            raise ValueError("the species in target_species are not allowed " +
                             "for the probability model you are using")

        for permut in itertools.permutations(target_species):
            for s in structures_list:
                # check if: species are in the domain,
                # and the probability of subst. is above the threshold
                els = s['structure'].composition.elements
                if len(els) == len(permut) and len(list(set(els) & set(self.get_allowed_species()))) == \
                        len(els) and self._sp.cond_prob_list(permut, els) > self._threshold:

                    clean_subst = {
                        els[i]: permut[i]
                        for i in range(0, len(els)) if els[i] != permut[i]
                    }

                    if len(clean_subst) == 0:
                        continue

                    transf = SubstitutionTransformation(clean_subst)

                    if Substitutor._is_charge_balanced(
                            transf.apply_transformation(s['structure'])):
                        ts = TransformedStructure(s['structure'], [transf],
                                                  history=[{
                                                      "source": s['id']
                                                  }],
                                                  other_parameters={
                                                      'type':
                                                      'structure_prediction',
                                                      'proba':
                                                      self._sp.cond_prob_list(
                                                          permut, els)
                                                  })
                        result.append(ts)
                        transmuter.append_transformed_structures([ts])

        if remove_duplicates:
            transmuter.apply_filter(
                RemoveDuplicatesFilter(symprec=self._symprec))
        if remove_existing:
            # Make the list of structures from structures_list that corresponds to the
            # target species
            chemsys = list(set([sp.symbol for sp in target_species]))
            structures_list_target = [
                st['structure'] for st in structures_list
                if Substitutor._is_from_chemical_system(
                    chemsys, st['structure'])
            ]
            transmuter.apply_filter(
                RemoveExistingFilter(structures_list_target,
                                     symprec=self._symprec))
        return transmuter.transformed_structures
示例#4
0
 def test_to_from_dict(self):
     fil = RemoveDuplicatesFilter()
     d = fil.as_dict()
     self.assertIsInstance(RemoveDuplicatesFilter().from_dict(d),
                           RemoveDuplicatesFilter)
示例#5
0
 def test_filter(self):
     transmuter = StandardTransmuter.from_structures(self._struct_list)
     fil = RemoveDuplicatesFilter()
     transmuter.apply_filter(fil)
     self.assertEqual(len(transmuter.transformed_structures), 11)
示例#6
0
 def test_to_from_dict(self):
     fil = RemoveDuplicatesFilter()
     d = fil.as_dict()
     self.assertIsInstance(RemoveDuplicatesFilter().from_dict(d),
                           RemoveDuplicatesFilter)
示例#7
0
    def pred_from_structures(self, target_species, structures_list,
                             remove_duplicates=True):
        """
        performs a structure prediction targeting compounds containing the
        target_species and based on a list of structure (those structures
        can for instance come from a database like the ICSD). It will return
        all the structures formed by ionic substitutions with a probability
        higher than the threshold

        Args:
            target_species:
                a list of species with oxidation states
                e.g., [Specie('Li',1),Specie('Ni',2), Specie('O',-2)]

            structures_list:
                a list of dictionnary of the form {'structure':Structure object
                ,'id':some id where it comes from}
                the id can for instance refer to an ICSD id

        Returns:
            a list of TransformedStructure objects.
        """
        result = []
        transmuter = StandardTransmuter([])
        if len(list(set(target_species) & set(self.get_allowed_species()))) \
                != len(target_species):
            raise ValueError("the species in target_species are not allowed"
                              + "for the probability model you are using")

        for permut in itertools.permutations(target_species):
            for s in structures_list:
                #check if: species are in the domain,
                #and the probability of subst. is above the threshold
                els = s['structure'].composition.elements
                if len(els) == len(permut) and \
                    len(list(set(els) & set(self.get_allowed_species()))) == \
                        len(els) and self._sp.cond_prob_list(permut, els) > \
                        self._threshold:

                    clean_subst = {els[i]: permut[i]
                                   for i in xrange(0, len(els))
                                   if els[i] != permut[i]}

                    if len(clean_subst) == 0:
                        continue

                    transf = SubstitutionTransformation(clean_subst)

                    if Substitutor._is_charge_balanced(
                            transf.apply_transformation(s['structure'])):
                        ts = TransformedStructure(
                            s['structure'], [transf], history=[s['id']],
                            other_parameters={
                                'type': 'structure_prediction',
                                'proba': self._sp.cond_prob_list(permut, els)}
                        )
                        result.append(ts)
                        transmuter.append_transformed_structures([ts])

        if remove_duplicates:
            transmuter.apply_filter(RemoveDuplicatesFilter(
                symprec=self._symprec))
        return transmuter.transformed_structures
示例#8
0
    def make_all_substituted_configurations(self):
        substituted_count = 0
        while substituted_count < self.number_of_substitutions:
            self.substituted_sites = []
            unique = 0
            _list_holder = copy.deepcopy(self.supercells)
            self.supercells = []

            if substituted_count < 2:
                for k, supercell in enumerate(_list_holder):
                    for extra_doped_supercell in self.make_one_substitution(
                            supercell):
                        self.supercells.append(extra_doped_supercell)

                        #if self.write_vasp:
                        #    dir_name = "SC_" + str(self.sc_size[0]) + "_" + str(self.sc_size[1]) + "_" + str(
                        #        self.sc_size[2]) + '_' + self.prefix + '_' + str(substituted_count + 1) + "_str_" + str(
                        #        len(self.supercells))
                        #    self._write_vasp_files(extra_doped_supercell, dir_name=dir_name)
                        #    unique += 1
            else:
                import random

                filter = RemoveDuplicatesFilter(symprec=1e-5)

                extra_doped_supercells = []

                doped_sites = []

                if len(_list_holder) > self.throttle:
                    _list_holder = random.choices(_list_holder,
                                                  k=self.throttle)

                for counter, supercell in enumerate(_list_holder):
                    extra_doped_supercells += self.make_one_substitution(
                        supercell)

                    for s in extra_doped_supercells:
                        __site_no = []
                        for no, site in enumerate(s.__dict__['_sites']):
                            if site.__dict__["_species"] == Composition(
                                    self.atom_substitute_to):
                                __site_no.append(no)
                        __site_no = list(sorted(__site_no))
                        if __site_no not in doped_sites:
                            doped_sites.append(__site_no)
                            self.supercells.append(s)
                    print(len(self.supercells))

            if self.max_structures is not None:
                if len(self.supercells) > self.max_structures:
                    import random
                    self.supercells = random.sample(self.supercells,
                                                    self.max_structures)

            if self.write_vasp:
                for i, cell in enumerate(self.supercells):
                    dir_name = "SC_" + str(self.sc_size[0]) + "_" + str(
                        self.sc_size[1]) + "_" + str(
                            self.sc_size[2]) + '_' + self.prefix + '_' + str(
                                substituted_count + 1) + "_str_" + str(i)
                    self._write_vasp_files(cell, dir_name=dir_name)
                    unique += 1

            print("number of dopants:" + str(substituted_count + 1) +
                  ' number of configurations:' + str(unique))

            substituted_count += 1

        #self.supercells = [map_pymatgen_IStructure_to_crystal(s) for s in self.supercells]

        return self.supercells