def test_calc_state_paths_simply_connected() -> None: # E # | # D C # \ / # B # | # A states = [ state_from_str(x) for x in ('A@0_[a]--B@2_[b]', 'B@2_[bb]--C@3_[c]', 'B@2_[bbb]--D@4_[d]', 'D@4_[dd]--E@5_[e]', 'E@5_[(r)]-{p}', 'A@0_[(x)]-{p}', 'B@2_[(z)]-{p}') ] actual_state_to_paths = calc_state_paths(states) expected_state_to_paths = { 'A@0_[(x)]-{p}': [[]], 'A@0_[a]--B@2_[b]': [[]], 'B@2_[(z)]-{p}': [['A@0_[a]--B@2_[b]']], 'B@2_[bb]--C@3_[c]': [['A@0_[a]--B@2_[b]']], 'B@2_[bbb]--D@4_[d]': [['A@0_[a]--B@2_[b]']], 'D@4_[dd]--E@5_[e]': [['A@0_[a]--B@2_[b]', 'B@2_[bbb]--D@4_[d]']], 'E@5_[(r)]-{p}': [['A@0_[a]--B@2_[b]', 'B@2_[bbb]--D@4_[d]', 'D@4_[dd]--E@5_[e]']], } # type: Dict[str, List[List[str]]] for state, paths in expected_state_to_paths.items(): assert len(actual_state_to_paths[state_from_str(state)]) == len(paths) for path in paths: assert [state_from_str(x) for x in path ] in actual_state_to_paths[state_from_str(state)]
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_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_with_connectivity_constraints() -> None: first_states = [ ValueSet(state_from_str(x)) for x in ('A@0_[ac]--C@2_[ca]', 'C@2_[ce]--E@4_[ec]') ] second_states = [ ValueSet(state_from_str(x)) for x in ('B@1_[bd]--D@3_[db]', 'D@3_[df]--F@5_[fd]') ] contingency = Union(Intersection(*first_states), Intersection(*second_states)) connected = with_connectivity_constraints(contingency) print(connected) print('Not connected:') for soln in contingency.calc_solutions(): print(soln) print() print('Connected:') for soln in connected.calc_solutions(): print(soln)
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_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_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_additional_modifiers() -> None: with pytest.raises(ValueError): state_from_str('A_[(x)]-{bladiebla}') rxncon_system = ExcelBook(ADDITIONAL_MODIFIERS_XLS).rxncon_system assert str(state_from_str('A_[(x)]-{bladiebla}')) == 'A_[(x)]-{bladiebla}' initialize_state_modifiers() with pytest.raises(ValueError): state_from_str('A_[(x)]-{bladiebla}')
def test_dynamical_modification_state() -> None: with pytest.raises(ValueError): state_from_str('A_[(r)]-{bla}') initialize_state_modifiers({'bla': 'bla'}) assert str(state_from_str('A_[(r)]-{bla}')) == 'A_[(r)]-{bla}' initialize_state_modifiers() with pytest.raises(ValueError): state_from_str('A_[(r)]-{bla}')
def test_non_elemental_contingency() -> None: rxncon_sys = Quick('''A_trsl_BmRNA C_p+_B_[(r1)] D_p+_B_[(r2)] D_[x]_ppi_B_[y] ; ! B-{p}''').rxncon_system contingencies = rxncon_sys.contingencies_for_reaction(reaction_from_str('D_[x]_ppi+_B_[y]')) assert len(contingencies) == 1 assert state_from_str('B@1_[(r1)]-{p}') in contingencies[0].effector.states assert state_from_str('B@1_[(r2)]-{p}') in contingencies[0].effector.states assert contingencies[0].effector.name == 'B-{p}'
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_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 test_additional_reactions() -> None: with pytest.raises(SyntaxError): reaction_from_str('A_smurf+_B_[(r)]') rxncon_system = ExcelBook(ADDITIONAL_REACTIONS_XLS).rxncon_system rxn = reaction_from_str('A_smurf+_B_[(r)]') assert rxn.produced_states == [state_from_str('B_[(r)]-{smurf}')] assert rxn.consumed_states == [state_from_str('B_[(r)]-{0}')] initialize_reaction_defs() with pytest.raises(SyntaxError): reaction_from_str('A_smurf+_B_[(r)]')
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_effector_states_property() -> None: state_a1 = sta.state_from_str('A@0--C@2') state_a2 = sta.state_from_str('A@0-{p}') state_b1 = sta.state_from_str('B@1-{ub}') state_b2 = sta.state_from_str('B@1--D@3') effector = eff.OrEffector( eff.AndEffector(eff.StateEffector(state_a1), eff.StateEffector(state_a2)), eff.AndEffector(eff.StateEffector(state_b1), eff.StateEffector(state_b2))) assert all(x in effector.states for x in [state_a1, state_a2, state_b1, state_b2]) assert all(x in [state_a1, state_a2, state_b1, state_b2] for x in effector.states)
def test_output_reactions() -> None: rxncon_sys = Quick("""A_p+_B_[(x)] [output]; ! B_[(x)]-{p}""").rxncon_system contingencies = rxncon_sys.contingencies_for_reaction(reaction_from_str('[output]')) assert len(contingencies) == 1 assert isinstance(contingencies[0].effector, StateEffector) assert [state_from_str('B@2_[(x)]-{p}')] == contingencies[0].effector.states
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_contingency_list_entry_from_strs(): cles = [ cle_from_str( 'A_p+_B_[(a)]', '!', '<bool>#A@0=<bool1>.A@1#B@1=<bool2>.<bool3>.B@3#E@2=<bool2>.<bool3>.E@3' ), cle_from_str('<bool>', 'OR', '<bool1>#<bool2>.<bool3>.A@2=A@1'), cle_from_str('<bool>', 'OR', '<bool2>#<bool1>.B@2=<bool3>.B@3'), cle_from_str('<bool1>', 'AND', 'A@1_[ab1]--B@2_[ba1]'), cle_from_str('<bool1>', 'AND', 'B@2_[be1]--E@3_[eb1]'), cle_from_str('<bool2>', 'AND', '<bool3>#<bool4>.A@2=A@2'), cle_from_str('<bool2>', 'AND', '<bool4>'), cle_from_str('<bool3>', 'OR', 'A@2_[ab2]--B@3_[ba2]'), cle_from_str('<bool3>', 'OR', 'A@2_[ae2]--E@3_[ea2]'), cle_from_str('<bool4>', 'OR', 'A@2_[(a1)]-{p}'), cle_from_str('<bool4>', 'OR', 'A@2_[(a2)]-{ub}'), ] effector = contingencies_from_contingency_list_entries( cles)[0].to_structured().effector states = effector.states assert state_from_str('A@0_[ab1]--B@1_[ba1]') in states assert state_from_str('B@1_[be1]--E@3_[eb1]') in states assert state_from_str('A@0_[ab2]--B@1_[ba2]') in states assert state_from_str('A@0_[ae2]--E@2_[ea2]') in states assert state_from_str('A@0_[(a1)]-{p}') in states assert state_from_str('A@0_[(a2)]-{ub}') in states
def test_ipi_is_mutually_exclusive_with() -> None: assert not state_from_str('A_[x]--[y]').is_mutually_exclusive_with( state_from_str('A_[x]--[y]')) assert state_from_str('A_[x]--[y]').is_mutually_exclusive_with( state_from_str('A_[x]--B_[y]')) assert state_from_str('A_[x]--[y]').is_mutually_exclusive_with( state_from_str('A_[y]--0'))
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_insulin_homodimer() -> None: cles = [ cle_from_str( 'IR_ap+_IR_[JM(Y972)]', '!', '<IRstar>#IR@0=<IR-Ins>.IR@0#IR@2=<IR-Ins>.<IR01-Ins>.IR@1#IR@2=<IR-Ins>.IR@2#insulin@3=<IR-Ins>.<IR01-Ins>.insulin@2#insulin@4=<IR-Ins>.<IR01-Ins>.insulin@3' ), cle_from_str('<IRstar>', 'AND', '<IR-phos>'), cle_from_str('<IRstar>', 'AND', '<IR-Ins>#<IR-phos>.IR@0=IR@0'), cle_from_str('<IR-phos>', 'AND', 'IR@0_[TK(Y1158)]-{P}'), cle_from_str('<IR-phos>', 'AND', 'IR@0_[TK(Y1162)]-{P}'), cle_from_str('<IR-phos>', 'AND', 'IR@0_[TK(Y1163)]-{P}'), cle_from_str('<IR-Ins>', 'AND', 'IR@0_[IRBD]--IR@2_[IRBD]'), cle_from_str('<IR-Ins>', 'AND', '<IR01-Ins>#IR@0=IR@0'), ##IR@1=IR@1 cle_from_str('<IR01-Ins>', 'OR', 'IR@0_[lig]--insulin@2_[IR]'), cle_from_str('<IR01-Ins>', 'OR', 'IR@1_[lig]--insulin@3_[IR]'), ] states = contingencies_from_contingency_list_entries( cles)[0].to_structured().effector.states assert state_from_str('IR@0_[TK(Y1158)]-{p}') in states assert state_from_str('IR@0_[TK(Y1162)]-{p}') in states assert state_from_str('IR@0_[TK(Y1163)]-{p}') in states assert state_from_str('IR@0_[IRBD]--IR@2_[IRBD]') in states assert state_from_str('IR@0_[lig]--insulin@3_[IR]') in states assert state_from_str('IR@2_[lig]--insulin@4_[IR]') in states
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_bidirectional_reactions() -> None: rxncon_sys = Quick('''A_[x]_ppi_B_[y]; ! A_[(x)]-{p} C_p+_A_[(x)]''').rxncon_system # Forward direction contingencies = rxncon_sys.contingencies_for_reaction(reaction_from_str('A_[x]_ppi+_B_[y]')) assert len(contingencies) == 1 assert contingencies[0].effector.states == [state_from_str('A@0_[(x)]-{p}')] assert contingencies[0].contingency_type == ContingencyType.requirement # Reverse direction contingencies = rxncon_sys.contingencies_for_reaction(reaction_from_str('A_[x]_ppi-_B_[y]')) assert len(contingencies) == 0
def test_simple_namespace() -> None: cles = [ cle_from_str('<C0>', 'AND', 'B@1_[(r)]-{p}'), cle_from_str('<C0>', 'AND', 'A@3_[ab]--B@1_[ba]'), cle_from_str('<C1>', 'AND', 'A@2_[ac]--C@4_[ca]'), cle_from_str('<C1>', 'AND', 'A@2_[ad]--D@5_[da]'), cle_from_str('<C>', 'AND', '<C0>#A@1=A@3'), cle_from_str('<C>', 'AND', '<C1>#<C0>.A@3=A@2'), cle_from_str('<C>', 'AND', 'X@0_[xa]--A@1_[ax]'), cle_from_str('X_p+_A_[(r)]', '!', '<C>#A@1=A@1#X@0=X@0'), ] contingencies = contingencies_from_contingency_list_entries(cles) effector = contingencies[0].to_structured().effector # Note: the precise numbering is not important, but currently is reproducible. assert state_from_str('X@0_[xa]--A@1_[ax]') in effector.states assert state_from_str('B@2_[(r)]-{p}') in effector.states assert state_from_str('A@1_[ab]--B@2_[ba]') in effector.states assert state_from_str('A@1_[ac]--C@3_[ca]') in effector.states assert state_from_str('A@1_[ad]--D@4_[da]') in effector.states
def test_modification_parsing() -> None: # Upper/lower case should not matter for StateModifier. assert state_from_str('A-{P}') == state_from_str('A-{p}') assert state_from_str('A_[(res)]-{UB}') == state_from_str('A_[(res)]-{Ub}') # Unknown StateModifier should raise. with pytest.raises(ValueError): state_from_str('A_[(res)]-{kryptonite}')
def test_dynamical_reactions() -> None: with pytest.raises(SyntaxError): rxn = reaction_from_str('A_agex_A_[(r)]') initialize_reaction_defs([{ '!UID:Reaction': 'auto-GuanineNucleotideExchange', '!UID:ReactionKey': 'agex', '!BidirectionalVerb': 'no', '!MolTypeX': 'Protein', '!ResolutionX': 'component', '!MolTypeY': 'Protein', '!ResolutionY': 'residue', '!SkeletonRule': '$y%#$y%-{0} -> $y%#$y%-{GTP}' }]) rxn = reaction_from_str('A_agex_A_[(r)]') assert rxn.produced_states == [state_from_str('A_[(r)]-{gtp}')] assert rxn.consumed_states == [state_from_str('A_[(r)]-{0}')] initialize_reaction_defs() with pytest.raises(SyntaxError): rxn = reaction_from_str('A_agex_A_[(r)]')
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 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_global_state_properties() -> None: state = state_from_str('[BLA]') assert state.is_global assert state.is_elemental assert not any(state.is_mutually_exclusive_with(state_to_test) for state_to_test in [ state_from_str('[BLUB]'), state_from_str('A_[x]--B_[y]'), state_from_str('A_[x]--0'), state_from_str('A_[(r)]-{p}'), state_from_str('A_[(r)]-{0}') ]) assert not state.is_homodimer assert state.is_structured assert state.neutral_states == []