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_equality_output_reaction() -> None: assert not reaction_from_str('A_p+_B_[(x)]') == reaction_from_str( '[output]') assert not reaction_from_str('[output]') == reaction_from_str( 'A_p+_B_[(x)]') assert reaction_from_str('[output]') == reaction_from_str('[output]') assert not reaction_from_str('[output]') == reaction_from_str('[output2]')
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_shuffled_columns() -> None: rxncon_system = ExcelBook(SHUFFLED_COLUMNS_XLS).rxncon_system expected_reactions = ['A_[x]_ppi+_B_[y]', 'A_[x]_ppi-_B_[y]', 'C_p+_A_[(z)]'] for rxn in expected_reactions: assert reaction_from_str(rxn) in rxncon_system.reactions
def test_missing_unnecessary_sheet() -> None: rxncon_system = ExcelBook(MISSING_UNNECESSARY_SHEET_XLS).rxncon_system expected_reactions = ['A_[x]_ppi+_B_[y]', 'A_[x]_ppi-_B_[y]', 'C_p+_A_[(z)]'] for rxn in expected_reactions: assert reaction_from_str(rxn) in rxncon_system.reactions
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_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 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_non_elemental_contingency_single_state() -> None: rxncon_sys = Quick('''A_trsl_BmRNA C_p+_B_[(r1)] 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 print(contingencies[0].effector) assert contingencies[0].effector.name == 'B-{p}'
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_output_reaction() -> None: rxn = reaction_from_str('[Output]') assert rxn.components_rhs == [] assert rxn.components_lhs == [] assert rxn.degraded_components == [] assert rxn.synthesised_components == [] assert rxn.consumed_states == [] assert rxn.produced_states == [] assert rxn.synthesised_states == [] assert rxn.degraded_states == []
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_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 _load_reaction_list(self) -> None: sheet = self._xlrd_book.sheet_by_name(SHEET_REACTION_LIST) reaction_rows = [row for row in sheet.get_rows()][DATA_ROW:] for row in reaction_rows: if not row[self._column_reaction_full_name].value: logger.debug('{}: Empty row'.format(current_function_name())) continue logger.debug('{}: {}'.format(current_function_name(), row[self._column_reaction_full_name].value)) # When a verb such as 'ppi' is encountered, the function 'preprocessed_reaction_strs' # will split it into 'ppi+' and 'ppi-'. reaction_strs = split_bidirectional_reaction_str(row[self._column_reaction_full_name].value) self._reactions += [reaction_from_str(x) for x in reaction_strs]
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 write_reaction_mapping(excel_filename: str, output=None): """ Creates reaction string to full reaction name mapping Args: excel_filename: Name of the excel input file. output: Name of the new output. Returns: None """ if not output: output = './reaction_mapping.csv' print('Reading in Excel file [{}] ...'.format(excel_filename)) excel_book = ExcelBook(excel_filename) sheet = excel_book._xlrd_book.sheet_by_name( SHEET_REACTION_LIST) # type: ignore reaction_rows = [row for row in sheet.get_rows()][DATA_ROW:] header_row = list(sheet.get_rows())[HEADER_ROW] rate_column = None for num, header in enumerate(header_row): if header.value == '!Rate': rate_column = num strs_to_reactions = {} strs_to_rates = {} for row in reaction_rows: if not row[excel_book._column_reaction_full_name].value: logger.debug('_load_reaction_list: Empty row') continue raw_str = row[excel_book._column_reaction_full_name].value logger.debug('_load_reaction_list: {}'.format(raw_str)) # When a verb such as 'ppi' is encountered, the function 'preprocessed_reaction_strs' # will split it into 'ppi+' and 'ppi-'. reaction_strs = split_bidirectional_reaction_str(raw_str) strs_to_reactions[raw_str] = [ reaction_from_str(x) for x in reaction_strs ] rate = 1 if rate_column is not None: rate = row[rate_column].value if rate == "": rate = 1 strs_to_rates[raw_str] = rate with open(output, mode='w') as output_file: writer = csv.writer(output_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) writer.writerow(['original', 'rxnconName', 'rate']) for key in strs_to_reactions: if isinstance(strs_to_reactions[key], list): for x in strs_to_reactions[key]: writer.writerow([key, x, strs_to_rates[key]]) else: writer.writerow( [key, strs_to_reactions[key], strs_to_rates[key]])
def _add_reaction_from_string(self, reaction_str: str) -> None: reaction_strs = split_bidirectional_reaction_str(reaction_str) for rxn in reaction_strs: reaction = reaction_from_str(rxn) self._reactions.append(reaction)
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 contingency_list_entry_from_strs(subject_str: str, verb_str: str, object_str: str) -> ContingencyListEntry: subject_str, verb_str, object_str = subject_str.strip(), verb_str.lower( ).strip(), object_str.strip() LOGGER.debug('{}: {} / {} / {}'.format(current_function_name(), subject_str, verb_str, object_str)) subject = None # type: Optional[Union[Reaction, BooleanContingencyName]] verb = None # type: Optional[Union[BooleanOperator, ContingencyType]] object = None # type: Optional[Union[State, BooleanContingencyName, Tuple[QualSpec, QualSpec]]] if re.match(BOOLEAN_CONTINGENCY_REGEX, subject_str): # subject: Boolean contingency, # verb : Boolean operator, # object : State / Boolean contingency / Qual Spec pair. subject = BooleanContingencyName(subject_str) verb = BooleanOperator(verb_str) else: # subject: Reaction, # verb : Contingency type, # object : State / Boolean contingency. subject = reaction_from_str(subject_str) verb = ContingencyType(verb_str) if re.match(BOOLEAN_CONTINGENCY_REGEX, object_str) and not isinstance(subject, Reaction): # subject: Boolean contingency, # verb : Contingency type / Boolean operator, # object : Boolean contingency. object = BooleanContingencyName(object_str) elif re.match(BOOLEAN_CONTINGENCY_REGEX, object_str.split('#')[0]) and isinstance(subject, Reaction): # subject: Reaction, # verb : Contingency type, # object : Boolean contingency + '#' + reactant equivs. name = object_str.split('#')[0] equivs_strs = [s.split(',') for s in object_str.split('#')[1:]] equivs_dict = { int(i): qual_spec_from_str(qual_spec_str).with_prepended_namespace([name]) for i, qual_spec_str in equivs_strs } equivs = StructEquivalences() for index, spec in enumerate(subject.components_lhs): try: equivs.add_equivalence( QualSpec([], spec.with_struct_index(index)), equivs_dict[index]) except KeyError: pass object = BooleanContingencyNameWithEquivs(name, equivs) LOGGER.debug('{} : Created {}'.format(current_function_name(), str(object))) elif verb == BooleanOperator.op_eqv: strs = [x.strip() for x in object_str.split(',')] object = (qual_spec_from_str(strs[0]).with_prepended_namespace( [subject.name]), qual_spec_from_str( strs[1]).with_prepended_namespace([subject.name])) else: object = state_from_str(object_str) assert subject is not None assert verb is not None assert object is not None return ContingencyListEntry(subject, verb, object)
def contingency_list_entry_from_strs(subject_str: str, verb_str: Union[str, float], object_str: str) -> ContingencyListEntry: """Parses a ContingencyListEntry from a triple obtained from a tabular representation of the rxncon system.""" # The excel parser returns a value of 0, which is used to denote a neutral contingency as a float object. if isinstance(verb_str, float): verb_str = str(int(verb_str)) assert verb_str == '0', 'Unrecognized contingency {}'.format(verb_str) def _add_equivs(equivs: StructEquivalences, equivs_strs: List[List[str]], name: str) -> StructEquivalences: for target_qual_spec_str, source_qual_spec_str in equivs_strs: lhs_qual_spec = qual_spec_from_str(target_qual_spec_str) rhs_qual_spec = qual_spec_from_str( source_qual_spec_str).with_prepended_namespace([name]) equivs.add_equivalence(lhs_qual_spec, rhs_qual_spec) return equivs subject_str, verb_str, object_str = subject_str.strip(), verb_str.lower( ).strip(), object_str.strip() LOGGER.debug('contingency_list_entry_from_strs: {} / {} / {}'.format( subject_str, verb_str, object_str)) subject = None # type: Optional[Union[Reaction, BooleanContingencyName]] verb = None # type: Optional[Union[BooleanOperator, ContingencyType]] object = None # type: Optional[Union[State, BooleanContingencyName, Tuple[QualSpec, QualSpec]]] if re.match(BOOLEAN_CONTINGENCY_REGEX, subject_str): # subject: Boolean contingency, # verb : Boolean operator, # object : State / Boolean contingency subject = BooleanContingencyName(subject_str) verb = BooleanOperator(verb_str) else: # subject: Reaction, # verb : Contingency type, # object : State / Boolean contingency. subject = reaction_from_str(subject_str) verb = ContingencyType(verb_str) if re.match(BOOLEAN_CONTINGENCY_REGEX, object_str) and '#' not in object_str: # subject: Boolean contingency, Reaction # verb : Contingency type / Boolean operator, # object : Boolean contingency. object = BooleanContingencyName(object_str) elif re.match(BOOLEAN_CONTINGENCY_REGEX, object_str.split('#')[0]): # subject: Reaction / Boolean contingency # verb : Contingency type / Boolean operator # object : Boolean contingency + '#' + reactant equivs / Boolean equivs. name = object_str.split('#')[0] equivs_strs = [s.split('=') for s in object_str.split('#')[1:]] equivs = StructEquivalences() _add_equivs(equivs, equivs_strs, name) object = BooleanContingencyNameWithEquivs(name, equivs) LOGGER.debug('contingency_list_entry_from_strs : Created {}'.format( str(object))) else: object = state_from_str(object_str) assert subject is not None, 'Could not parse subject in {} {} {}'.format( subject_str, verb_str, object_str) assert verb is not None, 'Could not parse verb in {} {} {}'.format( subject_str, verb_str, object_str) assert object is not None, 'Could not parse object in {} {} {}'.format( subject_str, verb_str, object_str) return ContingencyListEntry(subject, verb, object)