def _decorate_existing_edges(self): # This function decorates all existing edges in the knowledge graph with ICEES data, stored in EdgeAttributes knowledge_graph = self.message.knowledge_graph log = self.response # Query ICEES for each edge in the knowledge graph that ICEES can provide data on (use known curies) num_edges_obtained_icees_data_for = 0 edges_by_node_pair = self._get_edges_by_node_pair( knowledge_graph) # Don't duplicate effort for parallel edges for node_pair_key, node_pair_edges in edges_by_node_pair.items(): subject_key = node_pair_edges[0].subject object_key = node_pair_edges[0].object accepted_subject_synonyms = self._get_accepted_synonyms( subject_key) accepted_object_synonyms = self._get_accepted_synonyms(object_key) if accepted_subject_synonyms and accepted_object_synonyms: # Query ICEES for each possible combination of accepted subject/object synonyms for subject_curie_to_try, object_curie_to_try in itertools.product( accepted_subject_synonyms, accepted_object_synonyms): qedge = QEdge(subject=subject_curie_to_try, object=object_curie_to_try) qedge.id = f"icees_e00" log.debug( f"Sending query to ICEES+ for {subject_curie_to_try}--{object_curie_to_try}" ) p_value = self._get_icees_p_value_for_edge(qedge, log) if p_value is not None: num_edges_obtained_icees_data_for += len( node_pair_edges) new_edge_attribute = self._create_icees_edge_attribute( p_value) # Add the data as new EdgeAttributes on the existing edges with this subject/object ID for edge in node_pair_edges: if not edge.attributes: edge.attributes = [] edge.attributes.append(new_edge_attribute) # Don't worry about checking remaining synonym combos if we got results break if num_edges_obtained_icees_data_for: log.info( f"Overlayed {num_edges_obtained_icees_data_for} edges with exposures data from ICEES+" ) else: log.warning( f"Could not find ICEES+ exposures data for any edges in the KG" ) return self.response
def _add_virtual_edges(self, subject_qnode_key, object_qnode_key): # This function adds ICEES exposures data as virtual edges between nodes with the specified qnode IDs knowledge_graph = self.message.knowledge_graph query_graph = self.message.query_graph log = self.response nodes_by_qg_id = self._get_nodes_by_qg_id(knowledge_graph) subject_curies = set(nodes_by_qg_id.get(subject_qnode_key)) object_curies = set(nodes_by_qg_id.get(object_qnode_key)) # Determine which curies ICEES 'knows' about known_subject_curies = { curie for curie in subject_curies if self._get_accepted_synonyms(curie) } known_object_curies = { curie for curie in object_curies if self._get_accepted_synonyms(curie) } num_node_pairs_recognized = 0 for subject_curie, object_curie in ou.get_node_pairs_to_overlay( subject_qnode_key, object_qnode_key, query_graph, knowledge_graph, log): # Query ICEES only for synonyms it 'knows' about if subject_curie in known_subject_curies and object_curie in known_object_curies: accepted_subject_synonyms = self._get_accepted_synonyms( subject_curie) accepted_object_synonyms = self._get_accepted_synonyms( object_curie) for subject_synonym, object_synonym in itertools.product( accepted_subject_synonyms, accepted_object_synonyms): # qedge = QEdge(id=f"icees_{subject_synonym}--{object_synonym}", # subject_key=subject_synonym, # object_key=object_synonym) qedge = QEdge(subject=subject_synonym, object=object_synonym) qedge.id = f"icees_{subject_synonym}--{object_synonym}" log.debug( f"Sending query to ICEES+ for {subject_synonym}--{object_synonym}" ) p_value = self._get_icees_p_value_for_edge(qedge, log) if p_value is not None: num_node_pairs_recognized += 1 # Add a new virtual edge with this data id, virtual_edge = self._create_icees_virtual_edge( subject_curie, object_curie, p_value) old_id = id while id in knowledge_graph.edges: id = old_id + f".{random.randint(10**(9-1), (10**9)-1)}" knowledge_graph.edges[id] = virtual_edge break # Don't worry about checking remaining synonym combos if we got results # Add an 'empty' virtual edge (p-value of None) if we couldn't find any results for this node pair #1009 id, empty_virtual_edge = self._create_icees_virtual_edge( subject_curie, object_curie, None) while id in knowledge_graph.edges: id = old_id + f".{random.randint(10**(9-1), (10**9)-1)}" knowledge_graph.edges[id] = empty_virtual_edge # Add a qedge to the query graph that corresponds to our new virtual edges # new_qedge = QEdge(id=self.virtual_relation_label, # subject_key=subject_qnode_key, # object_key=object_qnode_key, # type=self.icees_edge_type, # option_group_id=ou.determine_virtual_qedge_option_group(subject_qnode_key, object_qnode_key, # query_graph, log)) # Likely need to change this for TRAPI 1.0 new_qedge = QEdge( subject=subject_qnode_key, object=object_qnode_key, predicate=self.icees_edge_type, option_group_id=ou.determine_virtual_qedge_option_group( subject_qnode_key, object_qnode_key, query_graph, log)) query_graph.edges[self.virtual_relation_label] = new_qedge if num_node_pairs_recognized: log.info( f"ICEES+ returned data for {num_node_pairs_recognized} node pairs" ) else: log.warning( f"Could not find ICEES+ exposures data for any {subject_qnode_key}--{object_qnode_key} node pairs" )