Source code for src.domains.motif_space

import numpy as np
from nifty8 import MultiDomain, DomainTuple
from .hamming_space import HammingSpace
from nifty8.utilities import check_object_identity, frozendict, indent
from ..obj.units import make_unit, Unit
from warnings import warn

def _motif_categories():
    return 'length{}strand','beginning','continuation','end'

def _return_motif_categories(motiflength : int = None):
    if motiflength is None:
        return _motif_categories()
    elif motiflength < 2:
        raise("motiflength needs to be at least 2")
    elif motiflength == 2:
        return _motif_categories()[1:]
    else:
        captured_strands = tuple([_motif_categories()[0].format(ii)
            for ii in range(1,motiflength-1)])
        return captured_strands+_motif_categories()[1:]

[docs] def make_hamming_dct(alphabet, motiflength, monomers_included=True): hamming = lambda ii : HammingSpace(alphabet,ii) # domain = \sum_{k=1}^{motiflength} hamming0 * hamming**k hamming0 # consider all strands shorter than motiflength monomers_untracked = 1-monomers_included domain = [(_return_motif_categories()[0].format(ii+1), hamming(ii+1)) for ii in range(monomers_untracked,motiflength-2)] # add beginnings domain += [(_return_motif_categories()[1], hamming(motiflength-1))] # add continuations domain += [(_return_motif_categories()[2], hamming(motiflength))] # add ends domain += [(_return_motif_categories()[3],hamming(motiflength-1))] domain_dct = {} for dom in domain: domain_dct[dom[0]] = dom[1] return domain_dct
[docs] class MotifSpace(MultiDomain):
[docs] def __init__(self, dct, alphabet = None, motiflength = None, units ='bits', _callingfrommake=False): if not _callingfrommake: raise NotImplementedError( 'To create a MultiDomain call `MultiDomain.make()`.') self._alphabet = alphabet self._motiflength = motiflength self._units = make_unit(units) self._keys = tuple(sorted(dct.keys())) self._domains = tuple(dct[key] for key in self._keys) self._idx = frozendict({key: i for i, key in enumerate(self._keys)})
[docs] @staticmethod def make(alphabet, motiflength, units : Unit = None, monomers_included=True): """Creates a MultiDomain object from a dictionary of names and domains Parameters ---------- inp : MultiDomain or dict{name: DomainTuple} The already built MultiDomain or a dictionary of DomainTuples Returns ------ A MultiDomain with the input Domains as domains """ if units is None: units = make_unit('bits',np.log2(len(alphabet))) else: units = make_unit(units) if (units/make_unit('bits', np.log2(len(alphabet))))!=1.: warn("Length of alphabet suggests that units of MotifSpace is {}".format(make_unit('bits',np.log2(len(alphabet))))+'but given units are {}.'.format(units)) if isinstance(alphabet,int): alphabet = list(1 + np.arange(alphabet)) inp = make_hamming_dct(alphabet, motiflength, monomers_included=monomers_included) if isinstance(inp, MotifSpace): return inp if not isinstance(inp, dict): raise TypeError("dict expected") tmp = {} for key, value in inp.items(): if not isinstance(key, str): raise TypeError("keys must be strings") tmp[key] = DomainTuple.make(value) tmp = frozendict(tmp) obj = MotifSpace._domainCache.get(tmp) if obj is not None: return obj obj = MotifSpace(tmp, alphabet=alphabet, motiflength=motiflength, units=units, _callingfrommake=True) MotifSpace._domainCache[tmp] = obj return obj
@property def motiflength(self): return self._motiflength @property def alphabet(self): return self._alphabet @property def number_of_letters(self): return len(self._alphabet) @property def units(self): return self._units