def test_phospho_mod_grounding(): a = Agent('MEK1', mods=[ ModCondition('phosphorylation', 'S', '218'), ModCondition('phosphorylation', 'S', '222') ], db_refs={'HGNC': '6840'}) b = Agent('ERK2', db_refs={'HGNC': '6871'}) a_phos = Agent('Foo', mods=[ModCondition('phosphorylation', None, None)], db_refs={'HGNC': '6840'}) st1 = Phosphorylation(a, b, 'T', '185') pysb_asmb = pa.PysbAssembler([st1]) model = pysb_asmb.make_model(policies='one_step') mps = list(pa.grounded_monomer_patterns(model, a_phos)) assert len(mps) == 2 assert mps[0].monomer.name == 'MEK1' assert mps[1].monomer.name == 'MEK1' sc = [mp.site_conditions for mp in mps] assert {'S218': ('p', WILD)} in sc assert {'S222': ('p', WILD)} in sc # Check if we get the doubly phosphorylated MonomerPattern mps = list(pa.grounded_monomer_patterns(model, a)) assert len(mps) == 1 assert mps[0].monomer.name == 'MEK1' assert mps[0].site_conditions == {'S218': ('p', WILD), 'S222': ('p', WILD)}
def test_get_mp_with_grounding_2(): a1 = Agent('A', mods=[ModCondition('phosphorylation', None, None)], db_refs={'HGNC': '6840'}) a2 = Agent('A', mods=[ModCondition('phosphorylation', 'Y', '187')], db_refs={'HGNC': '6840'}) Monomer('A_monomer', ['phospho', 'T185', 'Y187'], { 'phospho': 'y', 'T185': ['u', 'p'], 'Y187': ['u', 'p'] }) Annotation(A_monomer, 'https://identifiers.org/hgnc:6840') A_monomer.site_annotations = [ Annotation(('phospho', 'y'), 'phosphorylation', 'is_modification'), Annotation(('T185', 'p'), 'phosphorylation', 'is_modification'), Annotation(('Y187', 'p'), 'phosphorylation', 'is_modification'), Annotation('T185', 'T', 'is_residue'), Annotation('T185', '185', 'is_position'), Annotation('Y187', 'Y', 'is_residue'), Annotation('Y187', '187', 'is_position') ] mps_1 = list(pa.grounded_monomer_patterns(model, a1)) assert len(mps_1) == 3 mps_2 = list(pa.grounded_monomer_patterns(model, a2)) assert len(mps_2) == 1 mp = mps_2[0] assert mp.monomer == A_monomer assert mp.site_conditions == {'Y187': ('p', WILD)}
def test_get_mp_with_grounding(): foo = Agent('Foo', db_refs={'HGNC': 'foo'}) a = Agent('A', db_refs={'HGNC': '6840'}) b = Agent('B', db_refs={'HGNC': '6871'}) Monomer('A_monomer') Monomer('B_monomer') Annotation(A_monomer, 'https://identifiers.org/hgnc:6840') Annotation(B_monomer, 'https://identifiers.org/hgnc:6871') mps = list(pa.grounded_monomer_patterns(model, foo)) assert len(mps) == 0 mps = list(pa.grounded_monomer_patterns(model, a)) assert len(mps) == 1, mps assert mps[0].monomer == A_monomer mps = list(pa.grounded_monomer_patterns(model, b)) assert len(mps) == 1 assert mps[0].monomer == B_monomer
def check_policy(policy): pysb_asmb = pa.PysbAssembler([st1]) model = pysb_asmb.make_model(policies=policy) mps = list(pa.grounded_monomer_patterns(model, b_phos)) assert len(mps) == 1 assert mps[0].monomer.name == 'ERK2' assert mps[0].site_conditions == {'T185': ('p', WILD)}
def check_policy(policy): pysb_asmb = pa.PysbAssembler([st1]) model = pysb_asmb.make_model(policies=policy) mps = list(pa.grounded_monomer_patterns(model, b_phos)) assert len(mps) == 1 assert mps[0].monomer.name == 'ERK2' assert mps[0].site_conditions == {'T185': ('p', WILD)}
def test_get_mp_with_grounding(): foo = Agent('Foo', db_refs={'HGNC': 'foo'}) a = Agent('A', db_refs={'HGNC': '6840'}) b = Agent('B', db_refs={'HGNC': '6871'}) Monomer('A_monomer') Monomer('B_monomer') Annotation(A_monomer, 'http://identifiers.org/hgnc/HGNC:6840') Annotation(B_monomer, 'http://identifiers.org/hgnc/HGNC:6871') mps = list(pa.grounded_monomer_patterns(model, foo)) assert len(mps) == 0 mps = list(pa.grounded_monomer_patterns(model, a)) assert len(mps) == 1 assert mps[0].monomer == A_monomer mps = list(pa.grounded_monomer_patterns(model, b)) assert len(mps) == 1 assert mps[0].monomer == B_monomer
def test_grounded_active_pattern(): a = Agent('A', db_refs={'HGNC': '1234'}) b = Agent('B', db_refs={'HGNC': '5678'}) b_phos = Agent('B', mods=[ModCondition('phosphorylation', 'S', '100')], db_refs={'HGNC': '5678'}) b_act = Agent('B', activity=ActivityCondition('activity', True), db_refs={'HGNC': '5678'}) st1 = Phosphorylation(a, b, 'S', '100') st2 = ActiveForm(b_phos, 'activity', True) pysba = PysbAssembler([st1, st2]) model = pysba.make_model(policies='one_step') mps = list(pa.grounded_monomer_patterns(model, b_act))
def test_grounded_active_pattern(): a = Agent('A', db_refs={'HGNC': '1234'}) b = Agent('B', db_refs={'HGNC': '5678'}) b_phos = Agent('B', mods=[ModCondition('phosphorylation', 'S', '100')], db_refs={'HGNC': '5678'}) b_act = Agent('B', activity=ActivityCondition('activity', True), db_refs={'HGNC': '5678'}) st1 = Phosphorylation(a, b, 'S', '100') st2 = ActiveForm(b_phos, 'activity', True) pysba = PysbAssembler([st1, st2]) model = pysba.make_model(policies='one_step') mps = list(pa.grounded_monomer_patterns(model, b_act))
def process_statement(self, stmt): self.get_im() # Check if this is one of the statement types that we can check if not isinstance( stmt, (Modification, RegulateAmount, RegulateActivity, Influence)): logger.info('Statement type %s not handled' % stmt.__class__.__name__) return (None, None, 'STATEMENT_TYPE_NOT_HANDLED') # Get the polarity for the statement if isinstance(stmt, Modification): target_polarity = 1 if isinstance(stmt, RemoveModification) else 0 elif isinstance(stmt, RegulateActivity): target_polarity = 0 if stmt.is_activation else 1 elif isinstance(stmt, RegulateAmount): target_polarity = 1 if isinstance(stmt, DecreaseAmount) else 0 elif isinstance(stmt, Influence): target_polarity = 1 if stmt.overall_polarity() == -1 else 0 # Get the subject and object (works also for Modifications) subj, obj = stmt.agent_list() # Get a list of monomer patterns matching the subject FIXME Currently # this will match rules with the corresponding monomer pattern on it. # In future, this statement should (possibly) also match rules in which # 1) the agent is in its active form, or 2) the agent is tagged as the # enzyme in a rule of the appropriate activity (e.g., a phosphorylation # rule) FIXME if subj is not None: subj_mps = list( pa.grounded_monomer_patterns(self.model, subj, ignore_activities=True)) if not subj_mps: return (None, None, 'SUBJECT_MONOMERS_NOT_FOUND') else: subj_mps = [None] # Observables may not be found for an activation since there may be no # rule in the model activating the object, and the object may not have # an "active" site of the appropriate type obs_names = self.stmt_to_obs[stmt] if not obs_names: logger.info("No observables for stmt %s, returning False" % stmt) return (None, None, 'OBSERVABLES_NOT_FOUND') # Statement object is None if all(obs is None for obs in obs_names): # Cannot check modifications in this case if isinstance(stmt, Modification): return (None, None, 'STATEMENT_TYPE_NOT_HANDLED') obs_signed = [None] else: obs_signed = [(obs, target_polarity) for obs in obs_names] result_code = None return subj_mps, obs_signed, result_code
def test_phospho_mod_grounding(): a = Agent('MEK1', mods=[ModCondition('phosphorylation', 'S', '218'), ModCondition('phosphorylation', 'S', '222')], db_refs={'HGNC': '6840'}) b = Agent('ERK2', db_refs={'HGNC': '6871'}) a_phos = Agent('Foo', mods=[ModCondition('phosphorylation', None, None)], db_refs={'HGNC': '6840'}) st1 = Phosphorylation(a, b, 'T', '185') pysb_asmb = pa.PysbAssembler([st1]) model = pysb_asmb.make_model(policies='one_step') mps = list(pa.grounded_monomer_patterns(model, a_phos)) assert len(mps) == 2 assert mps[0].monomer.name == 'MEK1' assert mps[1].monomer.name == 'MEK1' sc = [mp.site_conditions for mp in mps] assert {'S218': ('p', WILD)} in sc assert {'S222': ('p', WILD)} in sc # Check if we get the doubly phosphorylated MonomerPattern mps = list(pa.grounded_monomer_patterns(model, a)) assert len(mps) == 1 assert mps[0].monomer.name == 'MEK1' assert mps[0].site_conditions == {'S218': ('p', WILD), 'S222': ('p', WILD)}
def get_all_mps(self, agents, ignore_activities=False, mapping=False): """Get a list of all monomer patterns for a list of agents.""" ag_to_mps = {} mps = [] for ag in agents: ag_mps = list( pa.grounded_monomer_patterns( self.model, ag, ignore_activities=ignore_activities)) if ag_mps: ag_to_mps[ag] = ag_mps mps += ag_mps if mapping: return ag_to_mps return set(mps)
def test_get_mp_with_grounding_2(): a1 = Agent('A', mods=[ModCondition('phosphorylation', None, None)], db_refs={'HGNC': '6840'}) a2 = Agent('A', mods=[ModCondition('phosphorylation', 'Y', '187')], db_refs={'HGNC': '6840'}) Monomer('A_monomer', ['phospho', 'T185', 'Y187'], {'phospho': 'y', 'T185':['u', 'p'], 'Y187':['u','p']}) Annotation(A_monomer, 'http://identifiers.org/hgnc/HGNC:6840') A_monomer.site_annotations = [ Annotation(('phospho', 'y'), 'phosphorylation', 'is_modification'), Annotation(('T185', 'p'), 'phosphorylation', 'is_modification'), Annotation(('Y187', 'p'), 'phosphorylation', 'is_modification'), Annotation('T185', 'T', 'is_residue'), Annotation('T185', '185', 'is_position'), Annotation('Y187', 'Y', 'is_residue'), Annotation('Y187', '187', 'is_position') ] mps_1 = list(pa.grounded_monomer_patterns(model, a1)) assert len(mps_1) == 3 mps_2 = list(pa.grounded_monomer_patterns(model, a2)) assert len(mps_2) == 1 mp = mps_2[0] assert mp.monomer == A_monomer assert mp.site_conditions == {'Y187': ('p', WILD)}
def add_obs_for_agent(agent): obj_mps = list(pa.grounded_monomer_patterns(self.model, agent)) if not obj_mps: logger.debug('No monomer patterns found in model for agent %s,' ' skipping' % agent) return obs_list = [] for obj_mp in obj_mps: obs_name = _monomer_pattern_label(obj_mp) + '_obs' # Add the observable obj_obs = Observable(obs_name, obj_mp, _export=False) obs_list.append(obs_name) try: self.model.add_component(obj_obs) except ComponentDuplicateNameError as e: pass return obs_list
def test_multiple_grounding_mods(): mek = Agent('MEK1', db_refs={'HGNC': '6840'}) erk = Agent('ERK2', db_refs={'HGNC': '6871'}) cbl = Agent('CBL', db_refs={'HGNC': '1541'}) ub_phos_erk = Agent('ERK2', mods=[ModCondition('phosphorylation', None, None), ModCondition('ubiquitination', None, None)], db_refs={'HGNC': '6871'}) st1 = Phosphorylation(mek, erk, 'T', '185') st2 = Phosphorylation(mek, erk, 'Y', '187') st3 = Ubiquitination(cbl, erk, 'K', '40') st4 = Ubiquitination(cbl, erk, 'K', '50') pysb_asmb = pa.PysbAssembler([st1, st2, st3, st4]) model = pysb_asmb.make_model(policies='one_step') mps = list(pa.grounded_monomer_patterns(model, ub_phos_erk)) assert len(mps) == 4 assert mps[0].monomer.name == 'ERK2' assert mps[1].monomer.name == 'ERK2' assert mps[2].monomer.name == 'ERK2' assert mps[3].monomer.name == 'ERK2'
def test_multiple_grounding_mods(): mek = Agent('MEK1', db_refs={'HGNC': '6840'}) erk = Agent('ERK2', db_refs={'HGNC': '6871'}) cbl = Agent('CBL', db_refs={'HGNC': '1541'}) ub_phos_erk = Agent( 'ERK2', mods=[ModCondition('phosphorylation', None, None), ModCondition('ubiquitination', None, None)], db_refs={'HGNC': '6871'}) st1 = Phosphorylation(mek, erk, 'T', '185') st2 = Phosphorylation(mek, erk, 'Y', '187') st3 = Ubiquitination(cbl, erk, 'K', '40') st4 = Ubiquitination(cbl, erk, 'K', '50') pysb_asmb = pa.PysbAssembler([st1, st2, st3, st4]) model = pysb_asmb.make_model(policies='one_step') mps = list(pa.grounded_monomer_patterns(model, ub_phos_erk)) assert len(mps) == 4 assert mps[0].monomer.name == 'ERK2' assert mps[1].monomer.name == 'ERK2' assert mps[2].monomer.name == 'ERK2' assert mps[3].monomer.name == 'ERK2'
def check_explanation(self): if self.model is None: raise ValueError('check_explanation requires a PySB model.') if self.explain is None: raise ValueError('check_explanation requires an explanation goal.') result = {} mc = PysbModelChecker(self.model, [self.explain]) try: pr = mc.check_statement(self.explain, max_paths=0) result['has_explanation'] = pr.path_found except Exception as e: logger.error("Error checking statement for paths: %s" % str(e)) result['has_explanation'] = False # If we found a path get a path if result['has_explanation']: try: pr = mc.check_statement(self.explain, max_paths=1, max_path_length=8) path_stmts = stmts_from_pysb_path(pr.paths[0], self.model, self.statements) result['explanation_path'] = path_stmts except Exception as e: logger.error("Error getting paths for statement: %s" % str(e)) # If we don't already have an explanation, see if we can propose one else: # Get the source rules associated with the statement to explain source_rules = [] subj_mps = grounded_monomer_patterns(self.model, self.explain.agent_list()[0]) for subj_mp in subj_mps: source_rules += mc._get_input_rules(subj_mp) obs_container = mc.stmt_to_obs[self.explain] # If we've got both source rules and observable names, add dummy # nodes for the source (connected to all input rules) and the # target (connected to all observables) so we only have to deal # with a single source and a single target if source_rules and obs_container: new_edges = [('SOURCE', sr) for sr in source_rules] new_edges += [(on, 'TARGET') for on, _ in obs_container.main_nodes] im = mc.get_im() im.add_edges_from(new_edges) # Now, we know that there is no path between SOURCE and TARGET. # Instead, we consider connections among all possible pairs # of nodes in the graph and count the number of nodes in # the path between source and target: best_edge = (None, 0) for u, v in itertools.permutations(im.nodes(), 2): # Add the edge to the graph im.add_edge(u, v) # Find longest path between source and target simple_paths = list( nx.all_simple_paths(im, 'SOURCE', 'TARGET')) simple_paths.sort(key=lambda p: len(p), reverse=True) if simple_paths and len(simple_paths[0]) > best_edge[1]: best_edge = ((u, v), len(simple_paths[0])) # Now remove the edge we added before going on to the next im.remove_edge(u, v) if best_edge[0]: result['connect_rules'] = best_edge[0] u_stmt = stmt_from_rule(best_edge[0][0], self.model, self.statements) v_stmt = stmt_from_rule(best_edge[0][1], self.model, self.statements) if u_stmt and v_stmt: result['connect_stmts'] = (u_stmt, v_stmt) logger.info("Model statements: %s" % str(self.statements)) logger.info("To explain %s, try connecting %s and %s" % (self.explain, u_stmt, v_stmt)) return result
def check_explanation(self): if self.model is None: raise ValueError('check_explanation requires a PySB model.') if self.explain is None: raise ValueError('check_explanation requires an explanation goal.') result = {} mc = ModelChecker(self.model, [self.explain]) try: pr = mc.check_statement(self.explain, max_paths=0) result['has_explanation'] = pr.path_found except Exception as e: logger.error("Error checking statement for paths: %s" % str(e)) result['has_explanation'] = False # If we found a path get a path if result['has_explanation']: try: pr = mc.check_statement(self.explain, max_paths=1, max_path_length=8) path_stmts = stmts_for_path(pr.paths[0], self.model, self.statements) result['explanation_path'] = path_stmts except Exception as e: logger.error("Error getting paths for statement: %s" % str(e)) # If we don't already have an explanation, see if we can propose one else: # Get the source rules associated with the statement to explain source_rules = [] subj_mps = grounded_monomer_patterns(self.model, self.explain.agent_list()[0]) for subj_mp in subj_mps: source_rules += mc._get_input_rules(subj_mp) obs_names = mc.stmt_to_obs[self.explain] # If we've got both source rules and observable names, add dummy # nodes for the source (connected to all input rules) and the # target (connected to all observables) so we only have to deal # with a single source and a single target if source_rules and obs_names: new_edges = [('SOURCE', sr) for sr in source_rules] new_edges += [(on, 'TARGET') for on in obs_names] im = mc.get_im() im.add_edges_from(new_edges) # Now, we know that there is no path between SOURCE and TARGET. # Instead, we consider connections among all possible pairs # of nodes in the graph and count the number of nodes in # the path between source and target: best_edge = (None, 0) for u, v in itertools.permutations(im.nodes(), 2): # Add the edge to the graph im.add_edge(u, v) # Find longest path between source and target simple_paths = list(nx.all_simple_paths(im, 'SOURCE', 'TARGET')) simple_paths.sort(key=lambda p: len(p), reverse=True) if simple_paths and len(simple_paths[0]) > best_edge[1]: best_edge = ((u, v), len(simple_paths[0])) # Now remove the edge we added before going on to the next im.remove_edge(u, v) if best_edge[0]: result['connect_rules'] = best_edge[0] u_stmt = _stmt_from_rule(self.model, best_edge[0][0], self.statements) v_stmt = _stmt_from_rule(self.model, best_edge[0][1], self.statements) if u_stmt and v_stmt: result['connect_stmts'] = (u_stmt, v_stmt) logger.info("Model statements: %s" % str(self.statements)) logger.info("To explain %s, try connecting %s and %s" % (self.explain, u_stmt, v_stmt)) return result