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
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.')
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.')
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())
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())