def respond_find_common_upstreams(self, content): """Response content to find-common-upstreams request""" genes_arg = content.gets('GENES') if not genes_arg: return self.make_failure('MISSING_MECHANISM') gene_names = _get_term_names(genes_arg) if not gene_names: return self.make_failure('MISSING_MECHANISM') gene_list = [] for gene_name in gene_names: gene_list.append(str(gene_name)) result = self.CA.find_common_upstreams(gene_list) if not result: return self.make_failure('NO_UPSTREAM_FOUND') reply = KQMLList('SUCCESS') upstreams = KQMLList() for r in result: upstreams.append(r) reply.set('upstreams', upstreams) return reply
def respond_find_drug_targets(self, content): """Response content to find-drug-target request.""" try: drug_arg = content.gets('drug') drug = self._get_agent(drug_arg) drug_name = drug.name except Exception: return self.make_failure('INVALID_DRUG') if '-' in drug_name: drug_names = [drug_name, drug_name.replace('-', '')] else: drug_names = [drug_name] all_targets = [] for drugn in drug_names: logger.info('DTDA looking for targets of %s' % drugn) drug_targets = self.dtda.find_drug_targets(drugn) all_targets += drug_targets all_targets = sorted(list(set(all_targets))) reply = KQMLList('SUCCESS') targets = KQMLList() for target_name in all_targets: target = KQMLList() target.set('name', target_name) targets.append(target) reply.set('targets', targets) return reply
def create_message(self): content = KQMLPerformative('SATISFIES-PATTERN') content.set('model', self.model) patt = KQMLList() patt.sets('type', 'eventual_value') ents = KQMLList() ent = KQMLList() ent.sets('description', agent_clj_from_text('phosphorylated MAPK1')) ents.append(ent) patt.set('entities', ents) val = KQMLList() val.sets('type', 'qualitative') val.sets('value', 'low') patt.set('value', val) content.set('pattern', patt) conds = KQMLList() cond = KQMLList() cond.sets('type', 'multiple') quant = KQMLList() quant.sets('type', 'total') ent = KQMLList() ent.sets('description', agent_clj_from_text('DUSP6')) quant.set('entity', ent) cond.sets('quantity', quant) #val = KQMLList() #val.sets('type', 'number') cond.set('value', KQMLToken('10')) #cond.set('value', val) conds.append(cond) content.set('conditions', conds) msg = get_request(content) return msg, content
def subscribe_tell(self, tell_type): msg = KQMLPerformative('subscribe') content = KQMLList('tell') content.append('&key') content.set('content', KQMLList.from_string('(%s . *)' % tell_type)) msg.set('content', content) self.send(msg)
def subscribe_request(self, req_type): msg = KQMLPerformative('subscribe') content = KQMLList('request') content.append('&key') content.set('content', KQMLList.from_string('(%s . *)' % req_type)) msg.set('content', content) self.send(msg)
def create_message1(self): txt = 'ELK1 transcribes FOS.' model = stmts_clj_from_text(txt) entity = agent_clj_from_text('FOS') entities = KQMLList([KQMLList([':description', entity])]) pattern = KQMLList() pattern.set('entities', entities) pattern.sets('type', 'eventual_value') value = KQMLList() value.sets('type', 'qualitative') value.sets('value', 'high') pattern.set('value', value) content = KQMLList('SATISFIES-PATTERN') content.set('pattern', pattern) content.set('model', model) condition_entity = agent_clj_from_text('MAPK1') conditions = KQMLList() condition = KQMLList() condition.sets('type', 'multiple') condition.set('value', '100.0') quantity = KQMLList() quantity.sets('type', 'total') entity = KQMLList() entity.set('description', condition_entity) quantity.set('entity', entity) condition.set('quantity', quantity) conditions.append(condition) content.set('conditions', conditions) msg = get_request(content) return msg, content
def create_message(self): model = stmts_clj_from_text('MAP2K1 binds MAPK1') entity = agent_clj_from_text('MAPK1-MAP2K1 complex') condition_entity = agent_clj_from_text('MAP2K1') entities = KQMLList([KQMLList([':description', entity])]) pattern = KQMLList() pattern.set('entities', entities) pattern.sets('type', 'no_change') value = KQMLList() value.sets('type', 'qualitative') value.sets('value', 'high') pattern.set('value', value) content = KQMLList('SATISFIES-PATTERN') content.set('pattern', pattern) content.set('model', model) conditions = KQMLList() condition = KQMLList() condition.sets('type', 'multiple') condition.set('value', '10.0') quantity = KQMLList() quantity.sets('type', 'total') entity = KQMLList() entity.set('description', condition_entity) quantity.set('entity', entity) condition.set('quantity', quantity) conditions.append(condition) content.set('conditions', conditions) msg = get_request(content) return (msg, content)
def create_message(self): txt = ('MEK not bound to Selumetinib phosphorylates ERK. DUSP ' 'dephosphorylates ERK. Selumetinib binds MEK.') model = stmts_clj_from_text(txt) entity = agent_clj_from_text('ERK that is phosphorylated') entities = KQMLList([KQMLList([':description', entity])]) pattern = KQMLList() pattern.set('entities', entities) pattern.sets('type', 'no_change') value = KQMLList() value.sets('type', 'qualitative') value.sets('value', 'low') pattern.set('value', value) content = KQMLList('SATISFIES-PATTERN') content.set('pattern', pattern) content.set('model', model) condition_entity = agent_clj_from_text('Selumetinib') conditions = KQMLList() condition = KQMLList() condition.sets('type', 'multiple') condition.set('value', '100.0') quantity = KQMLList() quantity.sets('type', 'total') entity = KQMLList() entity.set('description', condition_entity) quantity.set('entity', entity) condition.set('quantity', quantity) conditions.append(condition) content.set('conditions', conditions) msg = get_request(content) return msg, content
def create_message2(self): txt = 'ERK activates ELK1. DUSP inactivates ELK1. ' + \ 'Active ELK1 transcribes FOS.' model = stmts_kstring_from_text(txt) entity = ekb_kstring_from_text('FOS') entities = KQMLList([KQMLList([':description', entity])]) pattern = KQMLList() pattern.set('entities', entities) pattern.sets('type', 'always_value') value = KQMLList() value.sets('type', 'qualitative') value.sets('value', 'low') pattern.set('value', value) content = KQMLList('SATISFIES-PATTERN') content.set('pattern', pattern) content.set('model', model) condition_entity = ekb_kstring_from_text('DUSP') conditions = KQMLList() condition = KQMLList() condition.sets('type', 'multiple') condition.set('value', '100.0') quantity = KQMLList() quantity.sets('type', 'total') entity = KQMLList() entity.set('description', condition_entity) quantity.set('entity', entity) condition.set('quantity', quantity) conditions.append(condition) content.set('conditions', conditions) msg = get_request(content) return (msg, content)
def respond_find_cellular_location(self, content): """Response content to find-cellular-location request""" genes_arg = content.gets('GENES') if not genes_arg: return self.make_failure('MISSING_MECHANISM') gene_names = _get_term_names(genes_arg) if not gene_names: return self.make_failure('MISSING_MECHANISM') gene_list = [] for gene_name in gene_names: gene_list.append(str(gene_name)) result = self.CA.find_most_likely_cellular_location(gene_list) if not result: return self.make_failure('NO_COMMON_CELLULAR_LOCATION_FOUND') reply = KQMLList('SUCCESS') components = KQMLList() for r in result: components.append(r) reply.set('components', components) return reply
def respond_find_cellular_location_from_names(self, content): """Response content to find-cellular-location-from-names request where genes are given as a list of names """ gene_names = content.get('GENES') if not gene_names: return self.make_failure('MISSING_MECHANISM') if isinstance(gene_names, str): return self.make_failure('INVALID_FORMAT') gene_list = [] for gene_name in gene_names: gene_list.append(str(gene_name)) result = self.CA.find_most_likely_cellular_location(gene_list) if not result: return self.make_failure('NO_COMMON_CELLULAR_LOCATION_FOUND') reply = KQMLList('SUCCESS') components = KQMLList() for r in result: components.append(r) reply.set('components', components) return reply
def _get_drug_kqml(drug_list): drugs = KQMLList() for dn, pci in drug_list: drug = KQMLList() drug.sets('name', dn.replace(' ', '-')) if pci: drug.sets('pubchem_id', pci) drugs.append(drug) return drugs
def respond_find_mutex(self, content): """Response content to find-mutex request""" gene_arg = content.gets('GENE') if not gene_arg: return self.make_failure('MISSING_MECHANISM') gene_names = _get_term_names(gene_arg) if not gene_names: return self.make_failure('MISSING_MECHANISM') gene_name = gene_names[0] disease_arg = content.gets('DISEASE') if not disease_arg: return self.make_failure('MISSING_MECHANISM') disease_names = _get_term_names(disease_arg) if not disease_names: return self.make_failure('INVALID_DISEASE') disease_name = disease_names[0].replace("-", " ").lower() disease_abbr = self.CA.get_tcga_abbr(disease_name) if disease_abbr is None: return self.make_failure('INVALID_DISEASE') result = self.CA.find_mutex(gene_name, disease_abbr) if not result: return self.make_failure('NO_MUTEX_GENES_FOUND') reply = KQMLList('SUCCESS') mutex = KQMLList() # Reorganize result for r in result: groups = KQMLList() groups.set('score', r['score']) genes = KQMLList() for gene in r['group']: genes.append(gene) groups.set('group', genes) mutex.append(groups) # mutex.append(groups) reply.set('mutex', mutex) return reply
def respond_get_common(self, content): """Find the common up/down streams of a protein.""" # TODO: This entire function could be part of the MSA. if not CAN_CHECK_STATEMENTS: return self.make_failure( 'NO_KNOWLEDGE_ACCESS', 'Cannot access the database through the web api.' ) genes_ekb = content.gets('genes') agents = _get_agents(genes_ekb) if len(agents) < 2: return self.make_failure('NO_TARGET', 'Only %d < 2 agents given.' % len(agents)) direction = content.gets('up-down') logger.info("Got genes: %s and direction %s." % (agents, direction)) # Choose some parameters based on direction. if direction == 'ONT::MORE': method = 'common_upstreams' prefix = 'up' elif direction == 'ONT::SUCCESSOR': method = 'common_downstreams' prefix = 'down' else: # TODO: With the new MSA we could handle common neighbors. return self.make_failure("UNKNOWN_ACTION", direction) # Find the commonalities. try: finder = self.msa.find_mechanisms(method, *agents) except EntityError as e: return self.make_failure("MISSING_TARGET", e.args[0]) # Get post statements to provenance. if len(agents) > 2: name_list = ', '.join(ag.name for ag in agents[:-1]) + ',' else: name_list = agents[0].name name_list += ' and ' + agents[-1].name msg = ('%sstreams of ' % prefix).capitalize() + name_list self.send_provenance_for_stmts(finder.get_statements(), msg, ev_counts=finder.get_ev_totals()) # Create the reply resp = KQMLPerformative('SUCCESS') gene_list = KQMLList() for gene in finder.get_common_entities(): gene_list.append(gene) resp.set('commons', gene_list) resp.sets('prefix', prefix) return resp
def get_kagent(agent_tuple, term_id=None): agent, ont_type, urls = agent_tuple db_refs = '|'.join('%s:%s' % (k, v) for k, v in agent.db_refs.items()) kagent = KQMLList(term_id) if term_id else KQMLList() kagent.sets('name', agent.name) kagent.sets('ids', db_refs) url_parts = [KQMLList([':name', KQMLString(k), ':dblink', KQMLString(v)]) for k, v in urls.items()] url_list = KQMLList() for url_part in url_parts: url_list.append(url_part) kagent.set('id-urls', url_list) kagent.set('ont-type', ont_type) return kagent
def get_kagent(agent_tuple, term_id=None): agent, ont_type, urls = agent_tuple db_refs = '|'.join('%s:%s' % (k, v) for k, v in agent.db_refs.items()) kagent = KQMLList(term_id) if term_id else KQMLList() kagent.sets('name', agent.name) kagent.sets('ids', db_refs) url_parts = [ KQMLList([':name', KQMLString(k), ':dblink', KQMLString(v)]) for k, v in urls.items() ] url_list = KQMLList() for url_part in url_parts: url_list.append(url_part) kagent.set('id-urls', url_list) kagent.set('ont-type', ont_type) return kagent
def _response_to_query(self, msg, content, results, response_type): """Based on the response type, will create a properly formed reply with the results either input as patterns or bound to the arguments from the results. The reply is a tell which is then sent to Companions. Goes through the arguments and the results together to either bind a argument to the result or simple return the result in the place of that argument. The reply content is filled with these argument/result lists (they are listified before appending) before being added to the tell message and subsequently sent off to Companions. Arguments: msg {KQMLPerformative} -- the message being passed along to reply content {[type]} -- query, starts with a predicate and the remainder is the arguments results {[type]} -- The results of performing the query response_type {[type]} -- the given response type, if it is not given or is given to be pattern, the variable will be set to True, otherwise False. """ response_type = response_type is None or response_type == ':pattern' reply_content = KQMLList(content.head()) results_list = results if isinstance(results, list) else [results] result_index = 0 arg_len = len(content.data[1:]) for i, each in enumerate(content.data[1:]): # if argument is a variable if str(each[0]) == '?': # if last argument and there's still more in results if i == arg_len and result_index < len(results_list) - 1: # get the remaining list pattern = results_list[result_index:] else: # otherwise just get the next element pattern = results_list[result_index] reply_with = pattern if response_type else (each, pattern) reply_content.append(listify(reply_with)) result_index += 1 else: if response_type: # only add the arguments if this is pattern reply_content.append(each) reply_msg = KQMLPerformative('tell') reply_msg.set('sender', self.name) reply_msg.set('content', reply_content) self.reply(msg, reply_msg)
def response_to_query(self, msg: KQMLPerformative, content: KQMLPerformative, results: Any, response_type: str): """Based on the response type, will create a properly formed reply with the results either input as patterns or bound to the arguments from the results. The reply is a tell which is then sent to Companions. Goes through the arguments and the results together to either bind a argument to the result or simple return the result in the place of that argument. The reply content is filled with these argument/result lists (they are listified before appending) before being added to the tell message and subsequently sent off to Companions. Arguments: msg (KQMLPerformative): the message being passed along to reply content (KQMLPerformative): query, starts with a predicate and the remainder is the arguments results (Any): The results of performing the query response_type (str): the given response type, if it is not given or is given to be pattern, the variable will be set to True, otherwise False """ LOGGER.debug('Responding to query: %s, %s, %s', msg, content, results) response_type = response_type is None or response_type == ':pattern' reply_content = KQMLList(content.head()) results_list = results if isinstance(results, list) else [results] result_index = 0 arg_len = len(content.data[1:]) for i, each in enumerate(content.data[1:]): # if argument is a variable, replace in the pattern or bind if str(each[0]) == '?': # if last argument and there's still more in results if i == arg_len and result_index < len(results_list) - 1: pattern = results_list[result_index:] # get remaining list else: pattern = results_list[result_index] reply_with = pattern if response_type else (each, pattern) reply_content.append(listify(reply_with)) result_index += 1 # if not a variable, replace in the pattern. Ignore for bind elif response_type: reply_content.append(each) # no need to wrap reply_content in parens, KQMLList will do that for us reply_msg = f'(tell :sender {self.name} :content {reply_content})' self.reply(msg, performative(reply_msg))
def respond_get_synonyms(self, content): """Respond to a query looking for synonyms of a protein.""" ekb = content.gets('entity') try: synonyms = self.bs.get_synonyms(ekb) except InvalidAgentError: msg = self.make_failure('INVALID_AGENT') except SynonymsUnknownError: msg = self.make_failure('SYNONYMS_UNKNOWN') else: syns_kqml = KQMLList() for s in synonyms: entry = KQMLList() entry.sets(':name', s) syns_kqml.append(entry) msg = KQMLList('SUCCESS') msg.set('synonyms', syns_kqml) return msg
def respond_find_target_drug(self, content): """Response content to find-target-drug request.""" try: target_arg = content.gets('target') target = self._get_agent(target_arg) target_name = target.name except Exception: return self.make_failure('INVALID_TARGET') drug_names, pubchem_ids = self.dtda.find_target_drugs(target_name) reply = KQMLList('SUCCESS') drugs = KQMLList() for dn, pci in zip(drug_names, pubchem_ids): drug = KQMLList() drug.set('name', dn.replace(' ', '-')) if pci: drug.set('pubchem_id', pci) drugs.append(drug) reply.set('drugs', drugs) return reply
def respond_find_drug_targets(self, content): """Response content to find-drug-target request.""" try: drug_arg = content.gets('drug') drug = self._get_agent(drug_arg) except Exception as e: return self.make_failure('INVALID_DRUG') logger.info('DTDA looking for targets of %s' % drug.name) drug_targets = self.dtda.find_drug_targets(drug) all_targets = sorted(list(set(drug_targets))) reply = KQMLList('SUCCESS') targets = KQMLList() for target_name in all_targets: target = KQMLList() target.sets('name', target_name) targets.append(target) reply.set('targets', targets) return reply
def respond_get_synonyms(self, content): """Respond to a query looking for synonyms of a protein.""" entity_arg = content.get('entity') entity = self.get_agent(entity_arg) if entity is None: return self.make_failure('INVALID_AGENT') try: synonyms = self.bs.get_synonyms(entity) except SynonymsUnknownError: return self.make_failure('SYNONYMS_UNKNOWN') else: syns_kqml = KQMLList() for s in synonyms[:10]: entry = KQMLList() entry.sets(':name', s) syns_kqml.append(entry) msg = KQMLList('SUCCESS') msg.set('synonyms', syns_kqml) msg.set('num_synonyms', str(len(synonyms))) return msg
def respond_model_undo(self, content): """Return response content to model-undo request.""" res = self.mra.model_undo() no_display = content.get('no-display') model_id = res.get('model_id') # Start a SUCCESS message msg = KQMLPerformative('SUCCESS') # Add the model id msg.set('model-id', 'NIL' if model_id is None else str(model_id)) # Add the INDRA model json model = res.get('model') # Handle empty model if not model: self.send_clean_model() model_msg = encode_indra_stmts(model) msg.set('model', model_msg) # Get the action and add it to the message action = res.get('action') actionl = KQMLList() # Here we handle no action as effectively an empty remove action if action['action'] in ('no_op', 'remove_stmts'): actionl.append('remove_stmts') actionl.set( 'statements', encode_indra_stmts(action['statements']) ) msg.set('action', actionl) # Add the diagram diagrams = res.get('diagrams') if not no_display: if diagrams: rxn_diagram = diagrams.get('reactionnetwork') if rxn_diagram: msg.sets('diagram', rxn_diagram) self.send_display_model(diagrams) return msg
def respond_model_undo(self, content): """Return response content to model-undo request.""" res = self.mra.model_undo() no_display = content.get('no-display') model_id = res.get('model_id') # Start a SUCCESS message msg = KQMLPerformative('SUCCESS') # Add the model id msg.set('model-id', 'NIL' if model_id is None else str(model_id)) # Add the INDRA model json model = res.get('model') # Handle empty model if not model: self.send_clean_model() model_msg = encode_indra_stmts(model) msg.sets('model', model_msg) # Get the action and add it to the message action = res.get('action') actionl = KQMLList() # Here we handle no action as effectively an empty remove action if action['action'] in ('no_op', 'remove_stmts'): actionl.append('remove_stmts') actionl.sets( 'statements', encode_indra_stmts(action['statements']) ) msg.set('action', actionl) # Add the diagram diagrams = res.get('diagrams') if not no_display: if diagrams: rxn_diagram = diagrams.get('reactionnetwork') if rxn_diagram: msg.sets('diagram', rxn_diagram) self.send_display_model(diagrams) return msg
def respond_find_drugs_for_mutation_dataset(self, content): genes_arg = content.gets('GENES') if not genes_arg: return self.make_failure('MISSING_MECHANISM') gene_names = _get_term_names(genes_arg) if not gene_names: return self.make_failure('MISSING_MECHANISM') gene_list = [] for gene_name in gene_names: gene_list.append(str(gene_name)) dataset_arg = content.gets('DATASET') if not dataset_arg: dataset_arg = "CCLE" # default cell line result = self.BA.find_drugs_for_mutation_dataset( gene_list, dataset_arg) if not result: return self.make_failure('NO_DRUGS_FOUND') reply = KQMLList('SUCCESS') drugs = KQMLList() for r in result: drugs.append(r) reply.set('drugs', drugs) # drugs = KQMLList.from_string(drugs.to_string()) # reply.set('drugs', drugs) return reply
def respond_choose_sense(self, content): """Return response content to choose-sense request.""" agent_clj = content.get('agent') agent = self.get_agent(agent_clj) if not agent: return self.make_failure('MISSING_AGENT') add_agent_type(agent) def _get_urls(agent): urls = { k: get_identifiers_url(k, v) for k, v in agent.db_refs.items() if k not in {'TEXT', 'TYPE', 'TRIPS'} } return urls msg = KQMLPerformative('SUCCESS') msg.set('agent', self.make_cljson(agent)) description = None if 'UP' in agent.db_refs: description = uniprot_client.get_function(agent.db_refs['UP']) if description: msg.sets('description', description) urls = _get_urls(agent) if urls: url_parts = [ KQMLList([':name', KQMLString(k), ':dblink', KQMLString(v)]) for k, v in urls.items() ] url_list = KQMLList() for url_part in url_parts: url_list.append(url_part) msg.set('id-urls', url_list) return msg
def respond_find_treatment(self, content): """Response content to find-treatment request.""" try: disease_arg = content.gets('disease') disease = self.get_disease(disease_arg) except Exception as e: logger.error(e) reply = self.make_failure('INVALID_DISEASE') return reply logger.info('Disease type: %s' % disease.disease_type) if not trips_isa(disease.disease_type, 'ont::cancer'): logger.info('Disease is not a type of cancer.') reply = self.make_failure('DISEASE_NOT_FOUND') return reply logger.debug('Disease: %s' % disease.name) try: mut_protein, mut_percent = \ self.dtda.get_top_mutation(disease.name) except DiseaseNotFoundException: reply = self.make_failure('DISEASE_NOT_FOUND') return reply reply = KQMLList() # TODO: get functional effect from actual mutations # TODO: add list of actual mutations to response # TODO: get fraction not percentage from DTDA reply1 = KQMLList('SUCCESS') protein = KQMLList() protein.set('name', mut_protein) protein.set('hgnc', mut_protein) reply1.set('protein', protein) reply1.set('prevalence', '%.2f' % (mut_percent / 100.0)) reply1.set('functional-effect', 'ACTIVE') reply.append(reply1) reply2 = KQMLList('SUCCESS') drug_names, pubchem_ids = self.dtda.find_target_drugs(mut_protein) drugs = KQMLList() for dn, pci in zip(drug_names, pubchem_ids): drug = KQMLList() drug.sets('name', dn.replace(' ', '-')) if pci: drug.set('pubchem_id', pci) drugs.append(drug) reply2.set('drugs', drugs) reply.append(reply2) return reply
def respond_with_pattern(self, msg, content, results): reply_content = KQMLList(content.head()) results_list = results if isinstance(results, list) else [results] result_index = 0 arg_len = len(content.data[1:]) for i, each in enumerate(content.data[1:]): if str(each[0]) == '?': #add result if i == arg_len and result_index < len(results_list) - 1: # shove the rest of the results into this one var reply_content.append(listify(results_list[result_index:])) else: reply_content.append(listify(results_list[result_index])) result_index += 1 else: reply_content.append(each) reply_msg = KQMLPerformative('tell') reply_msg.set('sender', self.name) reply_msg.set('content', reply_content) self.reply(msg, reply_msg)
def respond_get_indra_representation(self, content): """Return the INDRA CL-JSON corresponding to the given content.""" # First get the KQML graph object for the given context context = content.get('context').to_string() graph = KQMLGraph(context) # Next, we look at each of the IDs that we need to build EKBs for # and build the EKBs one by one ekbs = [] for trips_id_obj in content.get('ids'): trips_id = trips_id_obj.to_string() if trips_id.startswith('ONT::'): trips_id = trips_id[5:] try: # Turn the graph into an EKB XML object, expanding around # the given ID. ekb = EKB(graph, trips_id) logger.debug('Extracted EKB: %s' % ekb.to_string()) ekbs.append((trips_id, ekb)) except Exception as e: logger.error('Encountered an error while parsing: %s.' % content.to_string()) logger.exception(e) msg = KQMLPerformative('done') # If we didn't get any EKBs, we just return an empty result if not ekbs: msg.set('result', KQMLList()) return msg # If there is one EKB then we work with that elif len(ekbs) == 1: ekbs_to_extract = ekbs # If there are multiple EKBs, we need to make sure that we are not # extracting IDs passed for embedded events (whose root ID, i.e., # trips_id is somewhere inside another EKB already). We therefore # iterate over all the EKBs and check this condition. If the EKB # isn't subsumed, it's added to a list of ones to be extracted. else: ekbs_to_extract = [] for idx, (trips_id, ekb) in enumerate(ekbs): other_ekbs = ekbs[:idx] + ekbs[idx + 1:] other_components = set.union( *[set(e.components) for _, e in other_ekbs]) if trips_id in other_components: continue ekbs_to_extract.append((trips_id, ekb)) # Finally, we extract entities (Agents or Statements) from the given # EKB, and add each extraction to a list entities = KQMLList() for trips_id, ekb in ekbs_to_extract: entity = ekb.get_entity() if entity is None: logger.info("Could not resolve entity from: %s. " % ekb.to_string()) else: js = self.make_cljson(entity) entities.append(js) if len(entities) == 1: msg.sets('result', entities[0]) else: msg.set('result', entities) return msg
def respond_build_model(self, content): """Return response content to build-model request.""" descr_format = content.gets('format') if descr_format: logger.info('Building model from format: %s' % descr_format) no_display = content.get('no-display') if not descr_format: descr = content.get('description') js_data = self.converter.cl_to_json(descr) if isinstance(js_data, dict): logger.error('JSON data should be a list not a dict.') raise InvalidModelDescriptionError("Model description should " "be a list of events.") js = json.dumps(js_data) res = self.mra.build_model_from_json(js) elif descr_format == 'ekb': descr = content.gets('description') res = self.mra.build_model_from_ekb(descr) elif descr_format == 'indra_json': descr = content.gets('description') res = self.mra.build_model_from_json(descr) else: err_msg = 'Invalid description format: %s' % descr_format raise InvalidModelDescriptionError(err_msg) if res.get('error'): raise InvalidModelDescriptionError(res.get('error')) model_id = res.get('model_id') if model_id is None: raise InvalidModelDescriptionError() # Start a SUCCESS message msg = KQMLPerformative('SUCCESS') # Add the model id msg.set('model-id', str(model_id)) # Add the INDRA model json model = res.get('model') if model and (descr_format == 'ekb' or not descr_format): self.send_background_support(model) model_msg = encode_indra_stmts(model) msg.set('model', model_msg) # Add the diagrams diagrams = res.get('diagrams') if not no_display: if diagrams: rxn_diagram = diagrams.get('reactionnetwork') if rxn_diagram: msg.sets('diagram', rxn_diagram) self.send_display_model(diagrams) # Indicate whether the goal has been explained has_expl = res.get('has_explanation') if has_expl is not None: msg.set('has_explanation', str(has_expl).upper()) # Send out various model diagnosis messages diagnostic_tells = self.send_model_diagnoses(res) if diagnostic_tells: suggs = KQMLList() for text in diagnostic_tells: sugg = KQMLList() sugg.sets('TEXT', text) suggs.append(sugg) msg.set('suggestions', suggs) # Once we sent out the diagnosis messages, we make sure we keep # track of whether we have an explanation if has_expl: self.have_explanation = True # Analyze the model for issues # Report ambiguities ambiguities = res.get('ambiguities') if ambiguities: ambiguities_msg = get_ambiguities_msg(ambiguities) msg.set('ambiguities', ambiguities_msg) return msg
def receive_ping(self, msg): reply = KQMLPerformative('update') reply.set('sender', self.name) #reply.set('receiver', msg.get('sender')) #reply.set('in-reply-to', msg.get('reply-with')) reply_content = KQMLList([':agent', self.name]) reply_content.append(':uptime') reply_content.append(self.uptime()) # I think .set('status', ':OK') can be used here reply_content.append(':status') reply_content.append(':OK') reply_content.append(':state') reply_content.append('idle') reply_content.append(':machine') reply_content.append(socket.gethostname()) reply.set('content', reply_content) self.reply(msg, reply)
def say(self, message): """Say something to the user.""" if message: msg = KQMLList('say') msg.append(KQMLString(message)) self.request(msg)
def respond_find_qca_path(self, content): """Response content to find-qca-path request""" if self.qca.ndex is None: reply = self.make_failure('SERVICE_UNAVAILABLE') return reply source_arg = content.get('SOURCE') target_arg = content.get('TARGET') reltype_arg = content.get('RELTYPE') if not source_arg: raise ValueError("Source list is empty") if not target_arg: raise ValueError("Target list is empty") target = self.get_agent(target_arg) if target is None: reply = self.make_failure('NO_PATH_FOUND') # NOTE: use the one below if it's handled by NLG #reply = self.make_failure('TARGET_MISSING') return reply source = self.get_agent(source_arg) if source is None: reply = self.make_failure('NO_PATH_FOUND') # NOTE: use the one below if it's handled by NLG #reply = self.make_failure('SOURCE_MISSING') return reply if reltype_arg is None or len(reltype_arg) == 0: relation_types = None else: relation_types = [str(k.data) for k in reltype_arg.data] results_list = self.qca.find_causal_path([source.name], [target.name], relation_types=relation_types) if not results_list: reply = self.make_failure('NO_PATH_FOUND') return reply def get_path_statements(results_list): stmts_list = [] for res in results_list: # Edges of the first result edges = res[1::2] # INDRA JSON of the edges of the result try: indra_edges = [fe[0]['__INDRA json'] for fe in edges] except Exception: indra_edges = [fe[0]['INDRA json'] for fe in edges] # Make the JSONs dicts from strings indra_edges = [json.loads(e) for e in indra_edges] # Now fix the edges if needed due to INDRA Statement changes indra_edges = _fix_indra_edges(indra_edges) stmts_list.append(indra_edges) return stmts_list paths_list = get_path_statements(results_list) self.report_paths_graph(paths_list) # Take the first one to report indra_edges = paths_list[0] # Get the INDRA Statement objects indra_edge_stmts = stmts_from_json(indra_edges) # Assemble into English for stmt in indra_edge_stmts: txt = EnglishAssembler([stmt]).make_model() self.send_provenance_for_stmts( [stmt], "the path from %s to %s (%s)" % (source, target, txt)) edges_cl_json = self.make_cljson(indra_edge_stmts) paths = KQMLList() paths.append(edges_cl_json) reply = KQMLList('SUCCESS') reply.set('paths', paths) return reply
def respond_expand_model(self, content): """Return response content to expand-model request.""" model_id = self._get_model_id(content) descr_format = content.gets('format') no_display = content.get('no-display') try: if not descr_format: descr = content.get('description') js = json.dumps(self.converter.cl_to_json(descr)) res = self.mra.expand_model_from_json(js, model_id) elif descr_format == 'ekb': descr = content.gets('description') res = self.mra.expand_model_from_ekb(descr, model_id) elif descr_format == 'indra_json': descr = content.gets('description') res = self.mra.expand_model_from_json(descr, model_id) else: err_msg = 'Invalid description format: %s' % descr_format raise InvalidModelDescriptionError(err_msg) except Exception as e: raise InvalidModelDescriptionError(e) new_model_id = res.get('model_id') if new_model_id is None: raise InvalidModelDescriptionError() # Start a SUCCESS message msg = KQMLPerformative('SUCCESS') # Add the model id msg.set('model-id', str(new_model_id)) # Add the INDRA model json model = res.get('model') model_msg = encode_indra_stmts(model) msg.set('model', model_msg) # Add the INDRA model new json model_new = res.get('model_new') # Indicate whether the goal has been explained has_expl = res.get('has_explanation') if has_expl is not None: msg.set('has_explanation', str(has_expl).upper()) # Send out various model diagnosis messages diagnostic_tells = self.send_model_diagnoses(res) if diagnostic_tells: suggs = KQMLList() for text in diagnostic_tells: sugg = KQMLList() sugg.sets('TEXT', text) suggs.append(sugg) msg.set('suggestions', suggs) # Once we sent out the diagnosis messages, we make sure we keep # track of whether we have an explanation if has_expl: self.have_explanation = True if model_new and (descr_format == 'ekb' or not descr_format): self.send_background_support(model_new) if model_new: model_new_msg = encode_indra_stmts(model_new) msg.set('model-new', model_new_msg) # Add the diagram if not no_display: diagrams = res.get('diagrams') if diagrams: rxn_diagram = diagrams.get('reactionnetwork') if rxn_diagram: msg.sets('diagram', rxn_diagram) self.send_display_model(diagrams) # Analyze the model for issues # Report ambiguities ambiguities = res.get('ambiguities') if ambiguities: ambiguities_msg = get_ambiguities_msg(ambiguities) msg.set('ambiguities', ambiguities_msg) return msg
def say(self, message): """Say something to the user.""" msg = KQMLList('say') msg.append(KQMLString(message)) self.request(msg)
def receive_other_performative(self, msg): """Override of KQMLModule default... ping isn't currently supported by pykqml so we handle other to catch ping and otherwise throw an error. Arguments: msg {KQMLPerformative} -- other type of performative, if ping we reply with a ping update otherwise error """ if msg.head() == 'ping': reply_content = KQMLList([':agent', self.name]) reply_content.append(':uptime') reply_content.append(self._uptime()) # TODO - check if .set('status', ':OK') can be used here instead reply_content.append(':status') reply_content.append(':OK') reply_content.append(':state') reply_content.append('idle') reply_content.append(':machine') reply_content.append(socket.gethostname()) reply = KQMLPerformative('update') reply.set('sender', self.name) # reply.set('receiver', msg.get('sender')) # reply.set('in-reply-to', msg.get('reply-with')) reply.set('content', reply_content) self.reply(msg, reply) else: self.error_reply(msg, 'unexpected performative: ' + str(msg))