The Network class is the central object in NeKo. It holds a directed graph of biological nodes (genes, proteins, complexes) and edges (interactions), and exposes methods for expanding, connecting, querying, and exporting those graphs.
Path policies are one_shortest, all_shortest, and all_bounded. Reuse
policies are none, discovered_paths, and induced_subgraph. A finite
positive maxlen is mandatory. The legacy algorithm, minimal, and
connect_with_bias parameters remain temporarily available and emit a
migration warning with the equivalent explicit call.
If neither old nor new selectors are supplied, the transition release keeps
the former effective default: all_bounded + discovered_paths. An explicitly
disabled minimal flag maps to none unless bias is enabled; either biased
legacy combination maps to induced_subgraph.
See Choosing a connection strategy for the full
policy matrix, fictitious topology diagrams, and the biological implications
of all public connection strategies.
The accession is sufficient: NeKo obtains the canonical term label from GO.
Exact-term human annotations are used by default. Use
include_descendants=True to include genes annotated to more specific GO
terms, or change taxon_id for another organism.
With compress=True, connected GO-associated genes are replaced by one node
named from the canonical GO term label. If collapsing those genes produces both
an activating and an inhibiting interaction between the same two nodes, NeKo
retains the conflicting evidence as one bimodal interaction. References and
interaction types from the contributing edges are preserved.
Parallel regulatory edges elsewhere in a network follow the same rule: an
A stimulation B edge together with an A inhibition B edge is represented
as A bimodal B. Complex formation remains separate because it does not encode
a regulatory sign.
The `Network` object is the central organizing component of the `neko`
module. It is the subject of all operations implemented here, including
topological algorithms, graph analysis, network visualization and
integration of database knowledge.
Args:
initial_nodes: A list of initial nodes to be added to the network.
sif_file: A SIF (Simple Interaction Format) file to load the network from.
resources: A pandas DataFrame containing the resources database.
def__init__(self,initial_nodes:list[str]=None,sif_file=None,resources=None,):self._init_args=locals()delself._init_args['self']self.nodes=pd.DataFrame(columns=["Genesymbol","Uniprot","Type"])self.edges=pd.DataFrame(columns=["source","target","Type","Effect","References"])# Internal object-based storageself._node_objs=set()# Set of Node objectsself._edge_objs=set()# Set of Edge objectsself.initial_nodes=initial_nodesself._ontology=Ontology()# --- NetworkState history tracking ---self._states:dict[int,NetworkState]={}self._state_metadata:dict[int,dict]={}self._state_log:list[int]=[]self._state_counter:int=0self._current_state_id:Optional[int]=Noneself._root_state_id:Optional[int]=Noneself._auto_state_depth:int=0self._history_enabled:bool=Trueself._max_history:Optional[int]=Noneself._is_initializing=Trueself._populate()self._is_initializing=False
Adds a node to the network. The node is added to the nodes DataFrame of the network. The function checks the
syntax for the genesymbol to ensure it is correct. If the node is a complex, it is added with the
'Genesymbol' as the complex string and 'Uniprot' as the node. Otherwise, it is added with the 'Genesymbol' as
the genesymbol and 'Uniprot' as the uniprot. The 'Type' is set as 'NaN' for all new nodes.
Args:
- node: A string representing the node to be added. The node can be represented by either its
Genesymbol or Uniprot identifier.
@_record_state_operationdefadd_node(self,node:str,from_sif:bool=False)->bool:""" Adds a node to the network. The node is added to the nodes DataFrame of the network. The function checks the syntax for the genesymbol to ensure it is correct. If the node is a complex, it is added with the 'Genesymbol' as the complex string and 'Uniprot' as the node. Otherwise, it is added with the 'Genesymbol' as the genesymbol and 'Uniprot' as the uniprot. The 'Type' is set as 'NaN' for all new nodes. Args: - node: A string representing the node to be added. The node can be represented by either its Genesymbol or Uniprot identifier. Returns: - None. """iffrom_sif:# check that the new entry node can be translated using the function mapping node identifier (all the# output of the function should be None) if it cannot be translated, print an error message but add the# node to the network anywaycomplex_string,genesymbol,uniprot=mapping_node_identifier(node)ifnotcomplex_stringandnotgenesymbolandnotuniprot:print("Error: node %s could not be automatically translated"%node)new_entry={"Genesymbol":node,"Uniprot":node,"Type":"NaN"}self.nodes.loc[len(self.nodes)]=new_entryself.nodes=self.nodes.drop_duplicates().reset_index(drop=True)self._add_node_obj(node,node,"NaN")returnTruenew_entry={"Genesymbol":genesymbol,"Uniprot":uniprot,"Type":"NaN"}self.nodes.loc[len(self.nodes)]=new_entryself.nodes=self.nodes.drop_duplicates().reset_index(drop=True)self._add_node_obj(genesymbol,uniprot,"NaN")self.initial_nodes.append(new_entry["Genesymbol"])self.initial_nodes=list(set(self.initial_nodes))returnTruecomplex_string,genesymbol,uniprot=mapping_node_identifier(node)# The identifier stored in ``Uniprot`` is also the identifier used by# resource edges. Prefer the caller's exact identifier when the# resource uses it (e.g. PhosphoSitePlus gene symbols and sites), and# otherwise use its translated UniProt or display identifier.resource_identifier=next((identifierforidentifierin(node,uniprot,genesymbol)ifidentifierisnotNoneandself.check_node(identifier)),None,)ifresource_identifierisNone:print("Error: node %s is not present in the resources database"%node)returnFalsenew_entry={"Genesymbol":complex_stringorgenesymbolornode,"Uniprot":resource_identifier,"Type":"NaN",}self.nodes.loc[len(self.nodes)]=new_entryself.nodes=self.nodes.drop_duplicates().reset_index(drop=True)self._add_node_obj(new_entry["Genesymbol"],new_entry["Uniprot"],new_entry["Type"])returnTrue
This method adds an interaction to the list of interactions while converting it to the NeKo-network format.
It checks if the edge represents inhibition or stimulation and sets the effect accordingly. It also checks if the
nodes involved in the interaction are already present in the network, if not, it adds them.
Args:
- edge: A pandas DataFrame representing the interaction. The DataFrame should contain columns for
'source', 'target', 'type', and 'references'. The 'source' and 'target' columns represent the nodes involved
in the interaction. The 'type' column represents the type of interaction. The 'references' column contains
the references for the interaction.
@_record_state_operationdefadd_edge(self,edge:pd.DataFrame)->None:""" This method adds an interaction to the list of interactions while converting it to the NeKo-network format. It checks if the edge represents inhibition or stimulation and sets the effect accordingly. It also checks if the nodes involved in the interaction are already present in the network, if not, it adds them. Args: - edge: A pandas DataFrame representing the interaction. The DataFrame should contain columns for 'source', 'target', 'type', and 'references'. The 'source' and 'target' columns represent the nodes involved in the interaction. The 'type' column represents the type of interaction. The 'references' column contains the references for the interaction. Returns: - None """# Check if the edge represents inhibition or stimulation and set the effect accordinglyeffect=check_sign(edge)references=edge["references"].values[0]if"references"inedge.columnselseNoneedge_type=edge["type"].values[0]if"type"inedge.columnselseNonedf_edge=pd.DataFrame({"source":edge["source"],"target":edge["target"],"Type":edge_type,"Effect":effect,"References":references})# Convert the "Uniprot" column to a set for efficient membership testuniprot_nodes=set(self.nodes["Uniprot"].unique())# add the new nodes to the nodes dataframeifedge["source"].values[0]notinuniprot_nodes:self.add_node(edge["source"].values[0])ifedge["target"].values[0]notinuniprot_nodes:self.add_node(edge["target"].values[0])self.edges=pd.concat([self.edges,df_edge],ignore_index=True)self.edges=consolidate_edges(self.edges)self.sync_edges_from_df()return
@_record_state_operationdefremove_node(self,node:str)->None:""" Removes a node from the network. The node is removed from both the list of nodes and the list of edges. Args: - node: A string representing the node to be removed. The node can be represented by either its Genesymbol or Uniprot identifier. Returns: - None """ifnodeisNoneor(notisinstance(node,str)andpd.isna(node)):returnmatching_nodes=self.nodes[(self.nodes["Genesymbol"]==node)|(self.nodes["Uniprot"]==node)]identifiers={node}identifiers.update(valueforvalueinmatching_nodes[["Genesymbol","Uniprot"]].stack()ifpd.notna(value))ifmatching_nodes.empty:translated=mapping_node_identifier(node)identifiers.update(valueforvalueintranslatedifvalueisnotNone)self.nodes=self.nodes[~self.nodes[["Genesymbol","Uniprot"]].isin(identifiers).any(axis=1)]self.edges=self.edges[~self.edges[["source","target"]].isin(identifiers).any(axis=1)]return
@_record_state_operationdefconnect_nodes(self,only_signed:bool=False,consensus_only:bool=False)->None:""" Delegates to strategies.connect_nodes. """from.strategiesimportconnect_nodesreturnconnect_nodes(self,only_signed=only_signed,consensus_only=consensus_only)
@_record_state_operationdefconnect_subgroup(self,group,maxlen:int=1,only_signed:bool=False,consensus:bool=False)->None:""" Delegates to strategies.connect_subgroup. """from.strategiesimportconnect_subgroupreturnconnect_subgroup(self,group,maxlen=maxlen,only_signed=only_signed,consensus=consensus)
@_record_state_operationdefconnect_component(self,comp_A,comp_B,maxlen:int=2,mode:Literal['OUT','IN','ALL']='OUT',only_signed:bool=False,consensus:bool=False)->None:""" Delegates to strategies.connect_component. """from.strategiesimportconnect_componentreturnconnect_component(self,comp_A,comp_B,maxlen=maxlen,mode=mode,only_signed=only_signed,consensus=consensus)
@_record_state_operationdefconnect_to_upstream_nodes(self,nodes_to_connect=None,depth:int=1,rank:int=1,only_signed:bool=True,consensus:bool=False)->None:""" Delegates to strategies.connect_to_upstream_nodes. """from.strategiesimportconnect_to_upstream_nodesreturnconnect_to_upstream_nodes(self,nodes_to_connect=nodes_to_connect,depth=depth,rank=rank,only_signed=only_signed,consensus=consensus)
Connect this network to genes associated with a GO term.
The GO accession is authoritative. Exact human annotations are used
by default; include_descendants enables annotations propagated
from more specific terms. When compress is true, connected GO
genes are replaced by a node carrying the canonical GO term label.
Args:
phenotype: Optional backward-compatible phenotype alias.
id_accession: GO accession such as GO:0062043.
sub_genes: Optional subset of network genes to connect from.
maxlen: Maximum path length in the interaction resource.
only_signed: Restrict paths to signed interactions.
compress: Collapse connected GO genes into one phenotype node.
taxon_id: NCBI taxonomy ID or NCBITaxon: CURIE.
include_descendants: Include associations to descendant GO terms.
exclude_automatic_assertions: Exclude ECO:0000501 records.
@_record_state_operationdefconnect_genes_to_phenotype(self,phenotype:str=None,id_accession:str=None,sub_genes:list=None,maxlen:int=2,only_signed:bool=False,compress:bool=False,taxon_id=9606,include_descendants:bool=False,exclude_automatic_assertions:bool=False,)->None:""" Connect this network to genes associated with a GO term. The GO accession is authoritative. Exact human annotations are used by default; ``include_descendants`` enables annotations propagated from more specific terms. When ``compress`` is true, connected GO genes are replaced by a node carrying the canonical GO term label. Args: phenotype: Optional backward-compatible phenotype alias. id_accession: GO accession such as ``GO:0062043``. sub_genes: Optional subset of network genes to connect from. maxlen: Maximum path length in the interaction resource. only_signed: Restrict paths to signed interactions. compress: Collapse connected GO genes into one phenotype node. taxon_id: NCBI taxonomy ID or ``NCBITaxon:`` CURIE. include_descendants: Include associations to descendant GO terms. exclude_automatic_assertions: Exclude ``ECO:0000501`` records. """from.strategiesimportconnect_genes_to_phenotypereturnconnect_genes_to_phenotype(self,phenotype=phenotype,id_accession=id_accession,sub_genes=sub_genes,maxlen=maxlen,only_signed=only_signed,compress=compress,taxon_id=taxon_id,include_descendants=include_descendants,exclude_automatic_assertions=exclude_automatic_assertions,)
@_record_state_operationdefcomplete_connection(self,maxlen:Optional[int]=2,algorithm=UNSET,minimal=UNSET,only_signed:bool=False,consensus:bool=False,connect_with_bias=UNSET,*,path_policy:Optional[PathPolicy]=None,reuse_policy:Optional[ReusePolicy]=None,)->None:""" Delegates to strategies.complete_connection. """from.strategiesimportcomplete_connectionreturncomplete_connection(self,maxlen=maxlen,algorithm=algorithm,minimal=minimal,only_signed=only_signed,consensus=consensus,connect_with_bias=connect_with_bias,path_policy=path_policy,reuse_policy=reuse_policy,_warning_stacklevel=5,)
This function generates a new edges dataframe with the source and target identifiers translated (if possible)
in Genesymbol format.
The network's node table is the primary mapping source so custom nodes
such as phenotypes are retained. Identifiers unknown to both the node
table and the biological mapper are preserved rather than replaced by
null values.
Args:
- None
Returns:
- A pandas DataFrame containing the edges with the source and target identifiers translated into Genesymbol
format.
defconvert_edgelist_into_genesymbol(self)->pd.DataFrame:""" This function generates a new edges dataframe with the source and target identifiers translated (if possible) in Genesymbol format. The network's node table is the primary mapping source so custom nodes such as phenotypes are retained. Identifiers unknown to both the node table and the biological mapper are preserved rather than replaced by null values. Args: - None Returns: - A pandas DataFrame containing the edges with the source and target identifiers translated into Genesymbol format. """uniprot_to_genesymbol={}genesymbols=set()for_,nodeinself.nodes.iterrows():genesymbol=node.get("Genesymbol")uniprot=node.get("Uniprot")ifpd.notna(genesymbol):genesymbols.add(genesymbol)ifpd.isna(uniprot)orpd.isna(genesymbol):continueexisting=uniprot_to_genesymbol.get(uniprot)ifexistingisnotNoneandexisting!=genesymbol:raiseValueError(f"Network identifier {uniprot!r} has multiple gene-symbol "f"labels: {existing!r} and {genesymbol!r}.")uniprot_to_genesymbol[uniprot]=genesymbolambiguous={identifier:labelforidentifier,labelinuniprot_to_genesymbol.items()ifidentifieringenesymbolsandidentifier!=label}ifambiguous:detail=", ".join(f"{identifier!r} -> {label!r}"foridentifier,labelinambiguous.items())raiseValueError("Network identifiers are ambiguous between the Uniprot and "f"Genesymbol columns ({detail}).")defconvert_identifier(identifier):ifpd.isna(identifier):returnidentifierifidentifierinuniprot_to_genesymbol:returnuniprot_to_genesymbol[identifier]ifidentifieringenesymbols:returnidentifieridentifiers=mapping_node_identifier(identifier)returnidentifiers[0]oridentifiers[1]oridentifiergs_edges=self.edges.copy()gs_edges["source"]=gs_edges["source"].apply(convert_identifier)gs_edges["target"]=gs_edges["target"].apply(convert_identifier)returngs_edges