def test_update_fusion_with_composite_annotation_in_replacement(state): state.change(+F.parse('gene.A')**F.parse('gene.B')) state.change( F.parse('gene.B') > CompositeAnnotation(F.parse('gene.C'), F.parse('gene.D'))) assert state.changes == (+F.parse('gene.A')**CompositeAnnotation( F.parse('gene.C'), F.parse('gene.D')), )
def change_annotation(annotation, site=None, replacement=None): """ Apply a change to an annotation. - If ``site`` is specified, looks for ``site`` and replaces with ``replacement``. - If ``site`` is not specified, create a :class:`CompositeAnnotation` of ``annotation`` and ``replacement``. """ if not (site or replacement): raise ValueError() if site: if isinstance(annotation, (Fusion, CompositeAnnotation, Plasmid)): if not annotation.contains(site): if replacement: return CompositeAnnotation(annotation, replacement) return annotation elif isinstance(annotation, (CompositeAnnotation, Plasmid)) \ or isinstance(site, (Feature, CompositeAnnotation)): if replacement is None: annotations = tuple(b for b in annotation if b != site) else: annotations = tuple(replacement if b == site else b for b in annotation if b != replacement) if isinstance(annotation, Fusion): return Fusion.fuse(annotations) return CompositeAnnotation(*annotations) elif isinstance(site, Fusion): before_index = annotation.index(site) upstream = annotation.annotations[:before_index] downstream = annotation.annotations[before_index + len(site):] if replacement is None: return Fusion.fuse(upstream + downstream) else: return Fusion.fuse(upstream + (replacement, ) + downstream) else: raise NotImplementedError() elif isinstance(annotation, Feature): if annotation == site: return replacement elif replacement: return CompositeAnnotation(annotation, replacement) return annotation else: raise NotImplementedError() elif isinstance(annotation, (Feature, Fusion)): return CompositeAnnotation(annotation, replacement) elif isinstance(annotation, (CompositeAnnotation, Plasmid)): if any(a == replacement for a in annotation): # ignore duplicates return annotation return CompositeAnnotation(annotation, replacement) else: raise NotImplementedError()
def test_parse_composite_annotation(parse): assert [ Change(after=CompositeAnnotation(Feature('geneA'), Feature('geneB'))) ] == parse('+{geneA, geneB}') assert [ Change(before=CompositeAnnotation(Feature('geneA'), Feature('geneB'))) ] == parse('-{geneA, geneB}') assert [ Change(before=Feature('geneX'), after=Fusion( CompositeAnnotation(Feature('geneA'), Feature('geneB')), Feature('geneX'))) ] == parse('geneX>{geneA, geneB}:geneX')
def test_added_fusion_features(): genotype = Genotype.parse( '+geneA -geneB:geneC +geneB:geneC +{geneA, geneB}') assert genotype.added_fusion_features == { Feature('geneA'), CompositeAnnotation(Feature('geneA'), Feature('geneB')) }
def test_integrate_plasmid_with_fusion(state): state.change( F('site') > Plasmid('pA', [F.parse('gene.A')**F.parse('gene.B')])) assert state.changes == (F('site') > Plasmid( 'pA', [F.parse('gene.A')**F.parse('gene.B')]), ) state.change(F.parse('gene.A')**F.parse('gene.B') > F.parse('gene.C')) assert state.changes == (F('site') > CompositeAnnotation( F.parse('gene.C')), )
def test_replace_feature_in_composite_annotation(): assert change_annotation(CompositeAnnotation(F('a'), F('b')), F('a'), None) == CompositeAnnotation(F('b')) assert change_annotation(CompositeAnnotation(F('b')), F('a'), None) == CompositeAnnotation(F('b')) assert change_annotation(CompositeAnnotation(F('a') ** F('b'), F('c')), F('a') ** F('b'), F('d')) == CompositeAnnotation(F('d'), F('c')) assert change_annotation(CompositeAnnotation(F('a') ** F('b'), F('c')), F('a') ** F('b'), F('c')) == CompositeAnnotation(F('c'))
def test_insert_feature_in_fusion(): assert change_annotation(F('a') ** F('b'), None, F('x')) == CompositeAnnotation(F('a') ** F('b'), F('x'))
def COMPOSITE_ANNOTATION(self, ast): return CompositeAnnotation(*ast)