/usr/share/pyshared/cogent/evolve/predicate.py is in python-cogent 1.5.1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | #!/usr/bin/env python
"""
Matching motifs: MotifChange("a", "g")
Boolean logic: Any, All, Not (or &, |, ~)
also:
anypredicate.aliased('shortname')
UserPredicate(f)
"""
import warnings
import numpy
__author__ = "Peter Maxwell"
__copyright__ = "Copyright 2007-2011, The Cogent Project"
__credits__ = ["Peter Maxwell", "Gavin Huttley"]
__license__ = "GPL"
__version__ = "1.5.1"
__maintainer__ = "Peter Maxwell"
__email__ = "pm67nz@gmail.com"
__status__ = "Production"
class _CallablePredicate(object):
# A predicate in the context of a particular model
def __init__(self, pred, model):
self.model = model
self.alphabet = model.getAlphabet()
self.name = repr(pred)
self.f = pred.interpret(model)
self.__doc__ = pred.__doc__
def __call__(self, x, y):
return self.f(x, y)
def __repr__(self):
return self.name
def asciiArt(self):
l = len(self.alphabet.getGapMotif())
rows = []
for i in range(l):
row = [a[i] for a in list(self.alphabet)]
rows.append(' '*(l+1) + ' '.join(row))
for y in self.alphabet:
row = []
for x in self.alphabet:
if not self.model.isinstantanious(x, y):
c = ' '
elif self(x,y):
c = '*'
else:
c = '-'
row.append(c)
rows.append(' '.join([y] + row))
return '\n'.join(rows)
class predicate(object):
def __and__(self, other):
return All(self, other)
def __or__(self, other):
return Any(self, other)
def __invert__(self):
return Not(self)
def __nonzero__(self):
warnings.warn('alphabet predicate used as truth value. Use only binary operators: &, | and ~', stacklevel=2)
return True
def __eq__(self, other):
warnings.warn('Warning: alphabet pair predicate used as value. Use parentheses')
return self is other
def aliased(self, new_name):
n = PredicateAlias(new_name, self)
n.__doc__ = self.__doc__ or repr(self)
return n
def makeModelPredicate(self, model):
return _CallablePredicate(self, model)
class PredicateAlias(predicate):
def __init__(self, name, subpredicate):
self.name = name
self.subpredicate = subpredicate
def __repr__(self):
return self.name
def interpret(self, model):
subpred = self.subpredicate.interpret(model)
return subpred
class _UnaryPredicate(predicate):
def __init__(self, subpredicate):
assert isinstance(subpredicate, predicate), subpredicate
self.subpredicate = subpredicate
self.__doc__ = repr(self)
def __repr__(self):
if hasattr(self, '_op_repr'):
return "%s(%s)" % (self._op_repr, self.subpredicate)
else:
return "%s(%s)" % (self.__class__.__name__, self.subpredicate)
class _GenericPredicate(predicate):
def __init__(self, *subpredicates):
for p in subpredicates:
assert isinstance(p, predicate), p
self.subpredicates = subpredicates
self.__doc__ = repr(self)
def __repr__(self):
if hasattr(self, '_op_repr'):
return '(%s)' % (' %s ' % self._op_repr).join([repr(p) for p in self.subpredicates])
else:
return '%s(%s)' % (self.__class__.__name__, ','.join(['(%s)' % repr(p) for p in self.subpredicates]))
# Boolean logic on motif pair predicates
class Not(_UnaryPredicate):
_op_repr = '~'
def interpret(self, model):
subpred = self.subpredicate.interpret(model)
def call(*args):
return not subpred(*args)
call.__doc__ = repr(self)
return call
class All(_GenericPredicate):
_op_repr = '&'
def interpret(self, model):
subpreds = [p.interpret(model) for p in self.subpredicates]
def call(*args):
for subpredicate in subpreds:
if not subpredicate(*args):
return False
return True
call.__doc__ = repr(self)
return call
class Any(_GenericPredicate):
_op_repr = '|'
def interpret(self, model):
subpreds = [p.interpret(model) for p in self.subpredicates]
def call(*args):
for subpredicate in subpreds:
if subpredicate(*args):
return True
return False
call.__doc__ = repr(self)
return call
class ModelSays(predicate):
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
def interpret(self, model):
return model.getPredefinedPredicate(self.name)
class DirectedMotifChange(predicate):
def __init__(self, from_motif, to_motif,
diff_at = None):
self.from_motif = from_motif
self.motiflen = len(from_motif)
self.to_motif = to_motif
self.diff_at = diff_at
def __repr__(self):
if self.diff_at is not None:
diff = '[%d]' % self.diff_at
else:
diff = ''
return '%s>%s%s' % (self.from_motif, self.to_motif, diff)
def testMotif(self, motifs, query):
"""positions where motif pattern is found in query"""
positions = set()
for offset in range(len(query)-self.motiflen+1):
for (q,ms) in zip(query[offset: offset+self.motiflen], motifs):
if q not in ms:
break
else:
positions.add(offset)
return positions
def testMotifs(self, from_motifs, to_motifs, x, y):
""""positions where both motifs patterns are found"""
pre = self.testMotif(from_motifs, x)
post = self.testMotif(to_motifs, y)
return pre & post
def interpret(self, model):
"""Make a callable function which implements this predicate
specificly for 'alphabet'"""
# may be looking for a 2nt pattern in a 3nt alphabet, but not
# 3nt pattern in dinucleotide alphabet.
alphabet = model.getAlphabet()
if alphabet.getMotifLen() < self.motiflen:
raise ValueError("Alphabet motifs (%s) too short for %s (%s)" %
(alphabet.getMotifLen(), repr(self), self.motiflen))
resolve = model.MolType.Ambiguities.__getitem__
from_motifs = [resolve(m) for m in self.from_motif]
to_motifs = [resolve(m) for m in self.to_motif]
def call(x, y):
diffs = [X!=Y for (X,Y) in zip(x, y)]
matches = []
for posn in self.testMotifs(from_motifs, to_motifs, x, y):
diff = list(numpy.nonzero(diffs[posn:posn+self.motiflen])[0])
if diff and self.diff_at is None or diff == [self.diff_at]:
matches.append(posn)
return len(matches) == 1
call.__doc__ = repr(self)
return call
class UndirectedMotifChange(DirectedMotifChange):
def __repr__(self):
if self.diff_at is not None:
diff = '[%d]' % self.diff_at
else:
diff = ''
return '%s/%s%s' % (self.from_motif, self.to_motif, diff)
def testMotifs(self, from_motifs, to_motifs, x, y):
preF = self.testMotif(from_motifs, x)
postF = self.testMotif(to_motifs, y)
preR = self.testMotif(from_motifs, y)
postR = self.testMotif(to_motifs, x)
return (preF & postF) | (preR & postR)
def MotifChange(x, y=None, forward_only=False, diff_at=None):
if y is None:
y = ''
for i in range(len(x)):
if i == diff_at or diff_at is None:
y += '?'
else:
y += x[i]
if forward_only:
return DirectedMotifChange(x, y, diff_at=diff_at)
else:
return UndirectedMotifChange(x, y, diff_at=diff_at)
class UserPredicate(predicate):
def __init__(self, f):
self.f = f
def __repr__(self):
return 'UserPredicate(%s)' % (
getattr(self.f, '__name__', None) or repr(self.f))
def interpret(self, model):
return self.f
silent = ModelSays('silent')
replacement = ModelSays('replacement')
def parse(rule):
if ':' in rule:
(label, rule) = rule.split(':')
else:
label = None
if '@' in rule:
(rule, diff_at) = rule.split('@')
diff_at = int(diff_at)
else:
diff_at = None
if '>' in rule or '/' in rule:
forward_only = '>' in rule
rule = rule.replace('>', '/')
(x,y) = rule.split('/')
if not y: y = None
pred = MotifChange(x, y, forward_only, diff_at)
else:
pred = ModelSays(rule)
if label:
pred = pred.aliased(label)
return pred
|