コード例 #1
0
    def substitution_structures(self, mp_struct, mpid):
        
        ''' Predicts substituted compounds from a given Materials Project structure (mp_struct) and ID (mpid) '''
        ''' flat_predictions: a list of predicted structures as pymatgen.alchemy.materials.TransformedStructure objects '''
        
        auto_oxi = AutoOxiStateDecorationTransformation() #initialize the automatic oxidation state transformation
        structures = []
        
        try:
            oxi_struct = auto_oxi.apply_transformation(mp_struct) # get oxidized reference structure
            subs = SubstitutionPredictor().composition_prediction(oxi_struct.composition) # from a given charge-balanced
            trial_subs = [list(sub['substitutions'].keys()) for sub in subs] # returns the potential substitutions
            sbr = Substitutor()
            
            for sub in trial_subs:
                run = True
                
                for specie in sub:
                    if str(specie.element) not in self.elements:
                        run = False

                if run == True:
                    structs = sbr.pred_from_structures(sub, [{'structure':oxi_struct, 'id':mpid}])
                    structures.append(structs)
           
        except:
            pass
        
        flat_predictions = [structure for substitution in structures for structure in substitution]
        
        return flat_predictions
コード例 #2
0
def predict_structure(species, struc_list, check_dir=False, threshold=0.00001):
    """ Predicted structures for set of pymatgen species using the Pymatgen structure predictor
    and save as cif file.
    TODO: This will be superceded by our own implementation of the structure prediction algorithm
    in future versions of SMACT.
    Args:
        species (list): Pymatgen Species for which structure should be predicted.
        struc_list (list): Pymatgen Structure objects to consider as parent structures in the
        substitution algorithm.
        check_dir (bool): check if directory already exists and only carry out
        prediction and write new files if it doesn't.
        threshold (float): Log-probability threshold for the Pymatgen structure predictor.
    Returns:
        Saves cif files of possible structures in new directory along with a summary .txt file
        containing info including probabilities.
    """
    sub = Substitutor(threshold=0.00001)
    print('{}  ........'.format(species))
    dirname = ''.join([str(i) for i in species])
    path_exists = True if os.path.exists(
        './SP_results/{0}'.format(dirname)) else False

    if (check_dir and path_exists):
        print('Already exists')
    else:
        print('{} not already there'.format(dirname))
        suggested_strucs = sub.pred_from_structures(target_species=species,
                                                    structures_list=struc_list,
                                                    remove_existing=False,
                                                    remove_duplicates=True)
        suggested_strucs = sorted(suggested_strucs,
                                  key=lambda k: k.other_parameters['proba'],
                                  reverse=True)

        # Save the structures as cifs
        if not path_exists:
            os.makedirs('./SP_results/{0}'.format(dirname))

        for i, d in enumerate(suggested_strucs):
            cw = CifWriter(d.final_structure)
            cw.write_file("SP_results/{0}/{1}_BasedOn_{2}.cif".format(
                dirname, i, d.history[0]['source']))

        # Save the summary as a text file
        with open('SP_results/{0}/{0}_summary.txt'.format(dirname), 'w') as f:
            f.write('Formula,  Probability,  Based on,  Substitutions \n')
            for i, struc in enumerate(suggested_strucs):
                f.write(
                    ' {0}, {1:12},   {2:.5f},         {3:9},    {4} \n'.format(
                        i, struc.composition.reduced_formula,
                        struc.other_parameters['proba'],
                        struc.history[0]['source'],
                        re.sub('Specie', '',
                               str(struc.history[1]['species_map']))))
    print('Done.')
コード例 #3
0
class SubstitutorTest(unittest.TestCase):
    def setUp(self):
        self.s = Substitutor(threshold=1e-3,
                             lambda_table=get_table(),
                             alpha=-5.)

    def test_substitutor(self):
        s_list = [Specie('O', -2), Specie('Li', 1)]
        subs = self.s.pred_from_list(s_list)
        self.assertEqual(len(subs), 4, 'incorrect number of substitutions')
        c = Composition({'O2-': 1, 'Li1+': 2})
        subs = self.s.pred_from_comp(c)
        self.assertEqual(len(subs), 4, 'incorrect number of substitutions')

    def test_as_dict(self):
        Substitutor.from_dict(self.s.as_dict())
コード例 #4
0
ファイル: oxidationstates.py プロジェクト: ssthurai/SMACT
def predict_structure(species, struc_list, check_dir=False):
    """ Save cif files of predicted structures for set of pymatgen species.
    Args:
        species (list): pymatgen species to predict structures for
        struc_list (list): pymatgen structures to substitute species into
        check_dir (bool): check if directory already exists and only carry out
        prediction if it doesn't.
    """
    sub = Substitutor(threshold=0.00001)
    print('{}  ........'.format(species))
    dirname = ''.join([str(i) for i in species])
    path_exists = True if os.path.exists(
        './SP_results/{0}'.format(dirname)) else False

    if (check_dir and path_exists):
        print('Already exists')
    else:
        print('{} not already there'.format(dirname))
        suggested_strucs = sub.pred_from_structures(target_species=species,
                                                    structures_list=struc_list,
                                                    remove_existing=False,
                                                    remove_duplicates=True)
        suggested_strucs = sorted(suggested_strucs,
                                  key=lambda k: k.other_parameters['proba'],
                                  reverse=True)

        # Save the structures as cifs
        if not path_exists:
            os.makedirs('./SP_results/{0}'.format(dirname))

        for i, d in enumerate(suggested_strucs):
            cw = CifWriter(d.final_structure)
            cw.write_file("SP_results/{0}/{1}_BasedOn_{2}.cif".format(
                dirname, i, d.history[0]['source']))

        # Save the summary as a text file
        with open('SP_results/{0}/{0}_summary.txt'.format(dirname), 'w') as f:
            f.write('Formula,  Probability,  Based on,  Substitutions \n')
            for i, struc in enumerate(suggested_strucs):
                f.write(
                    ' {0}, {1:12},   {2:.5f},         {3:9},    {4} \n'.format(
                        i, struc.composition.reduced_formula,
                        struc.other_parameters['proba'],
                        struc.history[0]['source'],
                        re.sub('Specie', '',
                               str(struc.history[1]['species_map']))))
    print('Done.')
コード例 #5
0
class SubstitutorTest(PymatgenTest):
    def setUp(self):
        self.s = Substitutor(threshold=1e-3,
                             lambda_table=get_table(),
                             alpha=-5.)

    def test_substitutor(self):
        s_list = [Specie('O', -2), Specie('Li', 1)]
        subs = self.s.pred_from_list(s_list)
        self.assertEqual(len(subs), 4, 'incorrect number of substitutions')
        c = Composition({'O2-': 1, 'Li1+': 2})
        subs = self.s.pred_from_comp(c)
        self.assertEqual(len(subs), 4, 'incorrect number of substitutions')

        structures = [{
            "structure": PymatgenTest.get_structure("Li2O"),
            "id": "pmgtest"
        }]
        subs = self.s.pred_from_structures(["Na+", "O2-"], structures)
        self.assertEqual(subs[0].formula, "Na2 O1")

    def test_as_dict(self):
        Substitutor.from_dict(self.s.as_dict())
コード例 #6
0
ファイル: test_substitutor.py プロジェクト: ExpHP/pymatgen
class SubstitutorTest(PymatgenTest):

    def setUp(self):
        self.s = Substitutor(threshold=1e-3, lambda_table=get_table(),
                             alpha= -5.)

    def test_substitutor(self):
        s_list = [Specie('O', -2), Specie('Li', 1)]
        subs = self.s.pred_from_list(s_list)
        self.assertEqual(len(subs), 4
                         , 'incorrect number of substitutions')
        c = Composition({'O2-': 1, 'Li1+': 2})
        subs = self.s.pred_from_comp(c)
        self.assertEqual(len(subs), 4
                         , 'incorrect number of substitutions')

        structures = [{"structure": PymatgenTest.get_structure("Li2O"),
                       "id": "pmgtest"}]
        subs = self.s.pred_from_structures(["Na+", "O2-"], structures)
        self.assertEqual(subs[0].formula, "Na2 O1")

    def test_as_dict(self):
        Substitutor.from_dict(self.s.as_dict())
コード例 #7
0
def get_Probable_Substitutions(species, elements_to_include, threshold):

    Sub = Substitutor(threshold=threshold)
    subs_dict = {}

    for specie in species:
        subs = Sub.pred_from_list([specie])
        try:
            subs.sort(key=lambda x: x['probability'], reverse=True)
            subs_dict_key = list(subs[0]['substitutions'].keys())[0]
            subs_dict[subs_dict_key] = []

            for i in range(len(subs)):
                if list(subs[i]['substitutions'].values()
                        )[0].symbol in elements_to_include:
                    subs_dict[subs_dict_key].append(
                        list(subs[i]['substitutions'].values())[0])
        except:
            print('No probable substitutions at %s threshold for %s' %
                  (threshold, specie))
            continue

    return subs_dict
コード例 #8
0
 def test_as_dict(self):
     Substitutor.from_dict(self.s.as_dict())
コード例 #9
0
 def setUp(self):
     self.s = Substitutor(threshold=1e-3,
                          lambda_table=get_table(),
                          alpha=-5.)
コード例 #10
0
ファイル: test_substitutor.py プロジェクト: ExpHP/pymatgen
 def test_as_dict(self):
     Substitutor.from_dict(self.s.as_dict())
コード例 #11
0
ファイル: test_substitutor.py プロジェクト: ExpHP/pymatgen
 def setUp(self):
     self.s = Substitutor(threshold=1e-3, lambda_table=get_table(),
                          alpha= -5.)
コード例 #12
0
    def process_item(self, item):
        """
        Finds all predicted structures for given item

        Args:
            item (dict): structure prediction request and relevant oxidation state-labeled structure templates

        Returns:
            (dict, dict): A tuple containing updated request doc and a list of crystal docs to update
        """
        request = item["request"]
        templates = item["templates"]

        self.logger.info(
            f"Labeling oxidation states for {len(templates)} structure templates"
        )

        oxi_labeled_templates = []
        for template in templates:
            struct = Structure.from_dict(template["structure"])
            try:
                oxi_labeled_templates.append({
                    "structure":
                    self.auto_oxi.apply_transformation(struct),
                    "id":
                    template[self.structure_templates.key],
                })
            except:
                continue  # if auto-oxidation fails, try next structure

        self.logger.info(
            f"Successfully labeled oxidation states for {len(oxi_labeled_templates)} structures"
        )
        self.logger.info("Substituting original species into structures")

        predicted_structs = Substitutor(
            threshold=request["threshold"]).pred_from_structures(
                request["original_species"],
                oxi_labeled_templates,
                remove_duplicates=True,
                remove_existing=True,
            )
        predicted_structs.sort(key=lambda s: s.other_parameters["proba"],
                               reverse=True)

        structure_prediction_id = request[self.requests.key]

        crystal_docs = []
        summaries = []

        self.logger.info(
            f"Found {len(predicted_structs)} predicted structures. Generating crystal docs (XRDs, CIFs, etc."
        )

        for number_id, struct in enumerate(predicted_structs):
            crystal = {}
            summary = {}
            xrd_dict = {}

            final_structure = struct.final_structure
            sga = SpacegroupAnalyzer(final_structure, symprec=0.1)

            for rad_source in ["CuKa", "AgKa", "MoKa", "FeKa"]:
                xrdc = XRDCalculator(wavelength=rad_source)
                pattern = xrdc.get_pattern(final_structure,
                                           two_theta_range=None)
                xrd_dict[rad_source] = pattern

            transformed_structure = struct.to_snl(
                f"{request['name']} <{request['email']}>",
                remarks=["Created by MP Structure Predictor"],
            )

            crystal[self.requests.key] = structure_prediction_id
            crystal[self.crystals.key] = number_id
            crystal["probability"] = struct.other_parameters["proba"]
            crystal["transformed_structure"] = transformed_structure
            crystal["xrd"] = xrd_dict
            crystal["space_group_info"] = {
                "symbol": sga.get_space_group_symbol(),
                "number": sga.get_space_group_number(),
                "hall": sga.get_hall(),
                "crystal_system": sga.get_crystal_system(),
            }

            summary[self.crystals.key] = number_id
            summary["probability"] = struct.other_parameters["proba"]
            summary[
                "pretty_formula"] = final_structure.composition.reduced_formula
            summary["nsites"] = len(final_structure)
            summary["space_group"] = sga.get_space_group_symbol()
            summary["cif"] = str(CifWriter(final_structure))

            crystal_docs.append(jsanitize(crystal, strict=True))
            summaries.append(jsanitize(summary, strict=True))

        self.logger.info(
            f"Successfully generated {len(crystal_docs)} crystal docs for request {request['original_species']}"
        )

        request.update({
            "state": "COMPLETE",
            "completed_at": datetime.utcnow(),
            "num_crystals": len(crystal_docs),
            "crystals": summaries,
        })

        return request, crystal_docs