class SubstitutionPredictorTransformation(AbstractTransformation): """ This transformation takes a structure and uses the structure prediction module to find likely site substitutions. """ def __init__(self, threshold=1e-2, **kwargs): """ Args: kwargs: args for SubstitutionProbability class lambda_table, alpha """ self._kwargs = kwargs self._threshold = threshold self._substitutor = SubstitutionPredictor(threshold=threshold, **kwargs) def apply_transformation(self, structure, return_ranked_list=False): if not return_ranked_list: raise ValueError("SubstitutionPredictorTransformation doesn't" " support returning 1 structure") preds = self._substitutor.composition_prediction( structure.composition, to_this_composition=False) preds.sort(key=lambda x: x['probability'], reverse=True) outputs = [] for pred in preds: st = SubstitutionTransformation(pred['substitutions']) output = {'structure': st.apply_transformation(structure), 'probability': pred['probability'], 'threshold': self._threshold, 'substitutions': {}} #dictionary keys have to be converted to strings for JSON for key, value in pred['substitutions'].items(): output['substitutions'][str(key)] = str(value) outputs.append(output) return outputs def __str__(self): return "SubstitutionPredictorTransformation" def __repr__(self): return self.__str__() @property def inverse(self): return None @property def is_one_to_many(self): return True @property def to_dict(self): d = {"name": self.__class__.__name__, "version": __version__, "init_args": self._kwargs, "@module": self.__class__.__module__, "@class": self.__class__.__name__} d["init_args"]["threshold"] = self._threshold return d
def test_prediction(self): sp = SubstitutionPredictor(threshold = 8e-3) result = sp.list_prediction(['Na+', 'Cl-'], to_this_composition = True)[5] cprob = sp.p.cond_prob_list(result['substitutions'].keys(), result['substitutions'].values()) self.assertAlmostEqual(result['probability'], cprob) self.assertEqual(set(result['substitutions'].values()), set(['Na+', 'Cl-'])) result = sp.list_prediction(['Na+', 'Cl-'], to_this_composition = False)[5] cprob = sp.p.cond_prob_list(result['substitutions'].keys(), result['substitutions'].values()) self.assertAlmostEqual(result['probability'], cprob) self.assertNotEqual(set(result['substitutions'].values()), set(['Na+', 'Cl-'])) c = Composition({'Ag2+' : 1, 'Cl-' : 2}) result = sp.composition_prediction(c, to_this_composition = True)[2] self.assertEqual(set(result['substitutions'].values()), set(c.elements)) result = sp.composition_prediction(c, to_this_composition = False)[2] self.assertEqual(set(result['substitutions'].keys()), set(c.elements))
class SubstitutionPredictorTransformation(AbstractTransformation): """ This transformation takes a structure and uses the structure prediction module to find likely site substitutions. Args: threshold: Threshold for substitution. **kwargs: Args for SubstitutionProbability class lambda_table, alpha """ def __init__(self, threshold=1e-2, **kwargs): self.kwargs = kwargs self.threshold = threshold self._substitutor = SubstitutionPredictor(threshold=threshold, **kwargs) def apply_transformation(self, structure, return_ranked_list=False): if not return_ranked_list: raise ValueError("SubstitutionPredictorTransformation doesn't" " support returning 1 structure") preds = self._substitutor.composition_prediction( structure.composition, to_this_composition=False) preds.sort(key=lambda x: x['probability'], reverse=True) outputs = [] for pred in preds: st = SubstitutionTransformation(pred['substitutions']) output = { 'structure': st.apply_transformation(structure), 'probability': pred['probability'], 'threshold': self.threshold, 'substitutions': {} } # dictionary keys have to be converted to strings for JSON for key, value in pred['substitutions'].items(): output['substitutions'][str(key)] = str(value) outputs.append(output) return outputs def __str__(self): return "SubstitutionPredictorTransformation" def __repr__(self): return self.__str__() @property def inverse(self): return None @property def is_one_to_many(self): return True