def respond_confirm_relation_from_literature(self, content): """Confirm a protein-protein interaction given subject, object, verb""" try: subj, obj, stmt_type, filter_agents = self._get_query_info(content) finder = \ self.msa.find_mechanism_from_input(subj, obj, None, stmt_type, ev_limit=5, persist=False, timeout=5, filter_agents=filter_agents) self._send_provenance_async(finder, 'confirming that some statements match') except MSALookupError as mle: return self.make_failure(mle.args[0]) stmts = finder.get_statements(timeout=20) if stmts is None: # TODO: Handle this more gracefully, if possible. return self.make_failure('MISSING_MECHANISM') num_stmts = len(stmts) description = finder.describe(include_negative=False) \ if stmts else None #self.say(description) resp = KQMLPerformative('SUCCESS') resp.set('some-relations-found', 'TRUE' if num_stmts else 'FALSE') resp.set('num-relations-found', str(num_stmts)) resp.set('dump-limit', str(DUMP_LIMIT)) resp.sets('suggestion', description if description else 'nil') return resp
def respond_find_relations_from_literature(self, content): """Find statements matching some subject, verb, object information.""" try: subj, obj, stmt_type, filter_agents = self._get_query_info(content) finder = \ self.msa.find_mechanism_from_input(subj, obj, None, stmt_type, ev_limit=3, persist=False, timeout=5, filter_agents=filter_agents) self._send_provenance_async(finder, 'finding statements that match') except MSALookupError as mle: return self.make_failure(mle.args[0]) stmts = finder.get_statements(timeout=15) if stmts is None: # Calling this success may be a bit ambitious. resp = KQMLPerformative('SUCCESS') resp.set('status', 'WORKING') resp.set('entities-found', 'nil') resp.set('num-relations-found', '0') resp.set('dump-limit', str(DUMP_LIMIT)) return resp agents = finder.get_other_agents() description = finder.describe(include_negative=False) #self.say(description) resp = KQMLPerformative('SUCCESS') resp.set('status', 'FINISHED') resp.set('entities-found', self.make_cljson(agents)) resp.set('num-relations-found', str(len(stmts))) resp.set('dump-limit', str(DUMP_LIMIT)) resp.sets('suggestion', description) resp.set('top-stmts', self.make_cljson(stmts[:10])) return resp
def respond_phosphorylation_activating(self, content): """Return response content to phosphorylation_activating request.""" if not CAN_CHECK_STATEMENTS: return self.make_failure( 'NO_KNOWLEDGE_ACCESS', 'Cannot access the database through the web api.') heading = content.head() m = re.match(r'(\w+)-(\w+)', heading) if m is None: return self.make_failure('UNKNOWN_ACTION') action, polarity = [s.lower() for s in m.groups()] target_cljson = content.get('target') if target_cljson is None or not len(target_cljson): return self.make_failure('MISSING_TARGET') agent = self.get_agent(target_cljson) # This is a bug in the BA that we can handle here if isinstance(agent, list): agent = agent[0] logger.debug('Found agent (target): %s.' % agent.name) site = content.gets('site') if site is None: residue = None position = None else: try: residue, position = site.split('-') except: return self.make_failure('INVALID_SITE') finder = self.msa.find_phos_activeforms(agent, residue=residue, position=position, action=action, polarity=polarity) stmts = finder.get_statements() logger.info("Found %d matching statements." % len(stmts)) if not len(stmts): return self.make_failure( 'MISSING_MECHANISM', "Could not find statement matching phosphorylation activating " "%s, %s, %s, %s." % (agent.name, residue, position, 'phosphorylation')) else: description = finder.describe(include_negative=False) # self.say(description) msg = "phosphorylation at %s%s activates %s." \ % (residue, position, agent.name) self.send_provenance_for_stmts( stmts, msg, ev_counts=finder.get_ev_totals(), source_counts=finder.get_source_counts()) msg = KQMLPerformative('SUCCESS') msg.set('is-activating', 'TRUE') msg.sets('suggestion', description) return msg
def respond_build_model(self, content): """Return response content to build-model request.""" descr = content.gets('description') descr_format = content.gets('format') no_display = content.get('no-display') if not descr_format or descr_format == 'ekb': res = self.mra.build_model_from_ekb(descr) elif descr_format == 'indra_json': 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.sets('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 self.send_model_diagnoses(res) # 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 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 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_cljson = content.get('genes') agents = [self.get_agent(ag) for ag in genes_cljson] 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(), source_counts=finder.get_source_counts()) # Create the reply resp = KQMLPerformative('SUCCESS') agents = finder.get_other_agents() resp.set('entities-found', self.make_cljson(agents)) resp.sets('prefix', prefix) return resp
def register(self): if self.name is not None: perf = KQMLPerformative('register') perf.set('name', self.name) if self.group_name is not None: try: if self.group_name.startswith('('): perf.sets('group', self.group_name) else: perf.set('group', self.group_name) except IOError: logger.error('bad group name: ' + self.group_name) self.send(perf)
def respond_model_remove_mechanism(self, content): """Return response content to model-remove-mechanism request.""" model_id = self._get_model_id(content) descr = content.get('description') js = json.dumps(self.converter.cl_to_json(descr)) no_display = content.get('no-display') try: res = self.mra.remove_mechanism(js, model_id) except Exception as e: raise InvalidModelDescriptionError(e) model_id = res.get('model_id') if model_id is None: raise InvalidModelDescriptionError('Could not find model id.') # 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') model_msg = encode_indra_stmts(model) msg.set('model', model_msg) # Handle empty model if not model: self.send_clean_model() # Get the action and add it to the message removed = res.get('removed') if not removed: msg = self.make_failure('REMOVE_FAILED') return msg else: actionl = KQMLList('remove_stmts') actionl.set('statements', encode_indra_stmts(removed)) msg.set('action', actionl) # Add the diagram diagrams = res.get('diagrams') logger.info(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_remove_mechanism(self, content): """Return response content to model-remove-mechanism request.""" ekb = content.gets('description') model_id = self._get_model_id(content) no_display = content.get('no-display') try: res = self.mra.remove_mechanism(ekb, model_id) except Exception as e: raise InvalidModelDescriptionError(e) model_id = res.get('model_id') if model_id is None: raise InvalidModelDescriptionError('Could not find model id.') # 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') model_msg = encode_indra_stmts(model) msg.sets('model', model_msg) # Handle empty model if not model: self.send_clean_model() # Get the action and add it to the message removed = res.get('removed') if not removed: msg = self.make_failure('REMOVE_FAILED') return msg else: actionl = KQMLList('remove_stmts') actionl.sets('statements', encode_indra_stmts(removed)) msg.set('action', actionl) # Add the diagram diagrams = res.get('diagrams') logger.info(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_has_mechanism(self, content): """Return response content to model-has-mechanism request.""" ekb = content.gets('description') model_id = self._get_model_id(content) try: res = self.mra.has_mechanism(ekb, model_id) except Exception as e: raise InvalidModelDescriptionError(e) # Start a SUCCESS message msg = KQMLPerformative('SUCCESS') # Add the model id msg.set('model-id', str(model_id)) # Add TRUE or FALSE for has-mechanism has_mechanism_msg = 'TRUE' if res['has_mechanism'] else 'FALSE' msg.set('has-mechanism', has_mechanism_msg) query = res.get('query') if query: query_msg = encode_indra_stmts([query]) msg.sets('query', query_msg) return msg
def respond_has_mechanism(self, content): """Return response content to model-has-mechanism request.""" ekb = content.gets('description') model_id = self._get_model_id(content) try: res = self.mra.has_mechanism(ekb, model_id) except Exception as e: raise InvalidModelDescriptionError(e) # Start a SUCCESS message msg = KQMLPerformative('SUCCESS') # Add the model id msg.set('model-id', str(model_id)) # Add TRUE or FALSE for has-mechanism has_mechanism_msg = 'TRUE' if res['has_mechanism'] else 'FALSE' msg.set('has-mechanism', has_mechanism_msg) query = res.get('query') if query: query_msg = encode_indra_stmts([query]) msg.sets('query', query_msg) return msg
def respond_build_model(self, content): """Return response content to build-model request.""" descr = content.gets('description') descr_format = content.gets('format') no_display = content.get('no-display') if not descr_format or descr_format == 'ekb': res = self.mra.build_model_from_ekb(descr) elif descr_format == 'indra_json': 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: self.send_background_support(model) model_msg = encode_indra_stmts(model) msg.sets('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) ambiguities = res.get('ambiguities') if ambiguities: ambiguities_msg = get_ambiguities_msg(ambiguities) msg.set('ambiguities', ambiguities_msg) return msg
def respond_remove_mechanism(self, content): """Return response content to model-remove-mechanism request.""" ekb = content.gets('description') model_id = self._get_model_id(content) no_display = content.get('no-display') try: res = self.mra.remove_mechanism(ekb, model_id) except Exception as e: raise InvalidModelDescriptionError(e) model_id = res.get('model_id') if model_id is None: raise InvalidModelDescriptionError('Could not find model id.') # 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') model_msg = encode_indra_stmts(model) msg.sets('model', model_msg) # Add the removed statements removed = res.get('removed') if removed: removed_msg = encode_indra_stmts(removed) msg.sets('removed', removed_msg) # 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(rxn_diagram) 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_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_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_model_undo(self, content): """Return response content to model-undo request.""" res = self.mra.model_undo() no_display = content.get('no-display') new_model_id = res.get('model_id') # 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.sets('model', model_msg) # 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) if not self.testing: self.send_display_model(model_msg, diagrams) return msg
def respond_expand_model(self, content): """Return response content to expand-model request.""" descr = content.gets('description') model_id = self._get_model_id(content) descr_format = content.gets('format') no_display = content.get('no-display') try: if not descr_format or descr_format == 'ekb': res = self.mra.expand_model_from_ekb(descr, model_id) elif descr_format == 'indra_json': 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.sets('model', model_msg) # Add the INDRA model new json model_new = res.get('model_new') if model_new: model_new_msg = encode_indra_stmts(model_new) msg.sets('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) if not self.testing: self.send_display_model(model_msg, diagrams) ambiguities = res.get('ambiguities') if ambiguities: ambiguities_msg = get_ambiguities_msg(ambiguities) msg.set('ambiguities', ambiguities_msg) return msg
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 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 error_reply(self, msg, comment): reply_msg = KQMLPerformative('error') reply_msg.sets('comment', comment) self.reply(msg, reply_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