예제 #1
0
    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
예제 #2
0
    def respond_get_paper_model(self, content):
        """Get and display the model from a paper, indicated by pmid."""
        pmid_raw = content.gets('pmid')
        prefix = 'PMID-'
        if pmid_raw.startswith(prefix) and pmid_raw[len(prefix):].isdigit():
            pmid = pmid_raw[len(prefix):]
        else:
            return self.make_failure('BAD_INPUT')
        try:
            stmts = get_statements_for_paper([('pmid', pmid)],
                                             simple_response=True)
        except IndraDBRestAPIError as e:
            if e.status_code == 404 and 'Invalid or unavailable' in e.reason:
                logger.error("Could not find pmid: %s" % e.reason)
                return self.make_failure('MISSING_MECHANISM')
            else:
                raise e

        if not stmts:
            resp = KQMLPerformative('SUCCESS')
            resp.set('relations-found', 0)
            return resp
        stmts = ac.map_grounding(stmts)
        stmts = ac.map_sequence(stmts)
        unique_stmts = ac.run_preassembly(stmts, return_toplevel=True)
        diagrams = _make_diagrams(stmts)
        self.send_display_model(diagrams)
        resp = KQMLPerformative('SUCCESS')
        resp.set('relations-found', len(unique_stmts))
        resp.set('dump-limit', str(DUMP_LIMIT))
        return resp
예제 #3
0
    def advertise_subscribe(self, pattern):
        """Connects to the host, then builds and sends a message to the
        facilitator with the pattern input as the content, then closes the
        connection.

        Arguments:
            pattern {[type]} -- content to be sent
        """
        # pylint: disable=no-member
        # pylint was unable to pick up on the host and port variables being in
        # a defaults dict which is then used to do __setattr__ with the key
        # value pairs from the dict.
        self.connect(self.host, self.port)
        reply_id = f'id{self.reply_id_counter}'
        self.reply_id_counter += 1
        content = KQMLPerformative('ask-all')
        content.set('receiver', self.name)
        content.set('in-reply-to', reply_id)
        content.set('content', pattern)
        subscribe = KQMLPerformative('subscribe')
        subscribe.set('receiver', self.name)
        subscribe.set('in-reply-to', reply_id)
        subscribe.set('content', content)
        msg = KQMLPerformative('advertise')
        msg.set('sender', self.name)
        msg.set('receiver', 'facilitator')
        msg.set('reply-with', reply_id)
        msg.set('content', subscribe)
        self.send(msg)
        self._close_socket()
예제 #4
0
 def advertise(self, pattern):
     self.connect(self.host, self.port)
     msg = KQMLPerformative('advertise')
     msg.set('sender', self.name)
     msg.set('receiver', 'facilitator')
     reply_id = 'id' + str(self.reply_id_counter)
     msg.set('reply-with', reply_id)
     self.reply_id_counter += 1
     content = KQMLPerformative('ask-all')
     content.set('receiver', self.name)
     content.set('in-reply-to', reply_id)
     content.set('content', pattern)
     msg.set('content', content)
     self.send(msg)
     self.close_socket()
예제 #5
0
 def send_display_model(self, model, diagrams):
     msg = KQMLPerformative('tell')
     content = KQMLList('display-model')
     content.set('type', 'indra')
     content.sets('model', model)
     msg.set('content', content)
     self.send(msg)
     for diagram_type, path in diagrams.items():
         if not path:
             continue
         msg = KQMLPerformative('tell')
         content = KQMLList('display-image')
         content.set('type', diagram_type)
         content.sets('path', path)
         msg.set('content', content)
         self.send(msg)
예제 #6
0
    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
예제 #7
0
 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 insert_data(self, receiver, data, wm_only=False):
        """Takes the data input by the user and processes it into an insert
        message which is subsequently sent off to Companions.

        Arguments:
            receiver {str} -- name of the receiver
            data {[type]} -- anything that can be listified

        Keyword Arguments:
            wm_only {bool} -- whether or not this should only be inserted into
                              the working memory (default: {False})
        """
        msg = KQMLPerformative('insert')
        msg.set('sender', self.name)
        msg.set('receiver', receiver)
        if wm_only:
            msg.data.append(':wm-only?')  # KMQLPerformative has no function
            # append, instead we must access the KQMLList inside the
            # KQMLPerformative .data attribute...
        msg.set('content', listify(data))
        # pylint: disable=no-member
        # pylint was unable to pick up on the host and port variables being in
        # a defaults dict which is then used to do __setattr__ with the key
        # value pairs from the dict.
        # self.connect(self.host, self.port)
        self.send(msg)
예제 #9
0
    def receive_subscribe(self, msg, content):
        """Override of KQMLModule default, expects a performative of ask-all.

        Gets the ask-all query from the message contents (the contents of
        the content variable is the query that we care about), then checks
        to see if the query head is in the dictionary of available asks and
        checks if the query string is in the dictionary of subscribers. If both
        of these are true we then append the message to the subscriber query,
        clean out any previous subscription data, and reply with a tell ok
        message.

        Arguments:
            msg {KQMLPerformative} -- performative to be passed along in reply
                                      and stored in the subscribers dictionary
            content {KQMLPerformative} -- ask-all for a query
        """
        LOGGER.debug('received subscribe: %s', content)  # lazy logging
        if content.head() == 'ask-all':
            # TODO - track msg ideas and use for filtering
            query = content.get('content')
            query_string = query.to_string()
            if query.head() in self.asks and query_string in self.subscribers:
                self.subscribers[query_string].append(msg)
                self.subcribe_data_old[query_string] = None
                self.subcribe_data_new[query_string] = None
                reply_msg = KQMLPerformative('tell')
                reply_msg.set(':sender', self.name)
                reply_msg.set('content', ':ok')
                self.reply(msg, reply_msg)
예제 #10
0
 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
예제 #11
0
 def achieve_on_agent(self, receiver, data):
     msg = KQMLPerformative('achieve')
     msg.set('sender', self.name)
     msg.set('receiver', receiver)
     msg.set('content', listify(data))
     self.connect(self.host, self.port)
     self.send(msg)
예제 #12
0
 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)
예제 #13
0
 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)
예제 #14
0
 def send_display_figure(self, path):
     msg = KQMLPerformative('tell')
     content = KQMLList('display-image')
     content.set('type', 'simulation')
     content.sets('path', path)
     msg.set('content', content)
     self.send(msg)
예제 #15
0
    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))
예제 #16
0
 def reply_with_content(self, msg, reply_content):
     "A wrapper around the reply method from KQMLModule."
     if not self.testing:
         reply_msg = KQMLPerformative('reply')
         reply_msg.set('content', reply_content)
         self.reply(msg, reply_msg)
     return (msg, reply_content)
예제 #17
0
def _get_perf(text, msg_id):
    text = text.encode('utf-8')
    msg = KQMLPerformative('REQUEST')
    msg.set('receiver', 'DRUM')
    content = KQMLList('run-text')
    content.sets('text', text)
    msg.set('content', content)
    msg.set('reply-with', msg_id)
    return msg
예제 #18
0
 def insert_data(self, receiver, data, wm_only=False):
     msg = KQMLPerformative('insert')
     msg.set('sender', self.name)
     msg.set('receiver', receiver)
     if wm_only:
         msg.append(':wm-only?')
     msg.set('content', listify(data))
     self.connect(self.host, self.port)
     self.send(msg)
예제 #19
0
def _get_perf(text, msg_id):
    """Return a request message for a given text."""
    msg = KQMLPerformative('REQUEST')
    msg.set('receiver', 'READER')
    content = KQMLList('run-text')
    content.sets('text', text)
    msg.set('content', content)
    msg.set('reply-with', msg_id)
    return msg
예제 #20
0
    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
예제 #21
0
 def register(self):
     if self.name is not None:
         perf = KQMLPerformative('register')
         perf.set('sender', self.name)
         perf.set('receiver', 'facilitator')
         content = KQMLList([
             '"socket://' + self.host + ':' + str(self.localPort) + '"',
             'nil', 'nil', self.localPort
         ])
         perf.set('content', content)
         self.send(perf)
예제 #22
0
 def ask_agent(self, receiver, data, query_type='user::query'):
     msg = KQMLPerformative('ask-all')
     msg.set('sender', self.name)
     msg.set('receiver', receiver)
     if isinstance(data, KQMLList):
         msg.set('content', data)
     else:
         msg.set('content', listify(data))
     msg.set('query-type', query_type)
     self.connect()  #Non-pip: self.connect(self.host, self.port)
     self.send(msg)
예제 #23
0
    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
예제 #24
0
 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 achieve_on_agent(self, receiver, data):
        """Sends a KQML message to the proper receiver with the data formatted
        properly as a list.

        Arguments:
            receiver {str} -- name of the receiver
            data {[type]} -- anything
        """
        msg = KQMLPerformative('achieve')
        msg.set('sender', self.name)
        msg.set('receiver', receiver)
        msg.set('content', listify(data))
        self.send(msg)
예제 #26
0
    def receive_tell(self, msg, content):
        """Override default KQMLModule tell to simply log the content and reply
        with nothing

        Arguments:
            msg {KQMLPerformative} -- tell to be passed along in reply
            content {KQMLPerformative} -- tell from companions to be logged
        """
        LOGGER.debug('received tell: %s', content)  # lazy logging
        reply_msg = KQMLPerformative('tell')
        reply_msg.set('sender', self.name)
        reply_msg.set('content', None)
        self.reply(msg, reply_msg)
예제 #27
0
    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:]
                    # pattern or binding...
                    reply_with = pattern if response_type else (each, pattern)
                    reply_content.append(listify(reply_with))
                else:
                    # same logic as above, just doesn't get the remaining list
                    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.connect(self.host, self.port)
        self.reply(msg, reply_msg)
예제 #28
0
 def respond_choose_sense(self, content):
     """Return response content to choose-sense request."""
     ekb = content.gets('ekb-term')
     agents, ambiguities = process_ekb(ekb)
     msg = KQMLPerformative('SUCCESS')
     if agents:
         kagents = []
         for term_id, agent_tuple in agents.items():
             kagent = get_kagent(agent_tuple, term_id)
             kagents.append(kagent)
         msg.set('agents', KQMLList(kagents))
     if ambiguities:
         ambiguities_msg = get_ambiguities_msg(ambiguities)
         msg.set('ambiguities', ambiguities_msg)
     return msg
예제 #29
0
 def receive_subscribe(self, msg, content):
     logger.debug('received subscribe: ' + str(content))
     # content performative should be an ask-all
     if content.head() == 'ask-all':
         # if we kept track of msg ideas, could check for that, but we aren't
         # content of content is the query that we care about
         query = content.get('content')  # as a KQMLList?
         query_string = query.to_string()
         if query.head() in self.asks and query_string in self.subscribers:
             self.subscribers[query_string].append(msg)
             self.subcribe_data_old[query_string] = None
             self.subcribe_data_new[query_string] = None
             reply_msg = KQMLPerformative('tell')
             reply_msg.set(':sender', self.name)
             reply_msg.set('content', ':ok')
             self.reply(msg, reply_msg)
예제 #30
0
 def register(self):
     """Overrides the KQMLModule default and uses Companions standards to
     send proper registration.
     """
     if self.name is not None:
         perf = KQMLPerformative('register')
         perf.set('sender', self.name)
         perf.set('receiver', 'facilitator')
         # pylint: disable=no-member
         # pylint was unable to pick up on the host variable being in a
         # defaults dict which is then used to do __setattr__ with the key
         # value pairs from the dict.
         socket_url = f'"socket://{self.host}:{self.local_port}"'
         content = KQMLList([socket_url, 'nil', 'nil', self.local_port])
         perf.set('content', content)
         self.send(perf)