def test_filter(self): fil = RemoveExistingFilter(self._exisiting_structures) transmuter = StandardTransmuter.from_structures(self._struct_list) transmuter.apply_filter(fil) self.assertEqual(len(transmuter.transformed_structures), 1) self.assertTrue( self._sm.fit(self._struct_list[-1], transmuter.transformed_structures[-1].final_structure))
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