def test_single_reaction() -> None: rxncon_sys = Quick('A_p+_B_[(r)]').rxncon_system assert state_from_str('B_[(r)]-{0}') in rxncon_sys.consumed_states assert state_from_str('B_[(r)]-{p}') in rxncon_sys.produced_states assert state_from_str('B_[(r)]-{0}') in rxncon_sys.states_for_component(spec_from_str('B')) assert state_from_str('B_[(r)]-{p}') in rxncon_sys.states_for_component(spec_from_str('B'))
def test_homodimer_to_structured_from_spec_previously_structured() -> None: # A previously structured homodimer should remain invariant upon updating its specs. structured_homodimer = state_from_str('A@0_[x]--A@1_[y]')\ .to_structured_from_spec(spec_from_str('A@2'))\ .to_structured_from_spec(spec_from_str('A@3')) assert structured_homodimer == state_from_str('A@0_[x]--A@1_[y]')
def test_equality() -> None: non_struct = spec_from_str('A_[d/s(r)]') struct = spec_from_str('A@5_[d/s(r)]') assert struct.to_non_struct_spec() == non_struct assert not struct == non_struct assert not non_struct == struct
def test_simple_reaction() -> None: rxn = reaction_from_str('A_p+_B_[(r)]') assert rxn.terms_rhs == [ ReactionTerm([spec_from_str('A')], []), ReactionTerm([spec_from_str('B')], [state_from_str('B_[(r)]-{p}')]) ]
def test_bond_complex_class() -> None: first_complex = BondComplex({spec_from_str('A@0')}, {state_from_str('A@0_[C]--C@2_[A]'): True}, set(), set()) second_complex = BondComplex({spec_from_str('C@2')}, {state_from_str('A@0_[C]--C@2_[A]'): True}, set(), set()) assert first_complex.dangling_bonds() == { state_from_str('A@0_[C]--C@2_[A]') } assert second_complex.dangling_bonds() == { state_from_str('A@0_[C]--C@2_[A]') } assert first_complex.can_connect_with(second_complex) first_and_second = first_complex.combined_with(second_complex) assert first_complex.dangling_bonds() == { state_from_str('A@0_[C]--C@2_[A]') } assert second_complex.dangling_bonds() == { state_from_str('A@0_[C]--C@2_[A]') } assert first_and_second.is_connected() assert not first_and_second.dangling_bonds()
def test_modification_props() -> None: # Elemental state, neutral. state = state_from_str('A_[(res)]-{0}') assert state.is_elemental assert elems_eq(state.components, [spec_from_str('A')]) assert state.is_neutral assert elems_eq(state.neutral_states, [state]) # Elemental state, non-neutral. state = state_from_str('A_[(res)]-{p}') assert state.is_elemental assert elems_eq(state.components, [spec_from_str('A')]) assert not state.is_neutral assert elems_eq(state.neutral_states, [state_from_str('A_[(res)]-{0}')]) # Non-elemental state, neutral. state = state_from_str('A_[dom]-{0}') assert not state.is_elemental assert elems_eq(state.components, [spec_from_str('A')]) assert state.is_neutral assert elems_eq(state.neutral_states, [state]) # Non-elemental state, non-neutral. state = state_from_str('A_[dom]-{p}') assert not state.is_elemental assert elems_eq(state.components, [spec_from_str('A')]) assert not state.is_neutral assert elems_eq(state.neutral_states, [state_from_str('A_[dom]-{0}')])
def test_homodimer_update_specs_flip() -> None: structured_homodimer = state_from_str('A@0_[x]--A@1_[y]') structured_homodimer.update_specs({ spec_from_str('A@0_[x]'): spec_from_str('A@1_[x]'), spec_from_str('A@1_[y]'): spec_from_str('A@0_[y]') }) assert structured_homodimer == state_from_str('A@1_[x]--A@0_[y]')
def test_translation() -> None: rxncon_sys = Quick('''A_trsl_BmRNA C_p+_B_[(r1)] D_p+_B_[(r2)] ; ! B@1_[(r1)]-{p} D_[x]_ppi+_B_[y] E_ub+_B_[(r1)]''').rxncon_system expected_rxns = { 'A_trsl_BmRNA': ReactionTestCase( [ state_from_str('B_[(r1)]-{0}'), state_from_str('B_[(r2)]-{0}'), state_from_str('B_[y]--0') ], [], [] ), 'C_p+_B_[(r1)]': ReactionTestCase( [], [state_from_str('B_[(r1)]-{p}')], [state_from_str('B_[(r1)]-{0}')] ), 'D_p+_B_[(r2)]': ReactionTestCase( [], [state_from_str('B_[(r2)]-{p}')], [state_from_str('B_[(r2)]-{0}')] ), 'D_[x]_ppi+_B_[y]': ReactionTestCase( [], [state_from_str('D_[x]--B_[y]')], [state_from_str('D_[x]--0'), state_from_str('B_[y]--0')] ), 'E_ub+_B_[(r1)]': ReactionTestCase( [], [state_from_str('B_[(r1)]-{ub}')], [state_from_str('B_[(r1)]-{0}')] ) } for rxn in rxncon_sys.reactions: assert elems_eq(rxn.synthesised_states, expected_rxns[str(rxn)].synthesised_states) assert elems_eq(rxn.produced_states, expected_rxns[str(rxn)].produced_states) assert elems_eq(rxn.consumed_states, expected_rxns[str(rxn)].consumed_states) assert rxncon_sys.states_for_component_grouped(spec_from_str('A')) == {} assert rxncon_sys.states_for_component_grouped(spec_from_str('C')) == {} assert rxncon_sys.states_for_component_grouped(spec_from_str('E')) == {} assert elems_eq(list(rxncon_sys.states_for_component_grouped(spec_from_str('B')).values()), [ [state_from_str('B_[y]--0'), state_from_str('B_[y]--D_[x]')], [state_from_str('B_[(r1)]-{0}'), state_from_str('B_[(r1)]-{p}'), state_from_str('B_[(r1)]-{ub}')], [state_from_str('B_[(r2)]-{0}'), state_from_str('B_[(r2)]-{p}')] ]) assert elems_eq(list(rxncon_sys.states_for_component_grouped(spec_from_str('D')).values()), [ [state_from_str('D_[x]--0'), state_from_str('B_[y]--D_[x]')] ])
def test_ipi_reaction() -> None: rxn = reaction_from_str('A_[n]_ipi+_A_[m]') assert rxn.terms_lhs == [ ReactionTerm([spec_from_str('A')], [state_from_str('A_[n]--0'), state_from_str('A_[m]--0')]) ] assert rxn.terms_rhs == [ ReactionTerm([spec_from_str('A')], [state_from_str('A_[n]--[m]')]) ]
def test_ipi_parsing() -> None: assert state_from_str('A_[x]--B_[y]') == state_from_str('B_[y]--A_[x]') # Too fine resolution (higher than elemental) raises. with pytest.raises(SyntaxError): state_from_str('A_[(x)]--[(y)]') with pytest.raises(AssertionError): state = state_from_str('A@1_[x]--[y]') state.update_specs({ spec_from_str('A@1_[x]'): spec_from_str('A@5_[x]'), })
def test_ppi_reaction() -> None: rxn = reaction_from_str('A_[x]_ppi+_B_[y]') assert rxn.terms_lhs == [ ReactionTerm([spec_from_str('A')], [state_from_str('A_[x]--0')]), ReactionTerm([spec_from_str('B')], [state_from_str('B_[y]--0')]) ] assert rxn.terms_rhs == [ ReactionTerm( [spec_from_str('A'), spec_from_str('B')], [state_from_str('A_[x]--B_[y]')]) ]
def test_ipi_props() -> None: # Elemental state, bond. state = state_from_str('A_[m]--[n]') assert state.is_elemental assert state.components == [spec_from_str('A')] assert not state.is_neutral assert elems_eq(state.neutral_states, [state_from_str('A_[m]--0'), state_from_str('A_[n]--0')])
def test_single_contingency() -> None: rxncon_sys = Quick('''A_p+_B_[(r)]; ! A_[(x)]-{p} C_p+_A_[(x)]''').rxncon_system assert state_from_str('A_[(x)]-{0}') in rxncon_sys.consumed_states assert state_from_str('B_[(r)]-{0}') in rxncon_sys.consumed_states assert state_from_str('A_[(x)]-{p}') in rxncon_sys.produced_states assert state_from_str('B_[(r)]-{p}') in rxncon_sys.produced_states assert state_from_str('A_[(x)]-{0}') in rxncon_sys.states_for_component(spec_from_str('A')) assert state_from_str('B_[(r)]-{0}') in rxncon_sys.states_for_component(spec_from_str('B')) assert state_from_str('A_[(x)]-{p}') in rxncon_sys.states_for_component(spec_from_str('A')) assert state_from_str('B_[(r)]-{p}') in rxncon_sys.states_for_component(spec_from_str('B')) contingencies = rxncon_sys.contingencies_for_reaction(reaction_from_str('A_p+_B_[(r)]')) assert len(contingencies) == 1 assert contingencies[0].effector.states == [state_from_str('A@0_[(x)]-{p}')] assert contingencies[0].contingency_type == ContingencyType.requirement
def test_unstructured_specs() -> None: protein_spec = spec_from_str('A_[dd/ss(rr)') # Protein assert isinstance(protein_spec, ProteinSpec) assert protein_spec.has_resolution(LocusResolution.residue) assert protein_spec.to_component_spec().has_resolution( LocusResolution.component) # DNA assert isinstance(protein_spec.to_gene_component_spec(), GeneSpec) assert protein_spec.to_gene_component_spec().has_resolution( LocusResolution.component) # mRNA assert isinstance(protein_spec.to_mrna_component_spec(), MRNASpec) assert protein_spec.to_mrna_component_spec().has_resolution( LocusResolution.component) with pytest.raises(SyntaxError): spec_from_str('0')
def state_from_str(state_str: str) -> State: # pylint: disable=too-many-return-statements state_str = state_str.strip() if re.match(GLOBAL_STATE_REGEX, state_str): return GlobalState(state_str) elif re.match(INTERACTION_STATE_REGEX, state_str): first_str, second_str = re.findall(INTERACTION_STATE_REGEX, state_str)[0] return InteractionState(spec_from_str(first_str), spec_from_str(second_str)) elif re.match(EMPTY_BINDING_STATE_REGEX, state_str): spec_str = re.findall(EMPTY_BINDING_STATE_REGEX, state_str)[0] return EmptyBindingState(spec_from_str(spec_str)) elif re.match(SELF_INTERACTION_STATE_REGEX, state_str): first_str, second_str = re.findall(SELF_INTERACTION_STATE_REGEX, state_str)[0] first_spec = spec_from_str(first_str) second_spec = spec_from_str(first_str).with_locus( locus_from_str(second_str)) return SelfInteractionState(first_spec, second_spec) elif re.match(GLOBAL_STATE_REGEX, state_str): return GlobalState(state_str.strip('[]')) elif re.match(MODIFICATION_STATE_REGEX, state_str): spec_str, mod_str = re.findall(MODIFICATION_STATE_REGEX, state_str)[0] return ModificationState(spec_from_str(spec_str), state_modifier_from_str(mod_str)) elif re.match(FULLY_NEUTRAL_STATE_REGEX, state_str): return FullyNeutralState() else: raise SyntaxError('Unable to parse State string {}'.format(state_str))
def test_ppi_props() -> None: # Elemental state, free binding domain. state = state_from_str('A_[m]--0') assert state.is_elemental assert elems_eq(state.components, [spec_from_str('A')]) assert state.is_neutral assert elems_eq(state.neutral_states, [state]) # Elemental state, bond. state = state_from_str('A_[m]--B_[n]') assert state.is_elemental assert elems_eq(state.components, [spec_from_str('A'), spec_from_str('B')]) assert not state.is_neutral assert elems_eq(state.neutral_states, [state_from_str('A_[m]--0'), state_from_str('B_[n]--0')]) # Non-elemental state, free binding domain. state = state_from_str('A--0') assert not state.is_elemental assert elems_eq(state.components, [spec_from_str('A')]) assert state.is_neutral assert elems_eq(state.neutral_states, [state]) # Non-elemental state, bond. state = state_from_str('A--B_[n]') assert not state.is_elemental assert elems_eq(state.components, [spec_from_str('A'), spec_from_str('B')]) assert not state.is_neutral assert elems_eq(state.neutral_states, [state_from_str('A--0'), state_from_str('B_[n]--0')])
def vars_from_name(self, name: str) -> Dict[str, Any]: assert self.matches_name_def(name) var_to_val = {} for var, _ in self.vars_def.items(): var_regex = self._to_base_regex().replace(var, SPEC_REGEX_MATCHING) for other_var in self.vars_def.keys(): if other_var != var: var_regex = var_regex.replace(other_var, SPEC_REGEX_NON_MATCHING) val_str = re.match(var_regex, name).group(1) val = spec_from_str(val_str) var_to_val[var] = val return var_to_val
def target_from_str(target_str: str) -> Target: """ Generates a target from string input. Args: target_str: The string representation of a StateTarget, ReactionTarget or ComponentStateTarget. Returns: A Target object e.g. StateTarget, ReactionTarget or ComponentStateTarget Raises: SyntaxError: If the string does not correspond to a predefined Target object an error is raised. """ try: return StateTarget(state_from_str(target_str)) except SyntaxError: pass try: if '#' in target_str: rxn_str, index_strs = target_str.split('#') target = ReactionTarget(reaction_from_str(rxn_str)) contingency_variant_index, interaction_variant_index = None, None for variant_str in index_strs.split('/'): if variant_str[0] == 'c': contingency_variant_index = int(variant_str[1:]) elif variant_str[0] == 'i': interaction_variant_index = int(variant_str[1:]) target.contingency_variant_index = contingency_variant_index target.interaction_variant_index = interaction_variant_index return target else: return ReactionTarget(reaction_from_str(target_str)) except SyntaxError: pass try: return ComponentStateTarget(spec_from_str(target_str)) except SyntaxError: raise SyntaxError('Could not parse target str {}'.format(target_str))
def test_properties_fully_neutral() -> None: fully_neutral_state = state_from_str('0') assert not fully_neutral_state.is_structured with pytest.raises(NotImplementedError): fully_neutral_state.is_subset_of(state_from_str('0')) with pytest.raises(NotImplementedError): fully_neutral_state.is_superset_of(state_from_str('0')) with pytest.raises(NotImplementedError): fully_neutral_state.is_elemental with pytest.raises(NotImplementedError): fully_neutral_state.is_neutral with pytest.raises(NotImplementedError): fully_neutral_state.neutral_states with pytest.raises(NotImplementedError): fully_neutral_state.to_structured_from_spec(spec_from_str('A_[m]')) with pytest.raises(NotImplementedError): fully_neutral_state.is_global with pytest.raises(NotImplementedError): fully_neutral_state.is_mutually_exclusive_with(state_from_str('0')) with pytest.raises(NotImplementedError): fully_neutral_state.to_structured_from_state( state_from_str('A@0_[x]--B@1_[y]')) with pytest.raises(NotImplementedError): fully_neutral_state.specs with pytest.raises(NotImplementedError): fully_neutral_state.is_homodimer
def test_modifier() -> None: rxn = reaction_from_str('A_trsl_BmRNA') assert rxn.modifier_components == [ spec_from_str('A'), spec_from_str('BmRNA') ] assert rxn.modifier_states == []
def qual_spec_from_str(qualified_spec_str: str) -> QualSpec: namespace = [x for x in qualified_spec_str.split('.')[:-1]] spec = spec_from_str(qualified_spec_str.split('.')[-1]) return QualSpec(namespace, spec)
def test_resolution_EmptyBindingState() -> None: with pytest.raises(SyntaxError): state_from_str('A_[(x)]--0') with pytest.raises(SyntaxError): EmptyBindingState(spec_from_str('A_[(x)]'))
def test_super_sub() -> None: assert spec_from_str('A_[x]').is_subspec_of(spec_from_str('A')) assert not spec_from_str('A').is_subspec_of(spec_from_str('B')) assert spec_from_str('A_[dom]').is_subspec_of(spec_from_str('A')) assert not spec_from_str('A').is_subspec_of(spec_from_str('A_[dom]'))
def test_homodimer_to_structured_from_spec_non_structured() -> None: structured_homodimer = state_from_str('A_[x]--A_[y]')\ .to_structured_from_spec(spec_from_str('A@0'))\ .to_structured_from_spec(spec_from_str('A@1')) assert structured_homodimer == state_from_str('A@0_[x]--A@1_[y]')
def test_ipi_to_structured_from_spec() -> None: homodimer = state_from_str('A_[x]--[y]') structured_homodimer = homodimer.to_structured_from_spec( spec_from_str('A@0')) assert structured_homodimer == state_from_str('A@0_[x]--[y]')
def test_ipi_update_spec() -> None: state = state_from_str('A_[x]--[y]') state.update_specs({spec_from_str('A_[x]'): spec_from_str('A_[z]')}) assert state == state_from_str('A_[y]--[z]') state.update_specs({spec_from_str('A_[y]'): spec_from_str('A_[z]')}) assert state == state_from_str('A_[z]--[z]')
def test_colons_dashes() -> None: assert spec_from_str('A_[d:bla]').locus.domain == 'd:bla' assert spec_from_str('A_[d-bla]').locus.domain == 'd-bla' assert spec_from_str('A_[(r:bla)]').locus.residue == 'r:bla' assert spec_from_str('A_[(r-bla)]').locus.residue == 'r-bla'
def test_ppi_structured_index() -> None: state = state_from_str('X@4--Z@3') assert spec_from_str('X@4') in state.specs assert spec_from_str('Z@3') in state.specs